Android - Comment faire un zoom circulaire / agrandissement d'une partie de l'image?

je suis en train de permettre à l'utilisateur de toucher l'image et puis fondamentalement un cirular loupe montrera qui permettra à l'utilisateur de mieux sélectionner une certaine zone sur l'image. Lorsque l'utilisateur libère le toucher, la partie agrandie disparaîtra. Ceci est utilisé sur plusieurs applications d'édition de photos et j'essaie d'implémenter ma propre version de celui-ci. Le code que j'ai ci-dessous amplifie une partie circulaire de l'imageview mais ne supprime pas ou ne supprime pas le zoom une fois que je relâche mon doigt. Je actuellement, positionnez un bitmap sur une toile en utilisant canvas = new Canvas(bitMap); et ensuite positionnez l'imageview en utilisant takenPhoto.setImageBitmap(bitMap); Je ne suis pas sûr que je vais le faire de la bonne façon. Le code onTouch est le suivant:

zoomPos = new PointF(0,0);
        takenPhoto.setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                 int action = event.getAction(); 
                    switch (action) { 
                        case MotionEvent.ACTION_DOWN: 
                            zoomPos.x = event.getX();
                            zoomPos.y = event.getY();
                            matrix.reset();
                            matrix.postScale(2f, 2f, zoomPos.x, zoomPos.y);
                            shader.setLocalMatrix(matrix);
                            canvas.drawCircle(zoomPos.x, zoomPos.y, 20, shaderPaint);
                            takenPhoto.invalidate();
                            break; 
                        case MotionEvent.ACTION_MOVE: 
                            zoomPos.x = event.getX();
                            zoomPos.y = event.getY();
                            matrix.reset();
                            matrix.postScale(2f, 2f, zoomPos.x, zoomPos.y);
                            canvas.drawCircle(zoomPos.x, zoomPos.y, 20, shaderPaint);
                            takenPhoto.invalidate();
                            break; 
                        case MotionEvent.ACTION_UP:   
                            //clear zoom here?

                            break; 
                        case MotionEvent.ACTION_CANCEL: 
                            break; 
                        default: 
                            break; 
            }
                    return true; 
            } 
            });
20
demandé sur IZI_Shadow_IZI 2012-12-13 20:45:19

4 réponses

en adaptant votre code, j'ai réussi à faire fonctionner l'approche suivante.

dans la fonction onTouch, définissez un point global pour déterminer où l'Utilisateur a touché, et définissez un booléen pour indiquer si le zoom est actuellement actif ou non:

@Override
public boolean onTouch(View view, MotionEvent event) {

    int action = event.getAction(); 

    zoomPos.x = event.getX();
    zoomPos.y = event.getY();

    switch (action) { 
    case MotionEvent.ACTION_DOWN:
    case MotionEvent.ACTION_MOVE:
        zooming = true;
        this.invalidate();
        break; 
    case MotionEvent.ACTION_UP:   
    case MotionEvent.ACTION_CANCEL:
        zooming = false;
        this.invalidate();
        break; 

    default: 
        break; 
    }

    return true; 
}

ensuite, dans la méthode onDraw, vous utilisez votre code pour dessiner la portion agrandie:

@Override
protected void onDraw(Canvas canvas) {

    super.onDraw(canvas);

    if (zooming) {
        matrix.reset();
        matrix.postScale(2f, 2f, zoomPos.x, zoomPos.y);
        mPaint.getShader().setLocalMatrix(matrix);

        canvas.drawCircle(zoomPos.x, zoomPos.y, 100, mPaint);
    }
}

notez que pour le shader, j'ai utilisé un shader bitmap comme décrit ici , qui a été créé avec:

mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image);
mShader = new BitmapShader(mBitmap, TileMode.CLAMP, TileMode.CLAMP);

mPaint = new Paint();
mPaint.setShader(mShader);
18
répondu qzikl 2017-05-23 12:02:38

la meilleure façon de revenir en arrière sera de recharger l'image à partir du fichier source. Ou encore, gardez la variable de matrice originale de copie avant les transformations commencées, pendant MotionEvent.ACTION_UP chargez la matrice originale.

6
répondu blaffie 2012-12-20 11:01:12

vous pouvez l'implémenter en utilisant un imageview personnalisé ,Créer un CodesforMagnifierImageView de classe.java dans votre forfait. Vous pouvez voir le code pour la classe respective à Codesformifier.java et utilisez simplement le code suivant dans votre fichier de mise en page à la place pour l'imageview

<com.yourpackage.CodesforMagnifierImageView
     android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:src="@drawable/your image" />
0
répondu Ramees 2017-04-17 05:19:49

certaines personnes ont demandé une position de loupe fixe, je l'ai expérimenté et j'ai trouvé la solution:

// bitmapWidth is the width of bitmap used for BitmapShader
// bitmapHeight is the height of bitmap used for BitmapShader
// canvasWidth is the width of canvas where the zoom touch events are tracked (usually has the same image as shader but can be different size)
// canvasHeight is the height of canvas where the zoom touch events are tracked
// touchPoint is the point on the canvas which area should be shown in zoom circle
// fixedZoomPoint is the center of the zoom circle (different from touch point)
// ZOOM_SCALE is the zooming ratio (e.g.: 2f)
// ZOOM_RADIUS is the radius of the zoom circle

override fun onDraw(canvas: Canvas) {
    super.onDraw(canvas)
    if (zooming) {
        val widthRatio = bitmapWidth / canvasWidth // This can be omitted if 1.0
        val heightRatio = bitmapHeight / canvasHeight // This can be omitted if 1.0
        matrix.reset()
        matrix.postScale(ZOOM_SCALE, ZOOM_SCALE, touchPoint.x * widthRatio, touchPoint.y * heightRatio)
        matrix.postTranslate(fixedZoomPoint.x - touchPoint.x * widthRatio, fixedZoomPoint.y - touchPoint.y * heightRatio)
        paint.getShader().setLocalMatrix(matrix)
        drawCircle(fixedZoomPoint.x, fixedZoomPoint.y, ZOOM_RADIUS, paint)
    }
}
0
répondu Mate Herber 2018-07-19 09:05:44