Android ImageView Image Scaling Effect

I am currently trying to develop an application in which the user will be able to enlarge the image. But instead of increasing the zoom, I need to make a lens effect, which means that when the user clicks on the image and holds his finger on it for some time, a circle with an enlarged image appears directly above it. It looks like this: enter image description here

I looked at the answers and links below and got it like this, but it doesn't work:

public class MainActivity extends Activity implements OnTouchListener{ ImageView takenPhoto; static PointF zoomPos; Paint shaderPaint; BitmapShader mShader; BitmapShader shader; Bitmap bmp; Bitmap mutableBitmap; static Matrix matrix; Canvas canvas; static Paint mPaint; 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 = (ImageView) 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); takenPhoto.setOnTouchListener(this); } private static class ZoomView extends View { public ZoomView(Context context) { super(context); } 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; } @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); } } } @Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub return true; } } 
+4
source share
3 answers

A few days later, trying to solve this problem, thanks to those answers above and other sources, I was able to write a full working code.

To save time for all of you guys, here it is. Copy-paste and edit it a little to fit your goals.

First of all, you need to edit the main action - we will use a custom ImageView

  <your.package.name.ZoomView android:id="@+id/imageView1" android:layout_width="wrap_content" android:layout_height="wrap_content"/> 

Then we will edit MainActivity.java. Use ZoomView as ImageView

 ImageView takenPhoto; takenPhoto = (ZoomView) findViewById(R.id.imageView1); 

After that create the ZoomView class and paste this:

 public class ZoomView extends ImageView { PointF zoomPos; boolean zooming; Matrix matrix; BitmapShader mShader; Paint mPaint; 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); int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_MOVE: zooming = true; this.invalidate(); break; case MotionEvent.ACTION_UP: 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(zoomPos.x, zoomPos.y, 100, mPaint); } } } 

You should now have a working magnifying effect.

+1
source

Well, I would prefer:

1- You must use the touch listener on the image.
2- You should have a canvas (where you draw an enlarged bitmap)

If you also want you to be able to implement onDragListener to update the circular scaled image when you drag your finger across the image.

I would say take a look at this link: Android - How does a circular zoom / zoom part of an image?

+2
source

One possible solution is to capture a Canvas object from the view where your image is displayed. You will need to update the Canvas using various motion events .

As part of handling these events, use functionality to display only part of the image . The method listed is part of the Canvas object. Regarding the options:

 Bitmap bitmap //The image to zoom on Rectangle src //A rectangle defining the portion of the image to zoom in on Rectangle dest //A rectangle defining where in the View to draw the zoomed portion of your image. //If the size of the rectangles is mismatched, it will zoom. Paint paint //The paint object necessary for drawing. 

Leave a comment if you have any questions. Happy coding!

0
source

All Articles