web-dev-qa-db-fra.com

Comment implémenter un recadrage à main levée dans Android?

Comment puis-je mettre en œuvre un recadrage à main levée sur Imageview.

En utilisant le code ci-dessous, je suis capable de tracer un chemin à main levée et de pouvoir rogner une image, mais je suis confronté à d'autres problèmes. 

Maintenant ce que j'ai essayé jusqu'à présent

Voici mon code

code pour le recadrage de l'image à l'aide de la toile

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

Code de recadrage bitmap

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

}

Voici ce que je reçois résultat en utilisant le code ci-dessus

Recadrage d'une image avec Finger Touch

Cette image montre le résultat après le recadrage de l'image

Ceci est ma sortie attendue 

S'il vous plaît vérifier ci-dessous capture pour le même

Cette image montre une image de rognage avec Finger Touch

Cette image montre le résultat après le recadrage de l'image

Les problèmes ci-dessous auxquels je suis confronté dans le code ci-dessus

  • Impossible de définir le bitmap en plein écran avec canvas
  • Si je mets en mode plein écran bitmap en plein écran que l'image s'étire
  • Comment définir un fond transparent sur un bitmap recadré
  • Impossible d'ajouter une bordure à une image recadrée
  • Le résultat du recadrage de l'image n'est pas comme prévu 

Voici un autre post que j'ai essayé jusqu'à présent

aucun des articles ci-dessus ne m'aide à atteindre mon rendement excepté 

Si besoin de plus d'informations s'il vous plaît faites le moi savoir. Merci d'avance. Vos efforts seront appréciés.

11
Goku

En général, votre code a l'air correct, mais j'ai quelques commentaires:

  • Impossible de définir le bitmap en plein écran avec canvas
  • Si je mets le bitmap en plein écran dans le canevas que l'image s'étire
    La partie de l'image que vous sélectionnez doit être placée dans un bitmap plus petit pour que le XML de disposition puisse la positionner comme vous le souhaitez. Vous créez une image bitmap en plein écran. Voir la démo suivante pour plus de détails.

  • Comment définir un fond transparent sur un bitmap recadré
    Je ne sais pas quel est le problème. 

  • Impossible d'ajouter une bordure à une image recadrée

  • Le résultat du recadrage de l'image n'est pas comme prévu
    Voir ci-dessous.

Voici une petite application de démonstration utilisant votre code. Vous n'avez pas fourni de MCVE , j'ai donc regroupé les éléments suivants à des fins de démonstration. Autre que le fonctionnement de l'application, je pense que le seul changement consiste à tracer la bordure dans MainActivity.Java. La largeur de la bordure commence au niveau du tracé de découpe dessiné par l'utilisateur et atteint l'intérieur de la découpe. Si vous souhaitez réellement encadrer la découpe sans perdre de pixels, vous devrez alors développer le chemin afin de l'adapter au cadre que j'ai arbitrairement défini sur 20 pixels.

Je devais aussi créer les mises en page utilisées, alors vous voudrez peut-être les regarder. Ils sont affichés ci-dessous.

Voici la vidéo de démonstration avec le code à suivre:

 enter image description here

MainActivity.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
Je ne pense pas qu'il y ait eu de changements importants dans cette classe.

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> 

Si vous souhaitez créer un bitmap recadré avec une bordure de 100 pixels, utilisez le code suivant dans 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
Cheticamp

J'ai essayé beaucoup de solution à ce problème dans mon projet, mais ce code fonctionne . Ici, j'ai mis le code de mon propre projet ici Vous pouvez l'utiliser si vous y avez trouvé la solution.

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

Ensuite, vous pouvez obtenir un résultat de culture .. comme,

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

Je pense, ce code sera parfait pour votre solution de problème .. Merci

1
Krishna Vyas

Les liens que vous avez postés sont assez anciens. Pourquoi ne songez-vous pas à ajouter une bibliothèque ?

0
Sundus Bokhari