【问题标题】:Android: Crop an Image after Taking it With Camera with a Fixed Aspect RatioAndroid:使用固定纵横比的相机拍摄图像后裁剪图像
【发布时间】:2009-12-29 07:21:24
【问题描述】:

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

   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
        }
    }

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

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

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

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

感谢您的帮助! :)

【问题讨论】:

    标签: android


    【解决方案1】:

    读了一些之后,我意识到不能这么简单。我修改后的通讯录源在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;
    
        }
        }
    }
    

    希望对你有帮助:)

    【讨论】:

    • 感谢 Wysie,但它不适用于 android 2.x。这是例外:04-29 18:35:02.857: ERROR/AndroidRuntime(3486): Caused by: android.content.ActivityNotFoundException: Unable to find explicit activity class {com.android.camera/com.android.camera.CropImage };您是否在 AndroidManifest.xml 中声明了此活动?
    • 如果 outputX 超过 500,所以没有任何想法?
    • 很棒的代码!谢谢你。如果您有来自@NguyenMinhBinh 的错误,请查看此thread
    • 它在 onactivityresult 中返回 null
    【解决方案2】:

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

    Android Works

    【讨论】:

      【解决方案3】:

      你试过这个Intent(但保留你已经拥有的crop/aspect/output/return-data extras)吗?

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

      这基本上就是Android contacts application 所做的,所以它可能不太适合您的用例(即立即拍照,而不是从图库中选择一张一张新照片)。

      无论如何都值得一试! :)

      【讨论】:

      • 对我也不起作用:android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.GET_CONTENT (has extras) }
      【解决方案4】:

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

              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);
              }
          });
      

      然后我将其裁剪为:

          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 在我看来是一个 ImageView 组件。可以看我的源码Here

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-18
        • 1970-01-01
        • 2010-12-21
        • 1970-01-01
        • 2013-07-30
        • 1970-01-01
        相关资源
        最近更新 更多