Эффект масштабирования изображения Android ImageView

В настоящее время я пытаюсь разработать приложение, где пользователь сможет увеличивать изображение. Но вместо увеличения зума мне нужно сделать эффект линзы, а это значит, что когда пользователь нажимает на изображение и держит палец на нем в течение некоторого времени, прямо над ним появляется круг с увеличенным изображением. Это выглядит так: Введите описание изображения здесь

Я посмотрел ответы и ссылки, приведенные ниже, и получил это так, но он не работает:

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

Ну, я бы предпочел:

1- Вы должны использовать сенсорный прослушиватель на изображении
2- У вас должен быть холст (где вы рисуете увеличенное растровое изображение)

Если вы также хотите, чтобы вы могли реализовать onDragListener для обновления кругового масштабированного изображения, когда вы перетаскиваете палец по изображению.

Я бы сказал, взгляните на эту ссылку: Android – Как круговое масштабирование / увеличение части изображения?

Спустя несколько дней, пытаясь решить эту проблему, я, благодаря ответам выше и другим источникам, смог написать полный рабочий код.

Чтобы сэкономить время для всех вас, ребята, вот оно. Скопируйте и вставьте немного, чтобы соответствовать вашим целям.

Прежде всего вам нужно отредактировать свою основную деятельность – мы собираемся использовать пользовательский ImageView

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

Затем мы отредактируем MainActivity.java. Используйте ZoomView так же, как ImageView

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

После этого создайте класс ZoomView и вставьте его:

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

Теперь у вас должен быть рабочий увеличивающий эффект.

Одним из возможных решений является захват объекта Canvas из представления, где отображается ваше изображение. Вам нужно будет обновить Canvas, используя различные события движения .

В рамках обработки этих событий используйте функциональные возможности для рисования только части изображения . Перечисленный метод является частью объекта Canvas. Что касается параметров:

 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. 

Оставьте комментарий, если у вас есть какие-либо вопросы. Счастливое кодирование!