Android:使用固定纵横比的相机拍摄后裁剪图像

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1973359/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 04:00:50  来源:igfitidea点击:

Android: Crop an Image after Taking it With Camera with a Fixed Aspect Ratio

android

提问by Wysie

I'm trying to crop an image after taking it, and my code is as follows:

我在拍摄后尝试裁剪图像,我的代码如下:

   private void doTakePhotoAction() {

        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, MediaStore.Images.Media.EXTERNAL_CONTENT_URI.toString());
        intent.putExtra("crop", "true");
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        intent.putExtra("outputX", 96);
        intent.putExtra("outputY", 96);

        try {
            intent.putExtra("return-data", true);
            startActivityForResult(intent, PICK_FROM_CAMERA);
        } catch (ActivityNotFoundException e) {
            //Do nothing for now
        }
    }

With the above code, I'm able to go to crop mode, and crop the picture. However, the 1:1 aspect ratio is not enforced, and neither is the outputX and outputY. I believe this is because the intent was for taking a picture, not for cropping. I've also written another method to getData() from the Intent, and after that use the following:

使用上面的代码,我可以进入裁剪模式,并裁剪图片。但是,1:1 的纵横比没有被强制执行,outputX 和 outputY 也没有强制执行。我相信这是因为目的是拍照,而不是裁剪。我还编写了另一个方法来从 Intent 获取 getData(),然后使用以下内容:

Intent intent = new Intent("com.android.camera.action.CROP");
intent.setClassName("com.android.camera", "com.android.camera.CropImage");

However, when I do that, I get the following runtime error:

但是,当我这样做时,我收到以下运行时错误:

E/AndroidRuntime(14648): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.android.camera/com.android.camera.CropImage}: java.lang.NullPointerException

Thanks for the help! :)

谢谢您的帮助!:)

回答by Wysie

After doing some reading, I realized it can't be done so simply. My modded Contacts source is at http://github.com/Wysie, you can take a look if you're interested. Also, here's what I did to get it working:

读了一些书后,我意识到不能这么简单。我修改过的 Contacts 源在http://github.com/Wysie,如果你有兴趣可以看看。另外,这是我为使其正常工作所做的工作:

private void doTakePhotoAction() {
    // http://2009.hfoss.org/Tutorial:Camera_and_Gallery_Demo
    // http://stackoverflow.com/questions/1050297/how-to-get-the-url-of-the-captured-image
    // http://www.damonkohler.com/2009/02/android-recipes.html
    // http://www.firstclown.us/tag/android/
    // The one I used to get everything working: http://groups.google.com/group/android-developers/msg/2ab62c12ee99ba30 

    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    //Wysie_Soh: Create path for temp file
    mImageCaptureUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(),
                        "tmp_contact_" + String.valueOf(System.currentTimeMillis()) + ".jpg"));

    intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mImageCaptureUri);

    try {
        intent.putExtra("return-data", true);
        startActivityForResult(intent, PICK_FROM_CAMERA);
    } catch (ActivityNotFoundException e) {
        //Do nothing for now
    }
}

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode != RESULT_OK) {
        return;
    }

    switch (requestCode) {

    case CROP_FROM_CAMERA: {
        //Wysie_Soh: After a picture is taken, it will go to PICK_FROM_CAMERA, which will then come here
        //after the image is cropped.

        final Bundle extras = data.getExtras();

        if (extras != null) {
            Bitmap photo = extras.getParcelable("data");

            mPhoto = photo;
            mPhotoChanged = true;
            mPhotoImageView.setImageBitmap(photo);
            setPhotoPresent(true);
        }

        //Wysie_Soh: Delete the temporary file                        
        File f = new File(mImageCaptureUri.getPath());            
        if (f.exists()) {
            f.delete();
        }

        InputMethodManager mgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        mgr.showSoftInput(mPhotoImageView, InputMethodManager.SHOW_IMPLICIT);

        break;
    }

    case PICK_FROM_CAMERA: {
        //Wysie_Soh: After an image is taken and saved to the location of mImageCaptureUri, come here
        //and load the crop editor, with the necessary parameters (96x96, 1:1 ratio)

        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setClassName("com.android.camera", "com.android.camera.CropImage");

        intent.setData(mImageCaptureUri);
        intent.putExtra("outputX", 96);
        intent.putExtra("outputY", 96);
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        intent.putExtra("scale", true);
        intent.putExtra("return-data", true);            
        startActivityForResult(intent, CROP_FROM_CAMERA);

        break;

    }
    }
}

Hope it helps :)

希望能帮助到你 :)

回答by dharmin007

Check out this post. I tested it on my android 1.5 (Htc Magic) and worked perfectly.

看看这个帖子。我在我的 android 1.5 (Htc Magic) 上对其进行了测试,并且运行良好。

Android Works

安卓作品

回答by Christopher Orr

Have you tried this Intent(but keeping the crop/aspect/output/return-data extras you already have)?

你有没有试过这个Intent(但保留你已经拥有的裁剪/方面/输出/返回数据附加项)?

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");

That's basically what the Android contacts applicationdoes, so perhaps it won't quite fit your use case (i.e. taking a photo immediately, rather than having the option of selecting one from the gallery ortaking a new photo).

这基本上是Android 联系人应用程序所做的,所以它可能不太适合您的用例(即立即拍照,而不是从图库中选择一张照片拍摄一张新照片)。

Worth a try anyway! :)

总之值得一试!:)

回答by Gordons

Though this might be a very old thread, I was able to crop a picture programmatically with the following code :

虽然这可能是一个非常古老的线程,但我能够使用以下代码以编程方式裁剪图片:

        btnTakePicture.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            Intent cameraIntent = new Intent(
                    android.provider.MediaStore.ACTION_IMAGE_CAPTURE);

            startActivityForResult(cameraIntent, CAMERA_REQUEST);
        }
    });

then I cropped it with :

然后我裁剪它:

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    if (requestCode == CAMERA_REQUEST && resultCode == RESULT_OK) {

        photo = (Bitmap) data.getExtras().get("data");

        performcrop();
    }

}

private void performcrop() {
    DisplayMetrics displayMetrics = this.getResources().getDisplayMetrics();
    int width = displayMetrics.widthPixels;
    int height = displayMetrics.heightPixels;

    Bitmap croppedBmp = Bitmap.createBitmap(photo, 0, 0, width / 2,
            photo.getHeight());

    imageTaken.setImageBitmap(croppedBmp);
}

imageTaken is an ImageView Component in my view. You can see my source Here

imageTaken 在我看来是一个 ImageView 组件。你可以在这里看到我的来源