安卓拍照生成缩略图及读取缩略图、原图、角度等信息

最近做项目遇到拍照然后显示图片到列表,再上传缩略图到服务器。为了避免OOM就在想怎么做才是最好的,最安全的。下面是我的个人想法,如果有更好的办法,希望可以给我留言共同学习,谢谢。


解决办法:安卓拍照会生成原图和缩略图的uri,我们可以去Media-Db中寻找,不需要手动压缩图片,然后显示到列表,点击加载大图,列表显示缩略图。但是安卓手机各有不同,又遇到新问题,入下:

问题一:

小米手机返回的全是file:///storage/emulated/0/ibanshou/20170325_110120.jpg,

三星等其他机器是content://media/external/images/media/25087

问题二:

拍照默认不生成缩略图。


下面我就贴出我的代码:

首先是调用系统相机拍照。并让它返回Uri。

intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getPackageManager()) != null) {
	ContentValues contentValues = new ContentValues();
	if(Build.MANUFACTURER.toLowerCase().equals("samsung"))
		contentValues.put(MediaStore.Images.Media.ORIENTATION, 90f);
	contentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
	//mPhotoUri是拍照返回的Uri
 mPhotoUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);intent.putExtra(MediaStore.EXTRA_OUTPUT, mPhotoUri);startActivityForResult(intent, 1);}




接着是在回调中生成缩略图:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
	if (resultCode != RESULT_OK) {
		return;
	}
	if (isTakePhoto) {//拍照的
		intent.putExtra("imageUri", mPhotoUri.toString());
		//根据得到的Uri去生成对于的缩略图,并更新Media数据库的关联。
		long id = ContentUris.parseId(mPhotoUri);
		// MINI.KIND是要生成缩略图的质量,不懂可以百度下这个。
		MediaStore.Images.Thumbnails.getThumbnail(getContentResolver(), id,
				MediaStore.Images.Thumbnails.MINI_KIND, null);
	} else {//相册选的
		if (data != null) {
			if (data.getExtras() != null)
				intent.putExtras(data.getExtras());
			if (data.getData() != null)
				intent.setData(data.getData());
		}
	}
	setResult(1, intent);
	finish();
}




下面回到列表页面的回调,显示到ImageView:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
	if (data != null) {
		mImageCaptureUri = data.getData();
		image_path = data.getStringExtra("imageUri");
			if (mImageCaptureUri != null) {
				//选相册
				FileUtils.getPic(mImageCaptureUri, mContext, image_iv1, imagePath, 0);
			} else if (!StringUtils.dealNull(image_path).equals("")) {
				//拍照
				mImageCaptureUri = Uri.parse(data.getStringExtra("imageUri"));
				FileUtils.getPic(mImageCaptureUri, mContext, image_iv1, imagePath, 0);
			}
	}
}




下面贴出FileUtils的相关代码,主要是对Media-DB的操作:

/**
	 * 获取缩略图
	 */
	public static String getThumbnails(Context mContext, long image_id) {
		String image_path = "";
		ContentResolver cr = mContext.getContentResolver();
		String[] projection = {MediaStore.Images.Thumbnails.DATA, MediaStore.Images.Thumbnails.IMAGE_ID};
		Cursor cursor = cr.query(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, projection,
				MediaStore.Images.Thumbnails.IMAGE_ID + "=" + image_id, null, null);
		if (cursor != null) {
			try {
				if (cursor.moveToFirst()) {
					int dataColumn = cursor.getColumnIndex(MediaStore.Images.Thumbnails.DATA);
					int dataColumn_id = cursor.getColumnIndex(MediaStore.Images.Thumbnails.IMAGE_ID);

					do {
						image_path = cursor.getString(dataColumn);
						Log.i("yfchu", image_path + "\n" + cursor.getInt(dataColumn_id));
					} while (cursor.moveToNext());
				}
			} finally {
				cursor.close();
			}
		}
		return image_path;
	}

	/**
	 * 获取图片Id
	 */
	public static long getImageId(Uri uri, Context mContext) {
		long imageId = -1;
		String path = uri.getEncodedPath();
		if (path != null)
			path = Uri.decode(path);
		StringBuffer buff = new StringBuffer();
		buff.append("(").append(MediaStore.Images.ImageColumns.DATA).append("=")
				.append("'" + path + "'").append(")");
		String[] projection = {Images.ImageColumns._ID, Images.ImageColumns.TITLE,
				Images.ImageColumns.DISPLAY_NAME, Images.ImageColumns.DATA};
		ContentResolver cr = mContext.getContentResolver();
		Cursor cursor = cr.query(Images.Media.EXTERNAL_CONTENT_URI, projection,
				buff.toString(), null, null);
		if (cursor != null) {
			try {
				if (cursor.moveToFirst()) {
					do {
						imageId = cursor.getInt(cursor.getColumnIndex(Images.ImageColumns._ID));
						String title = cursor.getString(cursor.getColumnIndex(Images.ImageColumns.TITLE));
						String name = cursor.getString(cursor.getColumnIndex(Images.ImageColumns.DISPLAY_NAME));
						String data = cursor.getString(cursor.getColumnIndex(Images.ImageColumns.DATA));
						Log.i("yfchu", imageId + "\n" + title + "\n" + name + "\n" + data);
					} while (cursor.moveToNext());
				}
			} finally {
				cursor.close();
			}
		}
		return imageId;
	}

	/**
	 * 获取图片角度
	 */
	public static int getImageRotate(Uri uri, Context mContext, long id) {
		int rotate = 0;
		String path = uri.getEncodedPath();
		if (path != null)
			path = Uri.decode(path);
		String[] projection = {Images.Media.DATA, Images.Media.ORIENTATION};
		ContentResolver cr = mContext.getContentResolver();
		Cursor cursor = cr.query(Images.Media.EXTERNAL_CONTENT_URI, projection,
				Images.Media._ID + "=" + id, null, null);
		if (cursor != null) {
			try {
				if (cursor.moveToFirst()) {
					do {
						rotate = cursor.getInt(cursor.getColumnIndex(Images.Media.ORIENTATION));
					} while (cursor.moveToNext());
				}
			} finally {
				cursor.close();
			}
		}
		return rotate;
	}

	/*
	* 获取图片--这是主要方法
	* */
	public static void getPic(Uri mImageCaptureUri, Context mContext,
							  ImageView image_iv1, String[] imagePath,int position) {
		long image_id = -1;
		if (mImageCaptureUri.getScheme().equals("file"))//判断是file还是content
			image_id = FileUtils.getImageId(mImageCaptureUri, mContext);//根据路径去Db查询imageId
		else
			image_id = ContentUris.parseId(mImageCaptureUri);//content的尾部就是imageId直接拿。
		int rotate = FileUtils.getImageRotate(mImageCaptureUri, mContext, image_id);//获取图片角度
		String path = FileUtils.getThumbnails(mContext, image_id);//根据ImageId去Thumbnails中查询ImageId列中相等的字段就是它的缩略图
		if (path.equals("")) {//为空代表无缩略图
			try {
				if (image_id != -1) {//得到ImageId但是系统没有生成缩略图,帮它生成缩略图并关联。下次再选就有了
					MediaStore.Images.Thumbnails.getThumbnail(
							mContext.getContentResolver(), image_id,
							MediaStore.Images.Thumbnails.MINI_KIND, null);
					path = FileUtils.getThumbnails(mContext, image_id);
				} else {
					//这里处理特殊情况,就是原图和缩略图在db中都查询不到得情况。
					//你只能自己压缩了。这里写压缩图片方法。
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		if (image_id != -1) {//一切正常,数据库查到大图和缩略图等,直接显示。
			File file = new File(path);
			imagePath[position] = file.getAbsolutePath();
			if (imagePath[position] != null) {
				Picasso.with(mContext).load(file).rotate(rotate).into(image_iv1);
			}
		}
	}




由于代码在公司项目里,没有单独整出来,就不发工程了。


根据这些网站总结学习的:

http://blog.csdn.net/csqingchen/article/details/45502813

还有看源码,从中知道如何系统生成缩略图到db

MediaStore.Images.Media.insertImage()



你可能感兴趣的:(移动开发)