2013-02-25 143 views
1

我們正在經歷大約一週的以下問題: 我們正在繪製一幅圖像,我們希望能夠在用戶的屏幕上重新縮放和「移動」。 爲了達到這個目的,我們使用了ImageView和Matrix:它效果很好。使用ImageView和矩陣在圖像上繪製圖形

但是,現在我們正在尋找在背景圖像上繪製一些矩形。 這些矩形必須重新縮放並與背景圖片一起轉換......我們遇到的問題是,當我們創建形狀並使用以下代碼進行繪製時,它將繪製在圖像的左上角部分就像整個用戶的屏幕被解釋爲其真實維度的一部分一樣......?

我定製的ImageView

public class EnvironmentView extends ImageView { 
Matrix matrix; 

// We can be in one of these 3 states 
static final int NONE = 0; 
static final int DRAG = 1; 
static final int ZOOM = 2; 
int mode = NONE; 

// Remember some things for zooming 
PointF last = new PointF(); 
PointF start = new PointF(); 
float minScale = 1f; 
float maxScale = 3f; 
float[] m; 

int viewWidth, viewHeight; 
static final int CLICK = 3; 
float saveScale = 1f; 
protected float origWidth, origHeight; 
int oldMeasuredWidth, oldMeasuredHeight; 

public static boolean EDIT_RISKYZONE = false; 
static boolean SAVE = false; 
ScaleGestureDetector mScaleDetector; 

Context context; 

@Override 
protected void onDraw(Canvas canvas){ 
    super.onDraw(canvas); 

    Paint paint = new Paint(); 

    paint.setColor(Color.RED); 
    paint.setStrokeWidth(3); 
    paint.setAlpha(80); 

    float left = 0; 
    float top = 0; 
    float right = getWidth(); 
    float down = getHeight(); 
    RectF origRect = new RectF(left, top, right, down); 

    matrix.mapRect(origRect); 
    canvas.drawRect(origRect, paint); 



} 

public EnvironmentView(Context context) { 
    super(context); 
    sharedConstructing(context); 
} 

public EnvironmentView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    sharedConstructing(context); 
} 

private void sharedConstructing(Context context) { 
    super.setClickable(true); 
    this.context = context; 
    matrix = new Matrix(); 
    m = new float[9]; 
    setImageMatrix(matrix); 
    setScaleType(ScaleType.MATRIX); 
} 

public void setMaxZoom(float x) { 
    maxScale = x; 
} 

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
    viewWidth = MeasureSpec.getSize(widthMeasureSpec); 
    viewHeight = MeasureSpec.getSize(heightMeasureSpec); 

    // 
    // Rescales image on rotation 
    // 
    if (oldMeasuredHeight == viewWidth && oldMeasuredHeight == viewHeight 
      || viewWidth == 0 || viewHeight == 0) 
     return; 
    oldMeasuredHeight = viewHeight; 
    oldMeasuredWidth = viewWidth; 

    if (saveScale == 1) { 
     //Fit to screen. 
     float scale; 

     Drawable drawable = getDrawable(); 
     if (drawable == null || drawable.getIntrinsicWidth() == 0 || drawable.getIntrinsicHeight() == 0) 
      return; 
     int bmWidth = drawable.getIntrinsicWidth(); 
     int bmHeight = drawable.getIntrinsicHeight(); 

     Log.d("bmSize", "bmWidth: " + bmWidth + " bmHeight : " + bmHeight); 

     float scaleX = (float) viewWidth/(float) bmWidth; 
     float scaleY = (float) viewHeight/(float) bmHeight; 
     scale = Math.min(scaleX, scaleY); 
     matrix.setScale(scale, scale); 

     // Center the image 
     float redundantYSpace = (float) viewHeight - (scale * (float) bmHeight); 
     float redundantXSpace = (float) viewWidth - (scale * (float) bmWidth); 
     redundantYSpace /= (float) 2; 
     redundantXSpace /= (float) 2; 

     matrix.postTranslate(redundantXSpace, redundantYSpace); 

     origWidth = viewWidth - 2 * redundantXSpace; 
     origHeight = viewHeight - 2 * redundantYSpace; 
     setImageMatrix(matrix); 
    } 
} 
} 

屏幕輸出

下面是什麼在用戶的屏幕上顯示的屏幕截圖,他已經繪製了屏幕的中央矩形之後,他們應該是約3/4的屏幕寬度和高度。

謝謝您的幫助!

+0

你可以使用一個簡單的onDraw()方法替換上面的所有代碼:一個imageView,一個固定的矩形和一個演示該問題的矩陣? – 2013-02-25 09:10:41

+0

可能問題在於圖像和矩形從不同的角度開始,所以您可能需要兩個基本上應用了相同的操作但基本不同的基礎? – 2013-02-25 09:18:58

+0

嗯......我只是做了你說的,我更新了我的文章(包括代碼和屏幕截圖),以便你可以看到究竟是不是按預期工作(或...?)。 – Ark4ntes 2013-02-25 09:49:07

回答

1

圖像需要從原點開始(左上角--0,0)。矩形應該從屏幕的中心開始寬度的一半,高度的一半。

int x = (widthOfScreen - widthOfRect)/2; 
int y = (heightOfScreen - heightOfRect)/2; 

所以我認爲你需要另一個矩陣。首先轉換第二個矩陣,以便將矩形放置在屏幕的中心,然後將相同的操作應用於另一個矩陣。在應用任何其他矩陣操作(即將它們全部註釋掉)之前嘗試做到這一點,並看到它將矩形放置在正確的位置。那麼如果是對的,它應該縮放OK。

+0

它的工作原理!非常感謝你!現在,我可以在背景圖片上創建我的矩形,然後放大,縮小,翻譯整個東西......太棒了:)謝謝,真的!因爲我沒有足夠的聲望,所以我不能「回答」你的答案......但是,還有一件事:當我在代碼中放回縮放函數時,以及當我在縮放環境中工作時,我只需要創建矩形「轉換」(意味着縮放+翻譯)...我的意思是:如果我在縮放環境後繪製矩形,則不會在我期望的位置繪製矩形(正好在我的手指下) ... – Ark4ntes 2013-02-25 11:32:07

+0

是的,我的邏輯中可能存在錯誤,我描述的翻譯可能需要在最後而不是開始處完成,並且基於矩形的最終大小而不是開始處的大小。如果你不能把它整理成僅僅是最小的onDraw()而沒有任何其他方法,那麼任何人都可以將它粘貼到他們的Android應用程序的onDraw()中,並用它提出一個新的問題。 – 2013-02-25 12:07:34

+0

你好,如答案中給出的,我拿了另一個矩陣,並將另一個矩陣轉換爲x和y的位置。但是我的矩形顯示在右下方。 // inDraw 'newmatrix。setTranslate(x,y)' 'newmatrix.mapRect(origRect)' 其實我是新手,請指導我出錯的地方。 – Dory 2013-04-24 12:30:43