首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android ImageView 獲取圖片實際顯示區域與尺寸

     編輯:程式設計綜合問答

需求場景

需要獲取 ImageView 中圖片**實際繪製後的矩形區域**(含縮放、平移、旋轉後的位置與大小),而非 ImageView 本身的佈局邊界。

核心解決方案:使用 Matrix.mapRect()


public class MatrixImageView extends ImageView {
    private RectF mSrcRect = new RectF();    // 原始圖片區域
    private RectF mDstRect = new RectF();    // 變換後區域
    
    @Override
    public void setImageMatrix(Matrix matrix) {
        super.setImageMatrix(matrix);
        
        // 1. 獲取原始圖片邊界
        Drawable drawable = getDrawable();
        if (drawable != null) {
            mSrcRect.set(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
        } else {
            mSrcRect.set(0, 0, getWidth(), getHeight());
        }
        
        // 2. 使用當前 Matrix 映射得到實際顯示區域
        Matrix currentMatrix = getImageMatrix();
        currentMatrix.mapRect(mDstRect, mSrcRect);
        
        // mDstRect 現在包含:左、上、右、下座標(相對 ImageView 左上角)
        // 寬度:mDstRect.width(),高度:mDstRect.height()
    }
    
    // 取得實際顯示區域
    public RectF getDisplayRect() {
        return new RectF(mDstRect);
    }
    
    // 取得實際顯示寬高
    public float getDisplayWidth() { return mDstRect.width(); }
    public float getDisplayHeight() { return mDstRect.height(); }
}

關鍵 API 解析

方法說明
getImageMatrix()取得 ImageView 當前的變換矩陣(含 scaleType、setScale、setRotation 等產生的變換)
Matrix.mapRect(dst, src)將 src 矩形套用矩陣變換,結果存入 dst。支援縮放、旋轉、平移、傾斜等複合變換
Drawable.getIntrinsicWidth/Height()取得圖片原始像素寬高(未縮放)

完整範例:雙指縮放後獲取實際區域


public class ZoomableImageView extends ImageView implements ScaleGestureDetector.OnScaleGestureListener {
    private ScaleGestureDetector scaleDetector;
    private Matrix matrix = new Matrix();
    private float scaleFactor = 1.0f;
    private RectF displayRect = new RectF();
    
    public ZoomableImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setScaleType(ScaleType.MATRIX); // 必須用 MATRIX 類型
        scaleDetector = new ScaleGestureDetector(getContext(), this);
    }
    
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        scaleDetector.onTouchEvent(event);
        return true;
    }
    
    @Override
    public boolean onScale(ScaleGestureDetector detector) {
        scaleFactor *= detector.getScaleFactor();
        scaleFactor = Math.max(0.5f, Math.min(scaleFactor, 5.0f));
        
        matrix.setScale(scaleFactor, scaleFactor, 
            detector.getFocusX(), detector.getFocusY());
        setImageMatrix(matrix);
        updateDisplayRect();
        return true;
    }
    
    @Override public boolean onScaleBegin(ScaleGestureDetector d) { return true; }
    @Override public void onScaleEnd(ScaleGestureDetector d) {}
    
    private void updateDisplayRect() {
        Drawable d = getDrawable();
        if (d == null) return;
        
        RectF src = new RectF(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
        matrix.mapRect(displayRect, src);
        
        // 現在可以用 displayRect 做邊界檢測、裁剪、標註等
        Log.d(TAG, "顯示區域: " + displayRect.toShortString());
    }
    
    // 取得實際顯示區域供外部使用
    public RectF getActualDisplayRect() {
        return new RectF(displayRect);
    }
}

常見應用場景

場景用途
圖片裁剪獲取可見區域對應原圖座標,執行裁剪
標註/標記將螢幕觸控座標轉換為圖片座標
區域辨識僅處理可見區域像素,節省運算
動畫過渡共用元素轉場需精確起始/結束矩形
列印/匯出按實際顯示比例匯出高解析度圖片

座標系轉換輔助方法


// 螢幕座標 → ImageView 區域座標
public PointF screenToImageView(float screenX, float screenY) {
    int[] location = new int[2];
    getLocationOnScreen(location);
    return new PointF(screenX - location[0], screenY - location[1]);
}

// ImageView 區域座標 → 原圖座標(需 Matrix 可逆)
public PointF imageViewToSource(float viewX, float viewY) {
    Matrix inverse = new Matrix();
    if (getImageMatrix().invert(inverse)) {
        float[] pts = {viewX, viewY};
        inverse.mapPoints(pts);
        return new PointF(pts[0], pts[1]);
    }
    return null;
}

// 原圖座標 → ImageView 區域座標
public PointF sourceToImageView(float srcX, float srcY) {
    float[] pts = {srcX, srcY};
    getImageMatrix().mapPoints(pts);
    return new PointF(pts[0], pts[1]);
}

總結

使用 getImageMatrix().mapRect(dstRect, srcRect) 即可獲得 ImageView 中圖片**實際繪製後的區域與尺寸**。關鍵點:setScaleType(ScaleType.MATRIX)、以原圖邊界為 srcRect、套用 getImageMatrix() 變換。此法支援任意複合變換(縮放、旋轉、平移、傾斜),是圖片編輯、裁剪、標註等功能的基礎。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved