这个问题在stackoverflow上到处都是。我很高兴看到它,因为最近我不得不自己解决这个问题。我会尽力标记一些重复的内容,但我更喜欢这个问题,因为它涉及有限的图像大小问题。
简短回答
简短回答是不要使用return-data选项。 在这里阅读更多关于该选项以及如何检索图像的信息:http://www.androidworks.com/crop_large_photos_with_android。 该文章在列出Intent的(已知)配置选项以及如何使用它们方面做得非常好。
选项#2:如果将return-data设置为“false”,则您将无法从onActivityResult Intent中直接接收位图,而必须将MediaStore.EXTRA_OUTPUT设置为Uri(仅文件模式),其中您希望存储位图。 这有一些限制,首先需要一个临时文件系统位置才能提供文件URI,这不是什么大问题(除了一些没有SD卡的设备)。
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
thiz = this;
setContentView(R.layout.main);
mBtn = (Button) findViewById(R.id.btnLaunch);
photo = (ImageView) findViewById(R.id.imgPhoto);
mBtn.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
try {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
intent.setType("image/*");
intent.putExtra("crop", "true");
intent.putExtra("aspectX", aspectX);
intent.putExtra("aspectY", aspectY);
intent.putExtra("outputX", outputX);
intent.putExtra("outputY", outputY);
intent.putExtra("scale", scale);
intent.putExtra("return-data", return_data);
intent.putExtra(MediaStore.EXTRA_OUTPUT, getTempUri());
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
intent.putExtra("noFaceDetection",!faceDetection);
if (circleCrop) {
intent.putExtra("circleCrop", true);
}
startActivityForResult(intent, PHOTO_PICKED);
} catch (ActivityNotFoundException e) {
Toast.makeText(thiz, R.string.photoPickerNotFoundText, Toast.LENGTH_LONG).show();
}
}
});
}
private Uri getTempUri() {
return Uri.fromFile(getTempFile());
}
private File getTempFile() {
if (isSDCARDMounted()) {
File f = new File(Environment.getExternalStorageDirectory(),TEMP_PHOTO_FILE);
try {
f.createNewFile();
} catch (IOException e) {
Toast.makeText(thiz, R.string.fileIOIssue, Toast.LENGTH_LONG).show();
}
return f;
} else {
return null;
}
}
private boolean isSDCARDMounted(){
String status = Environment.getExternalStorageState();
if (status.equals(Environment.MEDIA_MOUNTED))
return true;
return false;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case PHOTO_PICKED:
if (resultCode == RESULT_OK) {
if (data == null) {
Log.w(TAG, "Null data, but RESULT_OK, from image picker!");
Toast.makeText(this, R.string.no_photo_picked,
Toast.LENGTH_SHORT).show();
return;
}
final Bundle extras = data.getExtras();
if (extras != null) {
File tempFile = getTempFile();
if (data.getAction() != null) {
processPhotoUpdate(tempFile);
}
}
}
break;
}
}
来自以下网址的代码示例: http://www.androidworks.com/crop_large_photos_with_android
更多信息
详细回答是不要使用该意图。请继续阅读以了解原因。
非官方 API
问题的核心是非官方意图。非官方的意思是不属于公共 API 的一部分。目前它可以在大多数设备上工作,但这还远远不够。此外,谷歌可以随时更改此意图,而不让您知道。这将破坏所有使用它的应用程序。这有点像日历 API 曾经是非官方的情况。实际上,这个剪裁意图已经改变过一次。因此,请避免使用此意图。有替代方案。如果您愿意,请忽略此建议。
为了验证“适用于某些设备”的说法,请跟随此链接并享受沮丧的 Android 开发人员讨论什么应该被视为核心 Android 功能(但却不是):https://code.google.com/p/android/issues/detail?id=1480
是时候给出示例代码了吗?请查看此 GitHub 项目:https://github.com/lorensiuswlt/AndroidImageCrop
关于大小限制
我在探索此意图时遇到的另一个问题是图像裁剪大小限制。只需使用上面的示例代码和大于 300 像素的图像大小即可轻松重现。这基本上就是原始问题所涉及的内容。在最好的情况下,您的应用程序将崩溃。但我见过更糟糕的情况,甚至导致设备挂起,只能通过拆卸电池来重置。
现在,如果您删除该“return-data”选项,则可以再次运行它。有关如何获得结果的更多信息可以在简短的答案中找到,其中我已经引用了此链接:http://www.androidworks.com/crop_large_photos_with_android
解决方案
所以有很多问题。问题需要解决。在 Google 推出公共 API 之前,唯一的合理解决方案是提供自己的裁剪意图。只需获取一个适当的裁剪库,比如在 GitHub 上的这个:https://github.com/lvillani/android-cropimage
该项目缺乏一些文档,但由于它是非官方的 Android 裁剪意图的提取,因此您可以使用上面列出的示例来开始。只要确保不使用“return-data”选项即可。啊,请查看 CropImageIntentBuilder 类。这应该让您轻松创建用于裁剪的意图。别忘了将此 Activity 添加到您的清单中,并添加写入外部数据存储的权限。
private void doCrop(File croppedResult){
CropImageIntentBuilder builder = new CropImageIntentBuilder(600,600, croppedResult);
builder.setSourceImage(mImageCaptureUri);
Intent intent = builder.getIntent(getApplicationContext());
intent.putExtra("return-data", false);
startActivityForResult(intent, CROP_FROM_CAMERA);
}
使用此库还可以打开更多自定义的门。需要知道的是用于调整大小的核心位图功能:
如何在Android中裁剪解析的图像?。
就是这样。享受吧!
if(size == 1)
将使您的应用程序受到影响。如果我是你,我会跳过这一部分。此外,请考虑使用Intent#createChooser(..)
方法,而不是启动第一个可用组件-它可能不是用户首选的应用程序。 - Jens