2012-10-18 97 views
1

我想繪製一幅圖像(作爲家庭圖片即另一幅圖像(作爲一個框架))。移動背景圖像,同時保持正面圖像靜止在畫布上

我正在使用ImageView來處理這個問題。我可以拖動我的背景圖片,但視圖沒有再次繪製正面圖像。

這是我加載兩張圖片的代碼。 mFrontImage是'框架',mBackImage是我們拖動的'背景'。 這些代碼行沒有問題。

// Create a new bitmap scaled from original bitmap 
mFrontImage = Bitmap.createBitmap(bmpTemp, 0, 0, fw, fh, fmatrix, true); 

mCanvas = new Canvas(mFrontImage); 
mPaint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.DST_OVER)); 
mCanvas.drawBitmap(mFrontImage, 0, 0, mPaint); 
mCanvas.drawBitmap(mBackImage, 0, 0, mPaint); 

mImageV = (ImageView) this.findViewById(R.id.image_view); 
mImageV.setImageBitmap(mFrontImage); 
mImageV.setOnTouchListener(this); 

而這些代碼來處理觸摸運動:

case MotionEvent.ACTION_DOWN: 
downx = event.getX(); 
downy = event.getY(); 
_moving = true; 
break; 

case MotionEvent.ACTION_MOVE: 
if (_moving) 
{ 
    dx = event.getX() - downx; 
    dy = event.getY() - downy; 
    downx = event.getX(); 
    downy = event.getY(); 
    x += dx; 
    y += dy; 

    mCanvas.drawColor(Color.TRANSPARENT, Mode.CLEAR); 
    mCanvas.drawBitmap(mFrontImage, 0, 0, mPaint); 
    mCanvas.drawBitmap(mBackImage, x, y, mPaint); 
    mImageEdit.invalidate(); 
} 
break; 

case MotionEvent.ACTION_UP: 
_moving = false; 
break; 

drawColor將擦除畫布,然後drawBitmap(mBackImage〜)但不drawBitmap(mFrontImage〜)

我想要實現的是將mFrontImage繪製在0,0和mBackImage的新位置x,y上。

回答

0

我想除了創建新的類實現SurfaceView之外別無他法。我確實嘗試並取得成功。這是我想要嘗試類似方式的示例代碼。

此代碼由許多來源通過互聯網和我自己的實施組合而成。您可以將兩個圖像加載到視圖,然後調整大小/移動背景圖像。我曾嘗試旋轉,但仍未完成。

class MyCanvasView extends SurfaceView implements SurfaceHolder.Callback { 
    private DrawingThread _thread; 
    private Bitmap _frontbmp; 
    private Bitmap _backbmp; 
    private Matrix _matrix; 
    float x, y, downx, downy, oldx, oldy; 
    float dx, dy, bw, bh; 
    boolean _moving = false; 
    ScaleGestureDetector sgdetector; 
    float scalefactor = 1.0f; 
    float oldscalefactor = 1.0f; 

    public MyCanvasView(Context context) { 
     super(context); 
     x = oldx = 0; 
     y = oldy = 0; 
     getHolder().addCallback(this); 
     _thread = new DrawingThread(getHolder(), this); 
     setFocusable(true); 
    } 

    public void initView(Bitmap front, Bitmap back){ 
     _matrix = new Matrix(); 
     sgdetector = new ScaleGestureDetector(getContext(), new ScaleListener()); 
     _frontbmp = front; 
     _backbmp = back; 
     bw = _backbmp.getWidth(); 
     bh = _backbmp.getHeight(); 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     synchronized (_thread.getSurfaceHolder()) { 
      int action = event.getAction(); 
      sgdetector.onTouchEvent(event); 
      switch (action & MotionEvent.ACTION_MASK) 
      { 
       case MotionEvent.ACTION_DOWN: 
        downx = event.getX(); 
        downy = event.getY(); 
        if((downx > oldx && downx < (oldx + bw)) && (downy > oldy && downy < (oldy + bh))) 
        { 
         _moving = true; 
        } 
        break; 
       case MotionEvent.ACTION_MOVE: 
        if (_moving && !sgdetector.isInProgress()) 
        { 
         dx = event.getX() - downx; 
         dy = event.getY() - downy; 
         downx = event.getX(); 
         downy = event.getY(); 
         oldx = x; 
         oldy = y; 
         x += dx; 
         y += dy; 
        } 
        break; 
       case MotionEvent.ACTION_UP: 
        _moving = false; 
        oldx = x; 
        oldy = y; 
        break; 
       case MotionEvent.ACTION_CANCEL: 
        break; 
       case MotionEvent.ACTION_POINTER_DOWN: 
        _moving = false; 
        break; 
       case MotionEvent.ACTION_POINTER_UP: 
        break; 
       default: 
        break; 
      } 
      return true; 
     } 
    } 

    @Override 
    public void onDraw(Canvas canvas) { 
     if (_backbmp != null && _frontbmp != null){ 
      canvas.drawColor(Color.WHITE); 
      _matrix.postTranslate(x - oldx, y - oldy); 
      _matrix.postScale(scalefactor/oldscalefactor, scalefactor/oldscalefactor, x + bw/2, y + bh/2); 
      canvas.drawBitmap(_backbmp, _matrix, null); 
      oldscalefactor = scalefactor; 
      canvas.drawBitmap(_frontbmp, 0, 0, null); 
     } 

    } 

    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 

    } 

    public void surfaceCreated(SurfaceHolder holder) { 
     _thread.setRunning(true); 
     _thread.start(); 
    } 

    public void surfaceDestroyed(SurfaceHolder holder) { 
     // we have to tell thread to shut down & wait for it to finish, or else 
     // it might touch the Surface after we return and explode 
     boolean retry = true; 
     _thread.setRunning(false); 
     while (retry) { 
      try { 
       _thread.join(); 
       retry = false; 
      } catch (InterruptedException e) { 
       // we will try it again and again... 
      } 
     } 
    } 

    class DrawingThread extends Thread { 
     private SurfaceHolder _surfaceHolder; 
     private MyCanvasView _panel; 
     private boolean _run = false; 

     public DrawingThread(SurfaceHolder surfaceHolder, MyCanvasView panel) { 
      _surfaceHolder = surfaceHolder; 
      _panel = panel; 
     } 

     public void setRunning(boolean run) { 
      _run = run; 
     } 

     public SurfaceHolder getSurfaceHolder() { 
      return _surfaceHolder; 
     } 

     @Override 
     public void run() { 
      Canvas c; 
      while (_run) { 
       c = null; 
       try { 
        c = _surfaceHolder.lockCanvas(null); 
        synchronized (_surfaceHolder) { 
         _panel.onDraw(c); 
        } 
       } finally { 
        if (c != null) { 
         _surfaceHolder.unlockCanvasAndPost(c); 
        } 
       } 
      } 
     } 
    } 

    class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { 
     @Override 
     public boolean onScale(ScaleGestureDetector detector) { 
      oldx = x; 
      oldy = y; 
      scalefactor *= detector.getScaleFactor(); 
      // Don't let the object get too small or too large. 
      scalefactor = Math.max(0.1f, Math.min(scalefactor, 5.0f)); 
      return true; 
     } 
    } 
} 

希望有人會發現這有用。