我有裁剪图像的代码,如下所示:
public void doCrop(){
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setType("image/");
List<ResolveInfo> list = getPackageManager().queryIntentActivities(intent,0);
int size = list.size();
if (size == 0 ){
Toast.makeText(this, "Cant find crop app").show();
return;
} else{
intent.setData(selectImageUri);
intent.putExtra("outputX", 300);
intent.putExtra("outputY", 300);
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("scale", true);
intent.putExtra("return-data", true);
if (size == 1) {
Intent i = new Intent(intent);
ResolveInfo res = list.get(0);
i.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
startActivityForResult(i, CROP_RESULT);
}
}
}
public void onActivityResult (int requestCode, int resultCode, Intent dara){
if (resultCode == RESULT_OK){
if (requestCode == CROP_RESULT){
Bundle extras = data.getExtras();
if (extras != null){
bmp = extras.getParcelable("data");
}
File f = new File(selectImageUri.getPath());
if (f.exists()) f.delete();
Intent inten3 = new Intent(this, tabActivity.class);
startActivity(inten3);
}
}
}
根据我的阅读,代码 intent.putExtra("outputX", 300); intent.putExtra("outputY", 300);
用于设置裁剪结果的分辨率,但为什么我无法获得高于 300x300 的结果图像分辨率?当我设置 intent.putExtra("outputX", 800); intent.putExtra("outputY", 800);
裁剪函数没有结果或崩溃,对这种情况有什么想法吗?
日志猫说“!!!!失败的 BINDER 交易!!!!”
最佳答案
这个问题遍布 stackoverflow。我很高兴这是因为我最近不得不自己解决这个问题。我会尽力标记一些重复项,但我更喜欢这个,因为它解决了图像大小有限的问题。
简答
简短的回答是不使用 return-data 选项。在此处阅读有关该选项以及如何检索图像的更多信息:http://www.androidworks.com/crop_large_photos_with_android .这篇文章很好地列出了 Intent 的(已知)配置选项以及如何使用它们。
Option #2: If you set return-data to "false", you will not receive a Bitmap back from the onActivityResult Intent in-line, instead you will need to set MediaStore.EXTRA_OUTPUT to a Uri (of File scheme only) where you want the Bitmap to be stored. This has some restrictions, first you need to have a temp filesystem location in order to give the file scheme URI, not a huge problem (except on some devices that don't have sdcards).
/** 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
更多信息
长答案是根本不要使用该 Intent 。继续阅读以找出原因。
非官方API
问题的核心是非官方 Intent 。非官方的,因为它不是公共(public) API 的一部分。目前它适用于大多数设备,但大多数设备还不够。此外,Google 可以随时更改此 Intent 而不通知您。打破所有使用它的应用程序。就像日历 API 曾经是非官方的一样。事实上这个裁剪 Intent 已经改变过一次。所以避免使用这个 Intent 。还有其他选择。请随意忽略此建议。
只是为了证明“适用于某些设备的声明”,请点击此链接并享受沮丧的 Android 开发人员讨论什么应该被视为核心 android 功能的一部分(而不是):https://code.google.com/p/android/issues/detail?id=1480
是时候写示例代码了吗?检查这个 github 项目:https://github.com/lorensiuswlt/AndroidImageCrop
关于大小限制
我在探索此 Intent 时遇到的另一个问题是图像裁剪大小限制。这可以使用上面的示例代码和任何超过 300 像素的图像大小轻松重现。基本上这个原始问题是关于什么的。在最好的情况下,您的应用程序会崩溃。但我见过更糟糕的悬挂设备,它们只能通过取出电池来重置。
现在,如果您删除“返回数据”选项,您将能够再次运行它。有关如何获得结果的更多信息,请参阅我已经引用此链接的简短回答:http://www.androidworks.com/crop_large_photos_with_android
解决方案
所以问题很多。问题需要解决方案。在谷歌为此提供公共(public) API 之前,唯一合适的解决方案是提供您自己的裁剪 Intent 。只需在 github 上获得像这样的合适的裁剪库:https://github.com/lvillani/android-cropimage
该项目缺少一些文档,但由于它是非官方 android crop intent 的摘录,您可以使用顶部列出的示例开始。只要确保不使用 return-data 选项即可。啊,看看 CropImageIntentBuilder 类。这应该可以让您轻松创建裁剪 Intent 。不要忘记将此 Activity 添加到您的 list 和写入外部数据存储的权限。
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?
就是这样。享受吧!
关于android - 如何使用 com.android.camera.action.CROP 设置输出图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12758425/