Android - 相机和画廊意图后的裁剪给出了奇怪的结果

Posted

技术标签:

【中文标题】Android - 相机和画廊意图后的裁剪给出了奇怪的结果【英文标题】:Android - Cropping after Camera and Gallery Intents Gives Strange Results 【发布时间】:2012-03-31 12:05:21 【问题描述】:

我正在尝试启动 android 相机意图和选择照片意图(两个按钮,一个用于拍照,一个用于从图库中选择),两者都需要在它们之后启动裁剪意图,然后将裁剪后的照片返回到我的应用程序的活动。我浏览了许多其他地方发布的示例,但我的实现却得到了奇怪的结果。

对于拍照事件,它似乎工作正常,除了拍照并进入裁剪模式后,会弹出错误的照片。而不是裁剪你刚刚拍摄的照片,而是裁剪一张旧照片,我无法弄清楚它来自哪里。此外,有时在完成裁剪意图后,它会在 Parcel.readException 之后崩溃并出现 nullpointerexception(不能总是重现,但我认为如果您尽快拍照并裁剪,它会发生更多)。

对于选择照片意图,您的图库会按预期弹出,但在选择照片时,所发生的只是“已保存”消息被烘烤,而不是返回到我的应用程序的带有图像的活动。我相信我对选择照片意图的工作方式存在误解(我几乎重复使用了拍摄照片意图的代码)。

在这两种情况下,在裁剪模式下,尽管指定了 "scale" = false,您仍然可以调整裁剪区域的大小。

我的代码如下:

public class TestPhotoActivity extends Activity 

private ImageView imageView;
private Uri imageUri;

private int int_Height_crop = 600;
private int int_Width_crop = 600;

public final static int TAKE_PICTURE = 0;
public final static int CHOOSE_PICTURE = 1;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) 

    super.onCreate(savedInstanceState); 
    setContentView(R.layout.choose_photo); 

    imageView = (ImageView) findViewById(R.id.photo);

    Button take_photo = (Button) findViewById(R.id.take_photo);
    take_photo.setOnClickListener(new View.OnClickListener() 
        public void onClick(final View view)   
            takePhoto(view);
        
    );

    Button choose_photo = (Button) findViewById(R.id.choose_photo);
    choose_photo.setOnClickListener(new View.OnClickListener() 
        public void onClick(final View view)   
            choosePhoto(view);
        
    );     



public void takePhoto(View view)       
    Intent intent = new Intent("android.media.action.IMAGE_CAPTURE", null);  
    intent.putExtra("crop", "true");
    intent.putExtra("aspectX", 1);
    intent.putExtra("aspectY", 1);
    intent.putExtra("outputX", int_Width_crop);
    intent.putExtra("outputY", int_Height_crop);
    intent.putExtra("scale", false);
    intent.putExtra("return-data", true);
    File photo = new File(Environment.getExternalStorageDirectory(), System.currentTimeMillis() + ".jpg");      
    intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo));
    imageUri = Uri.fromFile(photo);
    intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
    intent.putExtra("noFaceDetection", true);
    startActivityForResult(intent, TAKE_PICTURE);


public void choosePhoto(View view)         
    Intent intent = new Intent(Intent.ACTION_PICK, null); 
    intent.setType("image/*");
    intent.putExtra("crop", "true");
    intent.putExtra("aspectX", 1);
    intent.putExtra("aspectY", 1);
    intent.putExtra("outputX", int_Width_crop);
    intent.putExtra("outputY", int_Height_crop);
    intent.putExtra("scale", false);
    intent.putExtra("return-data", true);
    File photo = new File(Environment.getExternalStorageDirectory(), System.currentTimeMillis() + "Pic.jpg");        
    intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo));
    imageUri = Uri.fromFile(photo);
    intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
    startActivityForResult(intent, CHOOSE_PICTURE);         


@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) 
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode)           
        case TAKE_PICTURE:              
            Log.d("photo", "requestCode: " + requestCode + "resultCode: " + resultCode + "wanted result: " + Activity.RESULT_OK);               
            if (resultCode == Activity.RESULT_OK) 

                if (data == null) 
                    Log.w("photo", "Null data, but RESULT_OK, from image picker!");
                    Toast t = Toast.makeText(this, "No photo picked.", Toast.LENGTH_SHORT);
                    t.show();
                    return;
                

                final Bundle extras = data.getExtras();

                if (extras != null)    
                    Log.d("photo", "extras is not null");
                    Uri selectedImage = imageUri;
                    getContentResolver().notifyChange(selectedImage, null);                
                    ContentResolver cr = getContentResolver();
                    Bitmap bitmap;
                    try 
                        bitmap = android.provider.MediaStore.Images.Media.getBitmap(cr, selectedImage);     
                        Log.d("photo", "data.getAction() is not null. setting image.");
                        imageView.setImageBitmap(bitmap);                           
                     catch (Exception e) 
                        Toast.makeText(this, "Failed to load", Toast.LENGTH_SHORT).show();
                        Log.e("photo", e.toString());
                    
                
            
        case CHOOSE_PICTURE:
            Log.d("photo", "requestCode: " + requestCode + "resultCode: " + resultCode + "wanted result: " + Activity.RESULT_OK);
            if(resultCode == RESULT_OK)
                Log.d("photo", "resultCode is ok");

                if (data == null) 
                    Log.w("photo", "Null data, but RESULT_OK, from image picker!");
                    Toast t = Toast.makeText(this, "No photo picked.", Toast.LENGTH_SHORT);
                    t.show();
                    return;
                

                final Bundle extras = data.getExtras();

                if (extras != null)    
                    Log.d("photo", "extras is not null");
                    Uri selectedImage = imageUri;
                    getContentResolver().notifyChange(selectedImage, null);                
                    ContentResolver cr = getContentResolver();
                    Bitmap bitmap;
                    try 
                        bitmap = android.provider.MediaStore.Images.Media.getBitmap(cr, selectedImage);  
                        Log.d("photo", "data.getAction() is not null. setting image.");
                        imageView.setImageBitmap(bitmap);
                     catch (Exception e) 
                        Toast.makeText(this, "Failed to load", Toast.LENGTH_SHORT).show();
                        Log.e("photo", e.toString());
                    
                                   

            
    



非常感谢任何帮助!

编辑:我还应该注意,我正在测试 LG Optimus LTE,Android 2.3

【问题讨论】:

同样的问题,在我的三星 i9000 上运行良好,但是我的应用程序的很多用户对此都有奇怪的问题......你找到任何解决方案了吗? 【参考方案1】:

我认为您的问题来自在临时文件名中使用 System.currentTimeMillis() 。这可以解释有时会得到一个较旧的文件。

我建议只重用同一个临时文件。

希望对你有帮助...

【讨论】:

以上是关于Android - 相机和画廊意图后的裁剪给出了奇怪的结果的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Android 相机上使用意图添加功能裁剪图像?

是否可以自定义 android 的相机裁剪意图视图?

裁剪后的Android图像视图仅显示小图像

android 的默认图库和相机意图是不是适用于所有设备?

将相机或画廊中的图像保存在 phonegap 的画布中,并在旋转和裁剪后保存

来自画廊/相机意图的图片方向[重复]