您的位置:首页 > 移动开发 > Android开发

超完整!Android获取图片的三种方法

2016-03-03 17:51 387 查看

本文导航

Camera的源码分析
获取Camera的缩略图
获取Camera的完整图片
获取Gallery的图片

源码部分分析

Camera.java →
点我定位,注意研究1134行与2023行的两个方法。

通过源码可以发现,输出的图片有2个分支

如果你没有指定Intent里面的Extra参数,它就返回一个序列化(
putExtra("data", bitmap)
)的Bitmap,从理论上来说,这样的代码写的很烂,属于
Magic Number


如果你指定了Intent里面的Extra参数
MediaStore.EXTRA_OUTPUT
,拍照后它就直接把bitmap写到了Uri里面了,返回是空

获得拍照的预览图

使用范围:获得很小的预览图,用于设置头像等地方。

返回示例:bitmap = data.getExtras().getParcelable("data");

public final static int REQUEST_IMAGE_CAPTURE = 1;

//start
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);

//receive
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != RESULT_OK) {
Log.d(TAG, "canceled or other exception!");
return;
}

if (requestCode == REQUEST_IMAGE_CAPTURE) {
Log.d(TAG, "REQUEST_IMAGE_CAPTURE");
Bitmap bitmap;
try {
//"data"这个居然没用常量定义,也是醉了,我们可以发现它直接把bitmap序列化到intent里面了。
bitmap = data.getExtras().getParcelable("data");
//TODO:do something with bitmap, Do NOT forget call Bitmap.recycler();
mCameraImageview.setImageBitmap(bitmap);
} catch (ClassCastException e){
//do something with exceptions
e.printStackTrace();
}
}

}

获得原始的拍照文件

使用范围:用于处理大的图片,比如使用滤镜,上传原始图像等操作,注意Uri不要用
data
私有目录,否则相机是写不进去的。

返回示例:

outputFileUri = file:///storage/sdcard0/JPEG_20150226_221320_-328629202.jpg

使用方法:

public final static int REQUEST_IMAGE_CAPTURE = 1;
Uri outputFileUri;

//start
@OnClick(R.id.itemSelectCamera) void itemSelectCamera() {
File file = FileUtils.createImageFile();
outputFileUri = Uri.fromFile(file);
Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(captureIntent, REQUEST_IMAGE_CAPTURE);
}

//receive
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

if (resultCode != RESULT_OK) {
Log.d(TAG, "canceled or other exception!");
return;
}

if (requestCode == REQUEST_IMAGE_CAPTURE) {
Log.d(TAG, "REQUEST_IMAGE_CAPTURE");
//TODO:Use the Uri
Intent intent = new Intent(this, ImageFilterActivity.class);
intent.setData(outputFileUri);
startActivity(intent);
}

}

关于文件如何创建,目前我找到的就是这个最稳定了,写到SD卡根目录,再说一遍,
data
目录(Context.getXXDir())是私有目录,其它程序是写不进去的

public class FileUtils {

public static File createImageFile() {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
try {
File image = File.createTempFile(imageFileName,  /* prefix */
".jpg",         /* suffix */
Environment.getExternalStorageDirectory()      /* directory */);
return image;
} catch (IOException e) {
//do noting
return null;
}
}
}

获取Gallery里面的图片

用途:获取MINETYPE为
"image/*"
的图片

返回示例 :

content://com.android.providers.media.documents/document/image%3A445

使用方法:

public final static int REQUEST_IMAGE_SELECT = 2;

@OnClick(R.id.itemSelectGallery) void itemSwitches() {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent, REQUEST_IMAGE_SELECT);
}

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

if (resultCode != RESULT_OK) {
Log.d(TAG, "canceled or other exception!");
return;
}

if (requestCode == REQUEST_IMAGE_SELECT) {
Log.d(TAG, "REQUEST_IMAGE_SELECT");
//TODO:Use Uri
Intent intent = new Intent(this, ImageFilterActivity.class);
intent.setData(data.getData());
startActivity(intent);
}
}

总结

这篇文章绝对比stackoverflow上的许多回答都更加完整,我花了很多时间查了很多的方案,最后定下来这三种方法是最好的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: