这个问题遍布stackoverflow。我很高兴,因为我最近不得不自己解决这个问题。我会尽我所能标记一些重复的,但我更喜欢这个,因为它解决了图像大小有限的问题。
简答
简短的回答是不使用 return-data 选项。在此处阅读有关该选项以及如何检索图像的更多信息:http ://www.androidworks.com/crop_large_photos_with_android 。这篇文章很好地列出了 Intent 的(已知的)配置选项以及如何使用它们。
选项 #2:如果您将 return-data 设置为“false”,您将不会收到来自 onActivityResult Intent 内联返回的位图,而是需要将 MediaStore.EXTRA_OUTPUT 设置为 Uri(仅限文件方案),您可以在其中希望存储位图。这有一些限制,首先您需要有一个临时文件系统位置才能提供文件方案 URI,这不是一个大问题(在一些没有 sdcard 的设备上除外)。
/** Called when the activity is first created. */
@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 {
// Launch picker to choose photo for selected contact
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); // lol, negative boolean noFaceDetection
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) {
// TODO Auto-generated catch block
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();
// new logic to get the photo from a URI
if (data.getAction() != null) {
processPhotoUpdate(tempFile);
}
}
}
break;
}
}
代码示例来自:http ://www.androidworks.com/crop_large_photos_with_android
更多信息
长答案是根本不使用这种意图。继续阅读以找出原因。
非官方 API
问题的核心是非官方意图。非官方的,因为不是公共 API 的一部分。目前它适用于大多数设备,但大多数还不够。此外,Google 可以随时更改此意图,而无需通知您。打破所有使用它的应用程序。就像日历 API 曾经是非官方的一样。事实上,这种作物意图已经改变了一次。所以避免使用这个意图。有替代方案。请随意忽略此建议。
只是为了证明“适用于某些设备的声明”,请点击此链接并享受沮丧的 Android 开发人员讨论哪些应该被视为核心 android 功能的一部分(而不是):https ://code.google.com/p/android /issues/detail?id=1480
示例代码的时间?检查这个 github 项目:https ://github.com/lorensiuswlt/AndroidImageCrop
关于尺寸限制
我在探索此意图时遇到的另一个问题是图像裁剪大小限制。这可以使用上面的示例代码和任何超过 300 像素的图像大小轻松复制。基本上这个原始问题是关于什么的。在最好的情况下,您的应用程序会崩溃。但我见过更糟糕的悬挂设备,只能通过取出电池来重置。
现在,如果您删除该“返回数据”选项,您将能够再次运行它。有关如何获得结果的更多信息,请参见我已经引用此链接的简短答案:http ://www.androidworks.com/crop_large_photos_with_android
解决方案
所以问题很多。问题需要解决方案。在谷歌为此提供公共 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);
// don't forget this, the error handling within the library is just ignoring if you do
builder.setSourceImage(mImageCaptureUri);
Intent intent = builder.getIntent(getApplicationContext());
// do not use return data for big images
intent.putExtra("return-data", false);
// start an activity and then get the result back in onActivtyResult
startActivityForResult(intent, CROP_FROM_CAMERA);
}
使用这个库也为更多的定制打开了大门。很高兴知道在功能上用于调整大小的核心位图:How to crop the parsed image in android?
就是这样。享受!