adi*_*ean 8 android image crop image-processing
我有代码来裁剪图像,如下所示:
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
从我读过的,代码intent.putExtra("outputX", 300); intent.putExtra("outputY", 300);用于设置裁剪结果的分辨率,但为什么我不能得到高于300x300的结果图像分辨率?当我设置intent.putExtra("outputX", 800); intent.putExtra("outputY", 800);裁剪功能没有结果或崩溃时,对于这种情况有什么想法吗?
原木猫说"!!!! FAULED BINDER TRANSACTION!!!
hcp*_*cpl 28
这个问题遍布stackoverflow.我很高兴这是因为我最近必须自己解决这个问题.我会尽我所能来标记一些重复项,但我更喜欢这一项,因为它解决了有限图像大小的问题.
简短的回答是不使用return-data选项.阅读有关该选项的更多信息以及如何在此处检索图像:http://www.androidworks.com/crop_large_photos_with_android.这篇文章很好地列出了Intent的(已知)配置选项以及如何使用它们.
选项#2:如果将return-data设置为"false",则不会从onActivityResult Intent内联返回Bitmap,而是需要将MediaStore.EXTRA_OUTPUT设置为Uri(仅限文件方案)想要存储位图.这有一些限制,首先你需要有一个临时文件系统位置,以便给出文件方案URI,而不是一个大问题(除了一些没有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;
}
}
Run Code Online (Sandbox Code Playgroud)
代码示例来自:http://www.androidworks.com/crop_large_photos_with_android
长期的答案是根本不使用这种意图.继续阅读以找出原因.
问题的核心是非正式意图.非官方的,不是公共API的一部分.目前它适用于大多数设备,但大多数只是不够.此外,谷歌可以随时更改此意图,而不会让您知道.打破所有使用它的应用程序.就像日历API曾经是非正式的一样.事实上,这种作物意图已经改变了一次.所以避免使用这个意图.还有其他选择.随意忽略这个建议.
只是为了证明"为一些设备声明工作",请点击此链接,享受沮丧的Android开发人员讨论应该被视为核心Android功能的一部分(并且不是):https://code.google.com/p/android /问题/细节?ID = 1480
时间代码?检查这个github项目:https://github.com/lorensiuswlt/AndroidImageCrop
我在探索这个意图时遇到的另一个问题是图像裁剪尺寸限制.使用上面的示例代码和300像素以上的任何图像大小都可以轻松地再现这一点.基本上这个原始问题是关于什么的.在最好的情况下,您的应用程序将崩溃.但我看到更糟糕的是挂起的设备只能通过取下电池来重置.
现在,如果您删除'return-data'选项,您将能够再次运行它.有关如何获得结果的更多信息,请参阅我刚才引用此链接的简短回答:http://www.androidworks.com/crop_large_photos_with_android
所以很多问题.问题需要解决方案.谷歌为此提出公共API之前唯一合适的解决方案就是提供自己的作物意图.只需在github上找到一个合适的裁剪库:https://github.com/lvillani/android-cropimage
该项目缺少一些文档,但由于它是非官方android作物意图的摘录,您可以使用顶部列出的示例开始.只需确保不要使用return-data选项.啊,看看CropImageIntentBuilder类.这应该可以让您轻松创建裁剪的意图.不要忘记将此活动添加到清单以及写入外部数据存储的权限.
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);
}
Run Code Online (Sandbox Code Playgroud)
使用此库还可以打开更多自定义的大门.很有用的是功能上用于调整大小的核心位图:如何在android中裁剪解析的图像?
就是这样.请享用!
Intent不是公共Android API的一部分,并不保证可以在所有设备上运行.它在Android 1.x和2.x的早期版本中使用,但它不再使用,不推荐使用.这可能就是为什么它在整个地方崩溃或者工作不当.
使用诸如Bitmap.createBitmap(..)或Bitmap.createScaledBitmap(..)创建原始图像的调整大小或裁剪版本的方法.这些是Android API的一部分,保证可以使用.
要裁剪位图,您可以使用Bitmap.createBitmap(Bitmap, int x, int y, int width, int height).例如,如果您需要从位图的每一侧裁剪10个像素,请使用:
Bitmap croppedBitmap = Bitmap.createBitmap(originalBitmap, 10, 10, originalBitmap.getWidth() - 20, originalBitmap.getHeight() - 20);
Run Code Online (Sandbox Code Playgroud)
如果需要向用户显示选择器.然后你可以做这样的事情:
private static final String TEMP_PHOTO_FILE = "temporary_holder.jpg";
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
photoPickerIntent.setType("image/*");
photoPickerIntent.putExtra("crop", "true");
photoPickerIntent.putExtra(MediaStore.EXTRA_OUTPUT, getTempUri());
photoPickerIntent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
startActivityForResult(photoPickerIntent, REQ_CODE_PICK_IMAGE);
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) {
}
return f;
} else {
return null;
}
}
private boolean isSDCARDMounted(){
String status = Environment.getExternalStorageState();
if (status.equals(Environment.MEDIA_MOUNTED))
return true;
return false;
}
protected void onActivityResult(int requestCode, int resultCode,
Intent imageReturnedIntent) {
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
switch (requestCode) {
case REQ_CODE_PICK_IMAGE:
if (resultCode == RESULT_OK) {
if (imageReturnedIntent!=null){
File tempFile = getTempFile();
String filePath= Environment.getExternalStorageDirectory()
+ "/temporary_holder.jpg";
System.out.println("path "+filePath);
Bitmap selectedImage = BitmapFactory.decodeFile(filePath);
_image = (ImageView) findViewById(R.id.image);
_image.setImageBitmap(selectedImage );
}
}
}
Run Code Online (Sandbox Code Playgroud)
来自这里的代码
| 归档时间: |
|
| 查看次数: |
28169 次 |
| 最近记录: |