移动背景图像,同时保持前面的图像静止在画布上

时间:2012-10-18 03:51:06

标签: android touch android-canvas

我想在另一幅图像(作为一个帧)内绘制一幅图像(如家庭图片所示)。

我正在使用ImageView来处理这个问题。我可以拖动我的背景图像,但视图没有再次绘制正面图像。

这是我加载两张图片的代码。 mFrontImage是'frame',mBackImage是我们将拖动的'background'。 这些代码行没有问题。

// 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~)

我想要实现的是在0,0处绘制mFrontImage,在新位置x,y处绘制mBackImage。

1 个答案:

答案 0 :(得分:0)

我认为除了创建新的类工具SurfaceView之外别无他法。我确实尝试过成功。这是我想要尝试类似方式的示例代码。

此代码通过Internet和我自己的实现从许多来源中合并而来。您可以将两个图像加载到视图中,然后调整大小/移动背景图像。我确实试过旋转,但还没完成它。

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;
        }
    }
}

希望有人会觉得这很有用。