Android image view matrix scale + translate

后端 未结 4 1952
执笔经年
执笔经年 2020-11-28 04:52

I am trying to manually get an image inside an imageview centered and fitting the screen. I need to do it with a matrix (I will later dynamically change the matrix transform

相关标签:
4条回答
  • 2020-11-28 05:30

    Here is how I solved my problem using matrices (requested by joakime in the other answer):

    private void setImageTransformation(float tx, float ty, float scale) {
        savedMatrix.reset();
        savedMatrix.postTranslate(-imageWidth / 2f, -imageHeight / 2f);
        savedMatrix.postScale(scale, scale);
        savedMatrix.postTranslate(tx, ty);
        imageView.setImageMatrix(savedMatrix);
    }
    
    public void resetImageMatrix() {
        if (!isImageLoaded()) return;
    
        imageWidth = imageView.getDrawable().getIntrinsicWidth();
        imageHeight = imageView.getDrawable().getIntrinsicHeight();
    
        float scaleX = (float) displayWidth / (float) imageWidth;
        float scaleY = (float) displayHeight / (float) imageHeight;
        minScale = Math.min(scaleX, scaleY);
        maxScale = 2.5f * minScale;
    
        initialTranslation.set(
                  Math.max(0, 
                    minScale * imageWidth / 2f 
                    + 0.5f * (displayWidth - (minScale * imageWidth))), 
                  Math.max(0, 
                    minScale * imageHeight / 2f
                    + 0.5f * (displayHeight - (minScale * imageHeight))));
    
        currentScale = minScale;
        currentTranslation.set(initialTranslation);
        initialImageRect.set(0, 0, imageWidth, imageHeight);
    
        setImageTransformation(initialTranslation.x, initialTranslation.y, 
                    minScale);
    }
    

    I am cheating here a bit because the pinch is not really centered between the user fingers, which is acceptable in my case.

    0 讨论(0)
  • 2020-11-28 05:30

    Or using

        m.postScale(minScale, minScale); //keep aspect ratio
    
        float tx = (getWidth() - bitmap1.getWidth()* scale) * 0.5f ;
        float ty = (getHeight() - bitmap1.getHeight()* scale) * 0.5f ;
    
        matrix.postTranslate(tx, ty );
    

    where getWidth is the width of your imageView. Works perfectly for me

    0 讨论(0)
  • 2020-11-28 05:32

    There's a convenient method called Matrix.setRectToRect(RectF, RectF, ScaleToFit) to help you here.

    Matrix m = imageView.getImageMatrix();
    RectF drawableRect = new RectF(0, 0, imageWidth, imageHeight);
    RectF viewRect = new RectF(0, 0, imageView.getWidth(), imageView.getHeight());
    m.setRectToRect(drawableRect, viewRect, Matrix.ScaleToFit.CENTER);
    imageView.setImageMatrix(m);
    

    That should set the matrix m to have combo of scaling and translate values that is needed to show the drawable centered and fit within the ImageView widget.

    0 讨论(0)
  • 2020-11-28 05:37

    Hey I was having the same issue, and you were oh so close! It was an order of operations issue, at least for me. The following worked for me:

    tx = (width - imgWidth) * 0.5f * scale;
    
    0 讨论(0)
提交回复
热议问题