Comment agrandir / zoomer une partie de l'image

Je fais une application où l'utilisateur pourra cliquer sur une partie de l'image et obtenir une version agrandie dans le coin de WebView . J'ai réussi à créer une Paint qui ferait une version de zoom, mais elle affiche un mauvais emplacement, comme il y a un certain décalage.

Je sais que cette question a été posée à maintes reprises et a déjà été répondu, mais il semble que non ces solutions aient été aidées.

Voici le code que j'ai utilisé:

  @Override public boolean onTouchEvent(@NonNull MotionEvent event) { zoomPos = new PointF(); zoomPos.x = event.getX(); zoomPos.y = event.getY(); matrix = new Matrix(); mShader = new BitmapShader(MainActivity.mutableBitmap, TileMode.CLAMP, TileMode.CLAMP); mPaint = new Paint(); mPaint.setShader(mShader); outlinePaint = new Paint(Color.BLACK); outlinePaint.setStyle(Paint.Style.STROKE); int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_MOVE: zooming = true; this.invalidate(); break; case MotionEvent.ACTION_UP: Point1 = true; zooming = false; this.invalidate(); break; case MotionEvent.ACTION_CANCEL: zooming = false; this.invalidate(); break; default: break; } return true; } @Override protected void onDraw(@NonNull Canvas canvas) { super.onDraw(canvas); if (zooming) { matrix.reset(); matrix.postScale(2f, 2f, zoomPos.x, zoomPos.y); mPaint.getShader().setLocalMatrix(matrix); canvas.drawCircle(100, 100, 100, mPaint); } } 

Techniquement, il devrait dessiner un cercle dans le coin supérieur gauche et afficher l'image agrandie de la zone où mon doigt est, il dessine un cercle, mais encore, le zoom est décalé.

Le résultat final devrait ressembler à ceci:

Entrez la description de l'image ici

MainActivity.java

 public class MainActivity extends Activity { static ImageView takenPhoto; static PointF zoomPos; Paint shaderPaint; static BitmapShader mShader; BitmapShader shader; Bitmap bmp; static Bitmap mutableBitmap; static Matrix matrix; Canvas canvas; static Paint mPaint; static Paint Paint; static boolean zooming; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); File file = new File(Environment.getExternalStorageDirectory() + "/Pictures/boxes.jpg"); String fileString = file.getPath(); takenPhoto = (ZoomView) findViewById(R.id.imageView1); bmp = BitmapFactory.decodeFile(fileString); mutableBitmap = bmp.copy(Bitmap.Config.ARGB_8888, true); takenPhoto.setImageBitmap(mutableBitmap); matrix = new Matrix(); mShader = new BitmapShader(mutableBitmap, TileMode.CLAMP, TileMode.CLAMP); mPaint = new Paint(); mPaint.setShader(mShader); zoomPos = new PointF(); Paint = new Paint(Color.RED); } } 

ZoomView.java

 public class ZoomView extends ImageView { private PointF zoomPos; PointF fingerPos; private Paint paint = new Paint(Color.BLACK); boolean zooming; Matrix matrix; BitmapShader mShader; Paint mPaint; Paint outlinePaint; boolean Point1; public ZoomView(Context context) { super(context); } public ZoomView(Context context, AttributeSet attrs) { super(context, attrs); } public ZoomView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public boolean onTouchEvent(@NonNull MotionEvent event) { zoomPos = new PointF(); zoomPos.x = event.getX(); zoomPos.y = event.getY(); matrix = new Matrix(); mShader = new BitmapShader(MainActivity.mutableBitmap, TileMode.CLAMP, TileMode.CLAMP); mPaint = new Paint(); mPaint.setShader(mShader); outlinePaint = new Paint(Color.BLACK); outlinePaint.setStyle(Paint.Style.STROKE); int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_MOVE: zooming = true; this.invalidate(); break; case MotionEvent.ACTION_UP: Point1 = true; zooming = false; this.invalidate(); break; case MotionEvent.ACTION_CANCEL: zooming = false; this.invalidate(); break; default: break; } return true; } @Override protected void onDraw(@NonNull Canvas canvas) { super.onDraw(canvas); if (zooming) { matrix.reset(); matrix.postScale(2f, 2f, zoomPos.x, zoomPos.y); mPaint.getShader().setLocalMatrix(matrix); RectF src = new RectF(zoomPos.x-50, zoomPos.y-50, zoomPos.x+50, zoomPos.y+50); RectF dst = new RectF(0, 0, 100, 100); matrix.setRectToRect(src, dst, Matrix.ScaleToFit.CENTER); matrix.postScale(2f, 2f); mPaint.getShader().setLocalMatrix(matrix); canvas.drawCircle(100, 100, 100, mPaint); canvas.drawCircle(zoomPos.x, zoomPos.y, 100, mPaint); canvas.drawCircle(zoomPos.x-110, zoomPos.y-110, 10, outlinePaint); } if(Point1){ canvas.drawCircle(zoomPos.x, zoomPos.y, 10, paint); } } } 

MODIFIER:

Comme vous pouvez le voir, un nouveau code est bien meilleur, il y a encore un décalage – point noir – position du doigt.

Entrez la description de l'image ici

  • Android drawText y compris l'enveloppement de texte
  • Comment définir paint.setColor (R.color.white)
  • Dessiner 2 cercles sur un canevas
  • Fonds d'écran Android Live - OpenGL vs Canvas
  • Envelopper du texte long sur un Toile Android
  • Android: Dessin sur toile, manière de faire en bas à gauche correspondent (0,0)?
  • Android: comment créer un bouton sur Bitmap dynamiquement ou un bouton OVERLAYING?
  • Scratch the screen pour afficher une image dans Android
  • One Solution collect form web for “Comment agrandir / zoomer une partie de l'image”

    On dirait que le problème concerne la façon dont vous utilisez la matrix .

    Maintenant, vous utilisez l'image originale (1) en tant que shader qui est ensuite affiché à l'échelle autour d'un point de pivotement (2) , comme faire un zoom autour d'un point (3) – mais pas en centrant le point (4) ! (Par exemple, ouvrez Google Maps et agrandissez la carte avec votre souris – le point est zoomé autour du pivot mais le pivot n'est pas centré)

    Entrez la description de l'image ici

    Ce qui sera un moyen plus facile d'atteindre ce que vous voulez, c'est d'utiliser la méthode Rect to Rect . IE vous souhaitez prendre une petite zone de l'image originale (5) et la dessiner dans une zone plus grande (6) .

    Entrez la description de l'image ici

    Et voici un exemple de code:

     RectF src = new RectF(zoomPos.x-50, zoomPos.y-50, zoomPos.x+50, zoomPos.y+50); RectF dst = new RectF(0, 0, 200, 200); matrix.setRectToRect(src, dst, Matrix.ScaleToFit.CENTER); 

    Quelques points supplémentaires:

    • Essayez de ne pas créer un new objet dans l' onTouch – il est appelé plusieurs fois et ce n'est pas bon sur les performances . Au lieu de cela, créez une fois et réutilisez.
    • getAction() aura des problèmes lorsqu'il y a plus d'un doigt sur l'écran car il s'agit de l'ID d'action et de l'ID du pointeur. Utilisez plutôt getActionMasked () et getActionIndex () .
    • N'utilisez pas de valeurs codées (50/100 dans le code exemple) – ce sont des pixels et ne sont pas conscients de la densité de l'écran. Utilisez la taille à l'échelle comme dp .
    coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.