【问题标题】:How to do custom image cropping in android如何在android中进行自定义图像裁剪
【发布时间】:2013-05-21 20:27:04
【问题描述】:

在我的应用程序中,我需要从图库/相机中获取图像,裁剪这些图像,然后将裁剪后的图像保存到其他地方。下面的代码完成了大部分工作,但无法根据我的喜好裁剪图像。使用下面的代码,我可以使用图像中间坐标的顶部、底部、左侧和右侧 4 个坐标裁剪图像;但我需要使用 8 个坐标进行裁剪。 This image 表达了我的意思。

public class MainActivity extends Activity {
  private static final int PICK_FROM_CAMERA = 1;
  private static final int PICK_FROM_GALLERY = 2;
  private static final int PRESS_OK = 3;
  ImageView imgview;
  String m_path;
  Bitmap m_thePic;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    imgview = (ImageView) findViewById(R.id.imageView1);
    Button buttonCamera = (Button) findViewById(R.id.btn_take_camera);
    Button buttonGallery = (Button) findViewById(R.id.btn_select_gallery);
    Button buttonOk = (Button) findViewById(R.id.btn_ok);

    File folder = new File(Environment.getExternalStorageDirectory().toString() + "/Images/");
    folder.mkdirs();
    buttonCamera.setOnClickListener(new View.OnClickListener() {
      public void onClick(View v) {
        // call android default camera
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT,
                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI.toString());
        // ******** code for crop image
        intent.putExtra("crop", "true");
        intent.putExtra("aspectX", 0);
        intent.putExtra("aspectY", 0);
        intent.putExtra("outputX", 100);
        intent.putExtra("outputY", 150);

        try {
          intent.putExtra("return-data", true);
          startActivityForResult(intent, PICK_FROM_CAMERA);
        } catch (ActivityNotFoundException e) {
          // Do nothing for now
        }
      }
    });
    buttonGallery.setOnClickListener(new View.OnClickListener() {
      public void onClick(View v) {
        // TODO Auto-generated method stub
        Intent intent = new Intent();
        // call android default gallery
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        // ******** code for crop image
        intent.putExtra("crop", "true");
        intent.putExtra("aspectX", 0);
        intent.putExtra("aspectY", 0);
        intent.putExtra("outputX", 200);
        intent.putExtra("outputY", 150);

        try {
          intent.putExtra("return-data", true);
          startActivityForResult(Intent.createChooser(intent, "Complete action using"), 1);
        } catch (ActivityNotFoundException e) {
          // Do nothing for now
        }
      }
    });
    buttonOk.setOnClickListener(new View.OnClickListener() {
      public void onClick(View v) {
        String m_path = Environment.getExternalStorageDirectory().toString();
        File m_imgDirectory = new File(m_path + "/Images/");
        File m_file = new File(m_path);
        String m_fileid = "nm_tech" + System.currentTimeMillis() + "";
        m_file = new File(m_path, "/Images/" + m_fileid + ".jpg");
        Uri outputFileUri = Uri.fromFile(m_file);

        Intent intent = new Intent(MainActivity.this,
                                   ImageGalleryDemoActivity.class);
        intent.putExtra("image", m_fileid);
        startActivity(intent);
        // startActivityForResult(intent,PRESS_OK);
        // call android default camera
        // Toast.makeText(getApplicationContext(), ,1234).show();
      }
    });
  }

  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Bundle extras = data.getExtras();
    Bitmap m_thePic = extras.getParcelable("data");
    String m_path = Environment.getExternalStorageDirectory().toString();
    File m_imgDirectory = new File(m_path + "/Images/");
    if (!m_imgDirectory.exists()) {
      m_imgDirectory.mkdir();
    }
    OutputStream m_fOut = null;
    File m_file = new File(m_path);
    m_file.delete();
    String m_fileid = "nm_tech" + System.currentTimeMillis() + "";
    m_file = new File(m_path, "/Images/" + m_fileid + ".jpg");
    try {
      if (!m_file.exists()) {
        m_file.createNewFile();
      }
      m_fOut = new FileOutputStream(m_file);
      Bitmap m_bitmap = m_thePic.copy(Bitmap.Config.ARGB_8888, true);
      m_bitmap.compress(Bitmap.CompressFormat.PNG, 100, m_fOut);
      m_fOut.flush();
      m_fOut.close();
      MediaStore.Images.Media.insertImage(getContentResolver(),
                      m_file.getAbsolutePath(),
                                          m_file.getName(),
                                          m_file.getName());
    } catch (Exception p_e) {
    }

    if (requestCode == PICK_FROM_CAMERA) {
      if (extras != null) {
        // Bitmap photo = extras.getParcelable("data");
        imgview.setImageBitmap(m_thePic);
      }
    }

    if (requestCode == PICK_FROM_GALLERY) {
      // Bundle extras2 = data.getExtras();
      if (extras != null) {
        imgview.setImageBitmap(m_thePic);
      }
    }

    if (requestCode == PRESS_OK) {
      Bundle extras11 = data.getExtras();
      Bitmap bmp = (Bitmap) extras.get("data");

      /*
       * Bitmap photo = extras.getParcelable("data");
       * imgview.setImageBitmap(photo); Intent n=new
       * Intent(getApplicationContext(),ImageGalleryDemoActivity.class);
       * n.putExtra("data",photo); startActivity(n);
       */
    }
  }
}

【问题讨论】:

  • 图片保存的时候必须是一个矩形,那你要什么空白区域呢?透明的,黑色的?您可以遍历您的点并找到保存图像所需的最小 Rect,然后在新图像上绘制图像部分,然后使用路径或您填充的任何内容删除侧面的空矩形。一点点数学,但是...
  • thnkyou,空白区域不是我的 prblm...我想以任何方式填充透明 noprblm...正常使用我的代码 1 可以使用左侧、顶部、右侧和底部 4 个点进行裁剪,在这里看到我的图像一次 8 点是 threre 使用我必须裁剪图像的那些 ponts

标签: android android-emulator


【解决方案1】:

这是一种简单的方法,您可以从坐标数组中创建最少需要的矩形

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);             
    setContentView(R.layout.activity_main);
    Rect r = getRect(new int[]{10, 10, 20, 20, 30, 30}, new int[]{20, 100, 10, 110, 20, 100});
    System.out.println(r.left + " " + r.top + " " + r.bottom + " " + r.right);
}

public Rect getRect(int[] x, int y[]){
    Rect r = new Rect();
        // Set the first coordinate, in order not to include 0, 0
    r.set(x[0], y[0], x[0], y[0]);
    for(int i = 1; i < x.length; i++){
        r.union(x[i], y[i]);
    }
    return r;
}

编辑:看你有 8 分,就这样调用这个 getRect

Rect rectToDraw = getRect(new int{yourx1, yourx2, yourx3, yourx4, yourx5, yourx6, yourx7, yourx8,}, new int{youry1, youry2, youry3, youry4, youry5, youry6, youry7, youry8});

你可以通过这个函数传递你想要的很多点,而不仅仅是 8 个

希望这对您有所帮助并享受您的工作

【讨论】:

  • 这只是为您的所有坐标定义一个公共 Rect,这里是我粘贴示例数组 Rect r = getRect(new int[]{10, 10, 20, 20, 30, 30}, new int[]{20, 100, 10, 110, 20, 100}); 的位置。然后从矩形得到底部、左侧、顶部和右侧。如我所见,您可以自己画画。
  • 我必须根据 8 个点裁剪图像,就像那个示例图像,我无法得到你,你能建议我如何解决我的问题
  • 好的,很抱歉逐行询问..在我的代码库中单击我正在放置裁剪代码...我必须在其中添加您发送的代码,不介意你能解释清楚
  • 我的意思是你拿了一个 rect 变量,为此你写了一个方法,你把代码应用到图像上
  • 在我的代码中,我也没有提到这 4 点,因为它默认了
猜你喜欢
  • 2023-03-12
  • 2013-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-02
  • 2021-12-03
  • 2017-05-18
  • 2021-07-24
相关资源
最近更新 更多