2012-10-18 6 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; 
     } 
    } 
} 

누군가가 유용 할 것입니다.