一站式解决,Android 拍照 图库的各种问题.

  在android开发中, 在一些编辑个人信息的时候,经常会有头像这么一个东西,就两个方面,调用系统相机拍照,调用系统图库获取图片.但是往往会遇到各种问题:

1.oom 

2.图片方向不对

3.activity result 的时候data == null

4.调用图库的时候没找到软件

嘿嘿..开代码:

首先是调用系统拍照,和图库的代码

package com.chzh.fitter.util;


import java.io.File;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
import android.widget.Toast;

//在onActivityResult方法中根据requestCode和resultCode来获取当前拍照的图片地址。
//注意:这里有个问题,在有些机型当中(如SamsungI939、note2等)遇见了当拍照并存储之后,intent当中得到的data为空:
/**
 * data = null 的情况主要是由于拍照的时候横屏了,导致重新create, 普通的解决方法可以在sharedpreference里面保存拍照文件的路径(onSaveInstance保存),
 * 在onRestoreSaveInstance里面在获取出来.
 * 最简单的可以用fileUtil 里面的一个静态变量保存起来..
 * */



public class CameraUtil {

	private static final String IMAGE_TYPE = "image/*";

	private Context mContext;

	public CameraUtil(Context context) {
		mContext = context;
	}

	/**
	 * 打开照相机
	 * @param activity 当前的activity
	 * @param requestCode 拍照成功时activity forResult 的时候的requestCode
	 * @param photoFile 拍照完毕时,图片保存的位置
	 */
	public void openCamera(Activity activity, int requestCode, File photoFile) {
		Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
		intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
		activity.startActivityForResult(intent, requestCode);
	}

	/**
	 * 本地照片调用
	 * @param activity
	 * @param requestCode
	 */
	public void openPhotos(Activity activity, int requestCode) {
		if (openPhotosNormal(activity, requestCode) && openPhotosBrowser(activity, requestCode) && openPhotosFinally());
	}

	/**
	 * PopupMenu打开本地相册.
	 */
	private boolean openPhotosNormal(Activity activity, int actResultCode) {
		Intent intent = new Intent(Intent.ACTION_PICK, null);
		intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
				IMAGE_TYPE);
		try {
			activity.startActivityForResult(intent, actResultCode);

		} catch (android.content.ActivityNotFoundException e) {

			return true;
		}

		return false;
	}

	/**
	 * 打开其他的一文件浏览器,如果没有本地相册的话
	 */
	private boolean openPhotosBrowser(Activity activity, int requestCode) {
		Toast.makeText(mContext, "没有相册软件,运行文件浏览器", Toast.LENGTH_LONG).show();
		Intent intent = new Intent(Intent.ACTION_GET_CONTENT); // "android.intent.action.GET_CONTENT"
		intent.setType(IMAGE_TYPE); // 查看类型 String IMAGE_UNSPECIFIED =
									// "image/*";
		Intent wrapperIntent = Intent.createChooser(intent, null);
		try {
			activity.startActivityForResult(wrapperIntent, requestCode);
		} catch (android.content.ActivityNotFoundException e1) {
			return true;
		}
		return false;
	}

	/**
	 * 这个是找不到相关的图片浏览器,或者相册
	 */
	private boolean openPhotosFinally() {
		Toast.makeText(mContext, "您的系统没有文件浏览器或则相册支持,请安装!", Toast.LENGTH_LONG).show();
		return false;
	}

	/**
	 * 获取从本地图库返回来的时候的URI解析出来的文件路径
	 * @return
	 */
	public static String getPhotoPathByLocalUri(Context context, Intent data) {
		Uri selectedImage = data.getData();
		String[] filePathColumn = { MediaStore.Images.Media.DATA };
		Cursor cursor = context.getContentResolver().query(selectedImage,
				filePathColumn, null, null, null);
		cursor.moveToFirst();
		int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
		String picturePath = cursor.getString(columnIndex);
		cursor.close();
		return picturePath;
	}

}

  接下来是解决oom的

  

package com.chzh.fitter.util;

import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.IOException;

import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.media.ExifInterface;
import android.net.Uri;
import android.util.Log;
import android.widget.ImageView;

import com.androidquery.util.AQUtility;

/**
 * @author jarrahwu
 *
 */
public class ImageUtil {

	/**
	 * Utility method for downsampling images.
	 *
	 * @param path
	 *            the file path
	 * @param data
	 *            if file path is null, provide the image data directly
	 * @param target
	 *            the target dimension
	 * @param isWidth
	 *            use width as target, otherwise use the higher value of height
	 *            or width
	 * @param round
	 *            corner radius
	 * @return the resized image
	 */
	public static Bitmap getResizedImage(String path, byte[] data, int target,
			boolean isWidth, int round) {

		Options options = null;

		if (target > 0) {

			Options info = new Options();
			info.inJustDecodeBounds = true;
			//设置这两个属性可以减少内存损耗
			info.inInputShareable = true;
			info.inPurgeable = true;

			decode(path, data, info);

			int dim = info.outWidth;
			if (!isWidth)
				dim = Math.max(dim, info.outHeight);
			int ssize = sampleSize(dim, target);

			options = new Options();
			options.inSampleSize = ssize;

		}

		Bitmap bm = null;
		try {
			bm = decode(path, data, options);
		} catch (OutOfMemoryError e) {
			L.red(e.toString());
			e.printStackTrace();
		}

		if (round > 0) {
			bm = getRoundedCornerBitmap(bm, round);
		}

		return bm;

	}

	private static Bitmap decode(String path, byte[] data,
			BitmapFactory.Options options) {

		Bitmap result = null;

		if (path != null) {

			result = decodeFile(path, options);

		} else if (data != null) {

			// AQUtility.debug("decoding byte[]");

			result = BitmapFactory.decodeByteArray(data, 0, data.length,
					options);

		}

		if (result == null && options != null && !options.inJustDecodeBounds) {
			AQUtility.debug("decode image failed", path);
		}

		return result;
	}

	private static Bitmap decodeFile(String path, BitmapFactory.Options options) {

		Bitmap result = null;

		if (options == null) {
			options = new Options();
		}

		options.inInputShareable = true;
		options.inPurgeable = true;

		FileInputStream fis = null;

		try {

			fis = new FileInputStream(path);

			FileDescriptor fd = fis.getFD();

			// AQUtility.debug("decoding file");
			// AQUtility.time("decode file");

			result = BitmapFactory.decodeFileDescriptor(fd, null, options);

			// AQUtility.timeEnd("decode file", 0);
		} catch (IOException e) {
			Log.error("TAG",e.toString())
		} finally {
			fis.close()
		}

		return result;

	}

	private static int sampleSize(int width, int target) {

		int result = 1;

		for (int i = 0; i < 10; i++) {

			if (width < target * 2) {
				break;
			}

			width = width / 2;
			result = result * 2;

		}

		return result;
	}

	/**
	 * 获取圆角的bitmap
	 * @param bitmap
	 * @param pixels
	 * @return
	 */
	private static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels) {

		Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
				bitmap.getHeight(), Config.ARGB_8888);
		Canvas canvas = new Canvas(output);

		final int color = 0xff424242;
		final Paint paint = new Paint();
		final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
		final RectF rectF = new RectF(rect);
		final float roundPx = pixels;

		paint.setAntiAlias(true);
		canvas.drawARGB(0, 0, 0, 0);
		paint.setColor(color);
		canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

		paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
		canvas.drawBitmap(bitmap, rect, rect, paint);

		return output;
	}

	/**
	 * auto fix the imageOrientation
	 * @param bm source
	 * @param iv imageView  if set invloke it's setImageBitmap() otherwise do nothing
	 * @param uri image Uri if null user path
	 * @param path image path if null use uri
	 */
	public static Bitmap autoFixOrientation(Bitmap bm, ImageView iv, Uri uri,String path) {
		int deg = 0;
		try {
			ExifInterface exif = null;
			if (uri == null) {
				exif = new ExifInterface(path);
			}
			else if (path == null) {
				exif = new ExifInterface(uri.getPath());
			}

			if (exif == null) {
				Log.error("TAG","exif is null check your uri or path");
				return bm;
			}

			String rotate = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
			int rotateValue = Integer.parseInt(rotate);
			System.out.println("orientetion : " + rotateValue);
			switch (rotateValue) {
			case ExifInterface.ORIENTATION_ROTATE_90:
				deg = 90;
				break;
			case ExifInterface.ORIENTATION_ROTATE_180:
				deg = 180;
				break;
			case ExifInterface.ORIENTATION_ROTATE_270:
				deg = 270;
				break;
			default:
				deg = 0;
				break;
			}
		} catch (Exception ee) {
			Log.d("catch img error", "return");
			if(iv != null)
			iv.setImageBitmap(bm);
			return bm;
		}
		Matrix m = new Matrix();
		m.preRotate(deg);
		bm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), m, true);

		//bm = Compress(bm, 75);
		if(iv != null)
			iv.setImageBitmap(bm);
		return bm;
	}


}

  

  如果想要代码Demo的话,可以留言.有什么坑爹的地方,多多拍砖..over.

posted @ 2014-05-13 17:41  JarrahWu  阅读(16548)  评论(10编辑  收藏  举报