如何在Android中实现手绘图像裁剪?

2022-09-03 14:44:33

如何在.Imageview

使用以下代码,我能够绘制手绘路径,并能够裁剪图像,但我遇到了一些其他问题

现在我到目前为止尝试过什么

这是我的代码

使用画布裁剪图像的代码

public class SomeView extends View implements View.OnTouchListener {
    private Paint paint;

    int DIST = 2;
    boolean flgPathDraw = true;

    Point mfirstpoint = null;
    boolean bfirstpoint = false;

    Point mlastpoint = null;

    Bitmap bitmap;

    Context mContext;

    public SomeView(Context c, Bitmap bitmap) {
        super(c);

        mContext = c;
        this.bitmap = bitmap;

        setFocusable(true);
        setFocusableInTouchMode(true);

        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setStyle(Paint.Style.STROKE);
        paint.setPathEffect(new DashPathEffect(new float[]{10, 20}, 0));
        paint.setStrokeWidth(5);
        paint.setColor(Color.RED);
        paint.setStrokeJoin(Paint.Join.ROUND);
        paint.setStrokeCap(Paint.Cap.ROUND);

        this.setOnTouchListener(this);
        points = new ArrayList<Point>();

        bfirstpoint = false;
    }

    public SomeView(Context context, AttributeSet attrs) {
        super(context, attrs);

        mContext = context;
        setFocusable(true);
        setFocusableInTouchMode(true);

        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(5);
        paint.setColor(Color.RED);

        points = new ArrayList<Point>();
        bfirstpoint = false;

        this.setOnTouchListener(this);
    }

    public void onDraw(Canvas canvas) {

        /*Rect dest = new Rect(0, 0, getWidth(), getHeight());

        paint.setFilterBitmap(true);
        canvas.drawBitmap(bitmap, null, dest, paint);*/

        canvas.drawBitmap(bitmap, 0, 0, null);

        Path path = new Path();
        boolean first = true;

        for (int i = 0; i < points.size(); i += 2) {
            Point point = points.get(i);
            if (first) {
                first = false;
                path.moveTo(point.x, point.y);
            } else if (i < points.size() - 1) {
                Point next = points.get(i + 1);
                path.quadTo(point.x, point.y, next.x, next.y);
            } else {
                mlastpoint = points.get(i);
                path.lineTo(point.x, point.y);
            }
        }
        canvas.drawPath(path, paint);
    }

    public boolean onTouch(View view, MotionEvent event) {
        // if(event.getAction() != MotionEvent.ACTION_DOWN)
        // return super.onTouchEvent(event);

        Point point = new Point();
        point.x = (int) event.getX();
        point.y = (int) event.getY();

        if (flgPathDraw) {

            if (bfirstpoint) {

                if (comparepoint(mfirstpoint, point)) {
                    // points.add(point);
                    points.add(mfirstpoint);
                    flgPathDraw = false;
                    showcropdialog();
                } else {
                    points.add(point);
                }
            } else {
                points.add(point);
            }

            if (!(bfirstpoint)) {

                mfirstpoint = point;
                bfirstpoint = true;
            }
        }

        invalidate();
        Log.e("Hi  ==>", "Size: " + point.x + " " + point.y);

        if (event.getAction() == MotionEvent.ACTION_UP) {
            Log.d("Action up*****~~>>>>", "called");
            mlastpoint = point;
            if (flgPathDraw) {
                if (points.size() > 12) {
                    if (!comparepoint(mfirstpoint, mlastpoint)) {
                        flgPathDraw = false;
                        points.add(mfirstpoint);
                        showcropdialog();
                    }
                }
            }
        }

        return true;
    }

    private boolean comparepoint(Point first, Point current) {
        int left_range_x = (int) (current.x - 3);
        int left_range_y = (int) (current.y - 3);

        int right_range_x = (int) (current.x + 3);
        int right_range_y = (int) (current.y + 3);

        if ((left_range_x < first.x && first.x < right_range_x)
                && (left_range_y < first.y && first.y < right_range_y)) {
            if (points.size() < 10) {
                return false;
            } else {
                return true;
            }
        } else {
            return false;
        }

    }

    public void fillinPartofPath() {
        Point point = new Point();
        point.x = points.get(0).x;
        point.y = points.get(0).y;

        points.add(point);
        invalidate();
    }

    public void resetView() {
        points.clear();
        paint.setColor(Color.WHITE);
        paint.setStyle(Paint.Style.STROKE);

        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(5);
        paint.setColor(Color.RED);

        points = new ArrayList<Point>();
        bfirstpoint = false;

        flgPathDraw = true;
        invalidate();
    }

    private void showcropdialog() {
        DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Intent intent;
                switch (which) {
                    case DialogInterface.BUTTON_POSITIVE:
                        cropImage();
                        break;

                    case DialogInterface.BUTTON_NEGATIVE:
                        /*// No button clicked

                        intent = new Intent(mContext, DisplayCropActivity.class);
                        intent.putExtra("crop", false);
                        mContext.startActivity(intent);

                        bfirstpoint = false;*/
                        resetView();

                        break;
                }
            }
        };

        AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
        builder.setMessage("Do you Want to save Crop or Non-crop image?")
                .setPositiveButton("Crop", dialogClickListener)
                .setNegativeButton("Non-crop", dialogClickListener).show()
                .setCancelable(false);
    }
}

用于裁剪位图的代码

public void cropImage() {

    setContentView(R.layout.activity_picture_preview);

    imageView = findViewById(R.id.image);

    int widthOfscreen = 0;
    int heightOfScreen = 0;

    DisplayMetrics dm = new DisplayMetrics();
    try {
        getWindowManager().getDefaultDisplay().getMetrics(dm);
    } catch (Exception ex) {
    }
    widthOfscreen = dm.widthPixels;
    heightOfScreen = dm.heightPixels;

    Bitmap bitmap2 = mBitmap;

    Bitmap resultingImage = Bitmap.createBitmap(widthOfscreen,
            heightOfScreen, bitmap2.getConfig());

    Canvas canvas = new Canvas(resultingImage);

    Paint paint = new Paint();

    Path path = new Path();

    for (int i = 0; i < points.size(); i++) {

        path.lineTo(points.get(i).x, points.get(i).y);

    }

    canvas.drawPath(path, paint);

    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));

    canvas.drawBitmap(bitmap2, 0, 0, paint);

    imageView.setImageBitmap(resultingImage);

}

在这里,我使用上面的代码得到了什么结果

使用手指触摸裁剪图像

此图像显示裁剪图像后的结果

这是我的预期输出

请检查下面的屏幕截图以获取相同的内容

此图像显示使用手指触摸裁剪图像

此图像显示裁剪图像后的结果

我在上面的代码中面临的以下问题

  • 无法使用画布在全屏模式下设置位图
  • 如果我在画布中全屏设置位图,则图像正在拉伸
  • 如何将透明背景设置为裁剪的位图
  • 无法向裁剪后的图像添加边框
  • 图像裁剪的结果与预期不符

以下是我迄今为止尝试过的其他一些帖子

以上帖子都无助于实现我的例外输出

如果需要更多信息,请让我知道。提前致谢。您的努力将不胜感激。


答案 1

总的来说,你的代码看起来不错,但我有一些评论:

  • 无法使用画布在全屏模式下设置位图
  • 如果我在画布中全屏设置位图,则图像正在拉伸
    您选择的图像部分需要放置在较小的位图中,以便布局XML可以根据需要定位它。您正在创建全屏位图。有关详细信息,请参阅以下演示。

  • 如何将透明背景设置为裁剪的位图
    ,我不清楚问题是什么。

  • 无法向裁剪后的图像添加边框

  • 图像裁剪的结果与预期
    不符,请参阅下文。

这是一个使用您的代码的小型演示应用程序。您没有提供 MCVE,因此出于演示目的,我将以下内容放在一起。除了让应用程序正常运行之外,我认为唯一的变化是在 中绘制边框。边框宽度从用户绘制的切出路径开始,并向内延伸到切口。如果要在不丢失任何像素的情况下实际构建剪切,则需要扩展路径以容纳我任意设置为20像素的帧。MainActivity.java

我还必须创建使用的布局,因此您可能想查看这些布局。它们发布在下面。

以下是演示视频,其中包含要遵循的代码:

enter image description here

主要活动.java

public class MainActivity extends AppCompatActivity {
    private Bitmap mBitmap;
    private SomeView mSomeView;

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

        mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.dog);
        mSomeView = new SomeView(this, mBitmap);
        LinearLayout layout = findViewById(R.id.layout);
        LinearLayout.LayoutParams lp =
            new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                                          LinearLayout.LayoutParams.WRAP_CONTENT);
        layout.addView(mSomeView, lp);
    }

    public void cropImage() {
        setContentView(R.layout.activity_picture_preview);
        ImageView imageView = findViewById(R.id.image);

        Bitmap fullScreenBitmap =
            Bitmap.createBitmap(mSomeView.getWidth(), mSomeView.getHeight(), mBitmap.getConfig());

        Canvas canvas = new Canvas(fullScreenBitmap);

        Path path = new Path();
        List<Point> points = mSomeView.getPoints();
        for (int i = 0; i < points.size(); i++) {
            path.lineTo(points.get(i).x, points.get(i).y);
        }

        // Cut out the selected portion of the image...
        Paint paint = new Paint();
        canvas.drawPath(path, paint);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(mBitmap, 0, 0, paint);

        // Frame the cut out portion...
        paint.setColor(Color.WHITE);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(10f);
        canvas.drawPath(path, paint);

        // Create a bitmap with just the cropped area.
        Region region = new Region();
        Region clip = new Region(0, 0, fullScreenBitmap.getWidth(), fullScreenBitmap.getHeight());
        region.setPath(path, clip);
        Rect bounds = region.getBounds();
        Bitmap croppedBitmap =
            Bitmap.createBitmap(fullScreenBitmap, bounds.left, bounds.top,
                                bounds.width(), bounds.height());

        imageView.setImageBitmap(croppedBitmap);
    }
}

SomeView.java
我不认为这门课有任何实质性的变化。

public class SomeView extends View implements View.OnTouchListener {  
    private Paint paint;  
    private List<Point> points;  

    int DIST = 2;  
    boolean flgPathDraw = true;  

    Point mfirstpoint = null;  
    boolean bfirstpoint = false;  

    Point mlastpoint = null;  

    Bitmap bitmap;  

    Context mContext;  


        public SomeView(Context c, Bitmap bitmap) {  
            super(c);  

            mContext = c;  
            this.bitmap = bitmap;  

            setFocusable(true);  
            setFocusableInTouchMode(true);  

            paint = new Paint(Paint.ANTI_ALIAS_FLAG);  
            paint.setStyle(Paint.Style.STROKE);  
            paint.setPathEffect(new DashPathEffect(new float[]{10, 20}, 0));  
            paint.setStrokeWidth(5);  
            paint.setColor(Color.RED);  
            paint.setStrokeJoin(Paint.Join.ROUND);  
            paint.setStrokeCap(Paint.Cap.ROUND);  

            this.setOnTouchListener(this);  
            points = new ArrayList<Point>();  

            bfirstpoint = false;  
        }  

        public SomeView(Context context, AttributeSet attrs) {  
            super(context, attrs);  

            mContext = context;  
            setFocusable(true);  
            setFocusableInTouchMode(true);  

            paint = new Paint(Paint.ANTI_ALIAS_FLAG);  
            paint.setStyle(Paint.Style.STROKE);  
            paint.setStrokeWidth(5);  
            paint.setColor(Color.RED);  

            points = new ArrayList<Point>();  
            bfirstpoint = false;  

            this.setOnTouchListener(this);  
        }  

        public void onDraw(Canvas canvas) {  

            /*Rect dest = new Rect(0, 0, getWidth(), getHeight());  

     paint.setFilterBitmap(true); canvas.drawBitmap(bitmap, null, dest, paint);*/  
      canvas.drawBitmap(bitmap, 0, 0, null);  

            Path path = new Path();  
            boolean first = true;  

            for (int i = 0; i < points.size(); i += 2) {  
                Point point = points.get(i);  
                if (first) {  
                    first = false;  
                    path.moveTo(point.x, point.y);  
                } else if (i < points.size() - 1) {  
                    Point next = points.get(i + 1);  
                    path.quadTo(point.x, point.y, next.x, next.y);  
                } else {  
                    mlastpoint = points.get(i);  
                    path.lineTo(point.x, point.y);  
                }  
            }  
            canvas.drawPath(path, paint);  
        }  

        public boolean onTouch(View view, MotionEvent event) {  
            // if(event.getAction() != MotionEvent.ACTION_DOWN)  
     // return super.onTouchEvent(event);  
      Point point = new Point();  
            point.x = (int) event.getX();  
            point.y = (int) event.getY();  

            if (flgPathDraw) {  

                if (bfirstpoint) {  

                    if (comparepoint(mfirstpoint, point)) {  
                        // points.add(point);  
      points.add(mfirstpoint);  
                        flgPathDraw = false;  
                        showcropdialog();  
                    } else {  
                        points.add(point);  
                    }  
                } else {  
                    points.add(point);  
                }  

                if (!(bfirstpoint)) {  

                    mfirstpoint = point;  
                    bfirstpoint = true;  
                }  
            }  

            invalidate();  
            Log.e("Hi  ==>", "Size: " + point.x + " " + point.y);  

            if (event.getAction() == MotionEvent.ACTION_UP) {  
                Log.d("Action up*****~~>>>>", "called");  
                mlastpoint = point;  
                if (flgPathDraw) {  
                    if (points.size() > 12) {  
                        if (!comparepoint(mfirstpoint, mlastpoint)) {  
                            flgPathDraw = false;  
                            points.add(mfirstpoint);  
                            showcropdialog();  
                        }  
                    }  
                }  
            }  

            return true;  
        }  

        private boolean comparepoint(Point first, Point current) {  
            int left_range_x = (int) (current.x - 3);  
            int left_range_y = (int) (current.y - 3);  

            int right_range_x = (int) (current.x + 3);  
            int right_range_y = (int) (current.y + 3);  

            if ((left_range_x < first.x && first.x < right_range_x)  
                && (left_range_y < first.y && first.y < right_range_y)) {  
                if (points.size() < 10) {  
                    return false;  
                } else {  
                    return true;  
                }  
            } else {  
                return false;  
            }  

        }  

        public void fillinPartofPath() {  
            Point point = new Point();  
            point.x = points.get(0).x;  
            point.y = points.get(0).y;  

            points.add(point);  
            invalidate();  
        }  

        public void resetView() {  
            points.clear();  
            paint.setColor(Color.WHITE);  
            paint.setStyle(Paint.Style.STROKE);  

            paint = new Paint(Paint.ANTI_ALIAS_FLAG);  
            paint.setStyle(Paint.Style.STROKE);  
            paint.setStrokeWidth(5);  
            paint.setColor(Color.RED);  

            points = new ArrayList<Point>();  
            bfirstpoint = false;  

            flgPathDraw = true;  
            invalidate();  
        }  

        private void showcropdialog() {  
            DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {  
                @Override  
      public void onClick(DialogInterface dialog, int which) {  
                    Intent intent;  
                    switch (which) {  
                        case DialogInterface.BUTTON_POSITIVE:  
                            ((MainActivity) mContext).cropImage();  
                            break;  

                        case DialogInterface.BUTTON_NEGATIVE:  
                            /*// No button clicked  

     intent = new Intent(mContext, DisplayCropActivity.class); intent.putExtra("crop", false); mContext.startActivity(intent);  
     bfirstpoint = false;*/  resetView();  

                            break;  
                    }  
                }  
            };  

            AlertDialog.Builder builder = new AlertDialog.Builder(mContext);  
            builder.setMessage("Do you Want to save Crop or Non-crop image?")  
                .setPositiveButton("Crop", dialogClickListener)  
                .setNegativeButton("Non-crop", dialogClickListener).show()  
                .setCancelable(false);  
        }  

        public List<Point> getPoints() {  
            return points;  
        }  
    }

activity_main.xml

<LinearLayout 
  android:id="@+id/layout"  
  xmlns:tools="http://schemas.android.com/tools"  
  android:layout_width="match_parent"  
  android:layout_height="match_parent"  
  android:orientation="vertical"  
  tools:context=".MainActivity"/>

activity_picture_preview.xml

<android.support.constraint.ConstraintLayout x
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorPrimary">

    <ImageView
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:srcCompat="@drawable/dog" />
</android.support.constraint.ConstraintLayout> 

如果要创建具有 100px 边框的裁剪位图,请在 中使用以下代码:cropImage()

    // Create a bitmap with just the cropped area.
    Region region = new Region();
    Region clip = new Region(0, 0, fullScreenBitmap.getWidth(), fullScreenBitmap.getHeight());
    region.setPath(path, clip);
    Rect sourceBounds = region.getBounds();
    Rect destBounds =
        new Rect(CROPPED_MARGIN, CROPPED_MARGIN, sourceBounds.width() + CROPPED_MARGIN,
                 sourceBounds.height() + CROPPED_MARGIN);
    Bitmap croppedBitmap =
        Bitmap.createBitmap(sourceBounds.width() + CROPPED_MARGIN * 2,
                            sourceBounds.height() + CROPPED_MARGIN * 2, mBitmap.getConfig());
    canvas.setBitmap(croppedBitmap);
    canvas.drawBitmap(fullScreenBitmap, sourceBounds, destBounds, null);

    imageView.setImageBitmap(croppedBitmap);

    // Add as member variable.
    private static final int CROPPED_MARGIN = 100;

答案 2

我已经在我的项目中尝试了很多解决这个问题的方法,但是这个代码是有效的。在这里,我把我自己项目的代码放在这里。如果您在其中找到了解决方案,则可以使用它。

public class CropView extends View implements View.OnTouchListener {
public static final String INTENT_KEY_CROP = "crop";
public static final String CACHE_KEY = "bitmap";

public static List<Point> points;
boolean flgPathDraw = true;
boolean bFirstPoint = false;
private Point firstPoint = null;
private Point lastPoint = null;

private final Bitmap originalImageBitmap;
private int canvasWidth;
private int canvasHeight;
private Paint paint;
private Context context;
private static LruCache<String, Bitmap> mMemoryCache;
private final ImageCropListener imageCropListener;

public interface ImageCropListener {
    void onClickDialogPositiveButton();
    void onClickDialogNegativeButton();
}

public static Bitmap getBitmapFromMemCache() {
    return mMemoryCache.get(CACHE_KEY);
}


public CropView(Context c, Bitmap bm, ImageCropListener listener) {
    super(c);

    context = c;
    setFocusable(true);
    setFocusableInTouchMode(true);
    paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    paint.setStyle(Paint.Style.STROKE);
    paint.setPathEffect(new DashPathEffect(new float[] { 10, 20 }, 0));
    paint.setStrokeWidth(5);
    paint.setColor(Color.WHITE);

    this.setOnTouchListener(this);
    points = new ArrayList<>();

    bFirstPoint = false;
    this.originalImageBitmap = bm;
    this.imageCropListener = listener;

    final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
    final int cacheSize = maxMemory / 8;
    mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
        @Override
        protected int sizeOf(String key, Bitmap bitmap) {
            // The cache size will be measured in kilobytes rather than
            // number of items.
            return bitmap.getByteCount() / 1024;
        }
    };

 }

 public CropView(Context context, AttributeSet attrs, Bitmap bm, 
 ImageCropListener listener) {
    super(context, attrs);
    this.context = context;
    setFocusable(true);
    setFocusableInTouchMode(true);

    paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeWidth(2);
    paint.setColor(Color.WHITE);

    this.setOnTouchListener(this);
    points = new ArrayList<>();
    bFirstPoint = false;
    this.originalImageBitmap = bm;
    this.imageCropListener = listener;
}

public void addBitmapToMemoryCache(Bitmap bitmap) {
    if (getBitmapFromMemCache() == null) {
        mMemoryCache.put(CACHE_KEY, bitmap);
    }
}

private float calcBitmapScale(int canvasWidth, int canvasHeight, int bmpWidth, int bmpHeight) {

    float scale = (float)canvasWidth / (float)bmpWidth;
    float tmp = bmpHeight * scale;

    if (tmp < canvasHeight) {
        scale = (float)canvasHeight / (float)bmpHeight;
        return scale;
    }

    return scale;
}

public void onDraw(Canvas canvas) {
    canvasWidth = canvas.getWidth();
    canvasHeight = canvas.getHeight();

   /* int bmpWidth = this.originalImageBitmap.getWidth();
    int bmpHeight = this.originalImageBitmap.getHeight();


    float toCanvasScale = this.calcBitmapScale(canvasWidth, canvasHeight, bmpWidth, bmpHeight);


    float diffX = (bmpWidth * toCanvasScale - canvasWidth);
    float diffY = (bmpHeight * toCanvasScale - canvasHeight);


    float addX = (diffX / toCanvasScale) / 2;
    float addY = (diffY / toCanvasScale) / 2;


    Rect rSrc = new Rect((int)addX, (int)addY,
            (int)((canvasWidth / toCanvasScale) + addX), (int)((canvasHeight / 
    toCanvasScale) + addY));
    RectF rDest = new RectF(0, 0, canvasWidth, canvasHeight);
    */
    canvas.drawBitmap(originalImageBitmap, 0, 0, null);

    Path cropAreaPath = new Path();
    boolean isFirstPoint = true;

    for (int i = 0; i < points.size(); i += 2) {
        Point point = points.get(i);
        if (isFirstPoint) {
            isFirstPoint = false;
            // 最初の処理でPathのx,y座標をpointの座標に移動する
            cropAreaPath.moveTo(point.x, point.y);
        } else if (i < points.size() - 1) {
            Point next = points.get(i + 1);
            cropAreaPath.quadTo(point.x, point.y, next.x, next.y);
        } else {
            lastPoint = points.get(i);
            cropAreaPath.lineTo(point.x, point.y);
        }
    }
    canvas.drawPath(cropAreaPath, paint);
}

public boolean onTouch(View view, MotionEvent event) {
    Point point = new Point();
    point.x = (int) event.getX();
    point.y = (int) event.getY();

    if (flgPathDraw) {
        if (bFirstPoint) {
            if (comparePoint(firstPoint, point)) {
                // points.add(point);
                points.add(firstPoint);
                flgPathDraw = false;
                showCropDialog();
            } else {
                points.add(point);
            }
        } else {
            points.add(point);
        }

        if (!(bFirstPoint)) {

            firstPoint = point;
            bFirstPoint = true;
        }
    }

    invalidate();
    //Log.e("Hi  ==>", "Size: " + point.x + " " + point.y);

    if (event.getAction() == MotionEvent.ACTION_UP) {
        Log.d("Action up***>", "called");
        lastPoint = point;
        if (flgPathDraw) {
            if (points.size() > 12) {
                if (!comparePoint(firstPoint, lastPoint)) {
                    flgPathDraw = false;
                    points.add(firstPoint);
                    showCropDialog();
                }
            }
        }
    }

    return true;
}

private boolean comparePoint(Point first, Point current) {
    int left_range_x = (int) (current.x - 3);
    int left_range_y = (int) (current.y - 3);

    int right_range_x = (int) (current.x + 3);
    int right_range_y = (int) (current.y + 3);

    if ((left_range_x < first.x && first.x < right_range_x)
            && (left_range_y < first.y && first.y < right_range_y)) {
        if (points.size() < 10) {
            return false;
        } else {
            return true;
        }
    } else {
        return false;
    }

}

public void fillinPartofPath() {
    Point point = new Point();
    point.x = points.get(0).x;
    point.y = points.get(0).y;

    points.add(point);
    invalidate();
}

public void resetView() {
    points.clear();
    paint.setColor(Color.WHITE);
    paint.setStyle(Paint.Style.STROKE);
    flgPathDraw = true;
    invalidate();
}

private void showCropDialog() {
    final Bitmap croppedImage = cropImage(this.originalImageBitmap);
    DialogInterface.OnClickListener dialogClickListener = new 
    DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            switch (which) {
                case DialogInterface.BUTTON_POSITIVE:
                    addBitmapToMemoryCache(croppedImage);
                    imageCropListener.onClickDialogPositiveButton();
                    break;

                case DialogInterface.BUTTON_NEGATIVE:
                    bFirstPoint = false;
                    resetView();
                    imageCropListener.onClickDialogNegativeButton();
                    break;
            }
        }
    };

    AlertDialog.Builder builder = new AlertDialog.Builder(context);
    builder.setMessage("Do you Want to save Crop or Non-crop image?")
            .setPositiveButton("Crop", dialogClickListener)
            .setNegativeButton("Cancel", dialogClickListener).show()
            .setCancelable(false);
}

private Bitmap cropImage(Bitmap image) {
    Bitmap cropImage = Bitmap.createBitmap(canvasWidth, canvasHeight, 
    image.getConfig());
    Canvas canvas = new Canvas(cropImage);
    Paint paint = new Paint();
    paint.setAntiAlias(true);

    Path path = new Path();
    for (int i = 0; i < CropView.points.size(); i++) {
        path.lineTo(CropView.points.get(i).x, CropView.points.get(i).y);
    }
    canvas.drawPath(path, paint);
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
    canvas.drawBitmap(originalImageBitmap, 0, 0, paint);

    return cropImage;
}

class Point {
    public float dy;
    public float dx;
    float x, y;

    @Override
    public String toString(){
        return x + ", " + y;
    }
}
}

然后,您可以获得裁剪结果。就像,

Bitmap cropBitmap = CropView.getBitmapFromMemCache();
                cropBitmap = getBitmapWithTransparentBG(cropBitmap,Color.WHITE);
                Drawable d = new BitmapDrawable(getResources(),cropBitmap);

public Bitmap getBitmapWithTransparentBG(Bitmap srcBitmap, int bgColor) {
    Bitmap result = srcBitmap.copy(Bitmap.Config.ARGB_8888, true);
    int nWidth = result.getWidth();
    int nHeight = result.getHeight();
    for (int y = 0; y < nHeight; ++y)
        for (int x = 0; x < nWidth; ++x) {
            int nPixelColor = result.getPixel(x, y);
            if (nPixelColor == bgColor)
                result.setPixel(x, y, Color.TRANSPARENT);
        }
    return result;
}

我认为,此代码将非常适合您的问题解决方案。谢谢


推荐