Proper Conversions for Image Scaling

I am writing an Android application (although I think this is a general question) and I need to display a large image (in ImageView) that can be scrolled and scaled. I managed to get the scroll to work, capturing touch events and performing matrix translations, and now I'm working on scaling.

If I just apply a scale transformation to the image, it scales at the origin, which is the top left corner of the screen. I would like to zoom in on the center of the screen. From what I read, this means that I need a transformation to make the origin in the center of the screen. I think something like the following is required: suppose the center of the screen is (5, 5) for simplicity ...

-Translate by (-5, -5)
-Scale by the zoom factor
-Translate by (+5, +5)*zoomfactor

Unfortunately, that doesn't seem to work - the zoom seems to go anywhere, BUT the center ... can anyone help me here?

EDIT: this is the code that now works

  Matrix zoommatrix = new Matrix(); float[] centerpoint = {targetimageview.getWidth()/2.0f, targetimageview.getHeight()/2.0f}; zoommatrix.postScale(zoomfactor, zoomfactor, centerpoint[0], centerpoint[1]); zoommatrix.preConcat(targetimageview.getImageMatrix()); targetimageview.setImageMatrix(zoommatrix); targetimageview.invalidate(); 
+4
source share
1 answer

Check ImageViewTouchBase in the source code of the Android application for the camera; his "zoomTo" method does this:

 protected void zoomTo(float scale, float centerX, float centerY) { if (scale > mMaxZoom) { scale = mMaxZoom; } float oldScale = getScale(); float deltaScale = scale / oldScale; mSuppMatrix.postScale(deltaScale, deltaScale, centerX, centerY); setImageMatrix(getImageViewMatrix()); center(true, true); } 

This center method is likely to be very interesting to you:

  protected void center(boolean horizontal, boolean vertical) { if (mBitmapDisplayed.getBitmap() == null) { return; } Matrix m = getImageViewMatrix(); RectF rect = new RectF(0, 0, mBitmapDisplayed.getBitmap().getWidth(), mBitmapDisplayed.getBitmap().getHeight()); m.mapRect(rect); float height = rect.height(); float width = rect.width(); float deltaX = 0, deltaY = 0; if (vertical) { int viewHeight = getHeight(); if (height < viewHeight) { deltaY = (viewHeight - height) / 2 - rect.top; } else if (rect.top > 0) { deltaY = -rect.top; } else if (rect.bottom < viewHeight) { deltaY = getHeight() - rect.bottom; } } if (horizontal) { int viewWidth = getWidth(); if (width < viewWidth) { deltaX = (viewWidth - width) / 2 - rect.left; } else if (rect.left > 0) { deltaX = -rect.left; } else if (rect.right < viewWidth) { deltaX = viewWidth - rect.right; } } postTranslate(deltaX, deltaY); setImageMatrix(getImageViewMatrix()); } 
+3
source

Source: https://habr.com/ru/post/1299751/


All Articles