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

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

4

1 回答 1

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

希望有人会发现这很有用。

于 2012-11-19T09:25:21.140 回答