其他分享
首页 > 其他分享> > Android缩放,拖动,在ImageView上绘制

Android缩放,拖动,在ImageView上绘制

作者:互联网

我在绘制和缩放ImageView时遇到问题.请帮帮我..

当我画一些东西,然后拖动或缩放图像时 – 图形保留在它的位置,就像你在屏幕截图上看到的那样.我需要简单地绘制图片,并有可能缩放和拖动这张图片.

enter image description here
enter image description here

我有一个自定义ImageView与此操作:

 public class DrawingView extends ImageView {
// onTouch
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;

private Path mPath;

private boolean zoomEnabled = true;

private Paint drawPaint, canvasPaint;
//initial color
private int paintColor = 0xFF660000;
//canvas
private Canvas drawCanvas;
//canvas bitmap
private Bitmap canvasBitmap;

private static final int INVALID_POINTER_ID = -1;

private float mPosX;
private float mPosY;

private float mLastTouchX;
private float mLastTouchY;
private float mLastGestureX;
private float mLastGestureY;
private int mActivePointerId = INVALID_POINTER_ID;

private ScaleGestureDetector mScaleDetector;
private float mScaleFactor = 1.f;

public DrawingView(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
    mScaleDetector = new ScaleGestureDetector(getContext(), new ScaleListener());
    setupDrawing();
}

public DrawingView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
    setupDrawing();
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {

    super.onSizeChanged(w, h, oldw, oldh);
    canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
    drawCanvas = new Canvas(canvasBitmap);

}

@Override
public boolean onTouchEvent(MotionEvent ev) {
    final int action = ev.getAction();
    mScaleDetector.onTouchEvent(ev);
    if (zoomEnabled) {
        switch (action & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN: {
                if (!mScaleDetector.isInProgress()) {
                    final float x = ev.getX();
                    final float y = ev.getY();

                    mLastTouchX = x;
                    mLastTouchY = y;
                    mActivePointerId = ev.getPointerId(0);
                }
                break;
            }
            case MotionEvent.ACTION_POINTER_1_DOWN: {
                if (mScaleDetector.isInProgress()) {
                    final float gx = mScaleDetector.getFocusX();
                    final float gy = mScaleDetector.getFocusY();
                    mLastGestureX = gx;
                    mLastGestureY = gy;
                }
                break;
            }
            case MotionEvent.ACTION_MOVE: {

                // Only move if the ScaleGestureDetector isn't processing a gesture.
                if (!mScaleDetector.isInProgress()) {
                    final int pointerIndex = ev.findPointerIndex(mActivePointerId);
                    final float x = ev.getX(pointerIndex);
                    final float y = ev.getY(pointerIndex);

                    final float dx = x - mLastTouchX;
                    final float dy = y - mLastTouchY;

                    mPosX += dx;
                    mPosY += dy;

                    invalidate();

                    mLastTouchX = x;
                    mLastTouchY = y;
                } else {
                    final float gx = mScaleDetector.getFocusX();
                    final float gy = mScaleDetector.getFocusY();

                    final float gdx = gx - mLastGestureX;
                    final float gdy = gy - mLastGestureY;

                    mPosX += gdx;
                    mPosY += gdy;

                    invalidate();

                    mLastGestureX = gx;
                    mLastGestureY = gy;
                }

                break;
            }
            case MotionEvent.ACTION_UP: {
                mActivePointerId = INVALID_POINTER_ID;
                break;
            }
            case MotionEvent.ACTION_CANCEL: {
                mActivePointerId = INVALID_POINTER_ID;
                break;
            }
            case MotionEvent.ACTION_POINTER_UP: {

                final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK)
                        >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
                final int pointerId = ev.getPointerId(pointerIndex);
                if (pointerId == mActivePointerId) {
                    // This was our active pointer going up. Choose a new
                    // active pointer and adjust accordingly.
                    final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
                    mLastTouchX = ev.getX(newPointerIndex);
                    mLastTouchY = ev.getY(newPointerIndex);
                    mActivePointerId = ev.getPointerId(newPointerIndex);
                } else {
                    final int tempPointerIndex = ev.findPointerIndex(mActivePointerId);
                    mLastTouchX = ev.getX(tempPointerIndex);
                    mLastTouchY = ev.getY(tempPointerIndex);
                }
                break;
            }
        }

        return true;
    } else {
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                touchStart(ev.getX(), ev.getY());
                invalidate();
                break;
            case MotionEvent.ACTION_MOVE:
                touchMove(ev.getX(), ev.getY());
                invalidate();
                break;
            case MotionEvent.ACTION_UP:
                touchUp();
                invalidate();
                break;
        }
        return true;
    }
}

@Override
public void onDraw(Canvas canvas) {
    canvas.save();
    canvas.translate(mPosX, mPosY);

    if (mScaleDetector.isInProgress()) {
        canvas.scale(mScaleFactor, mScaleFactor, mScaleDetector.getFocusX(), mScaleDetector.getFocusY());
    }
    else{
        canvas.scale(mScaleFactor, mScaleFactor, mLastGestureX, mLastGestureY);
    }
    super.onDraw(canvas);
    canvas.restore();

    canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
    canvas.drawPath(mPath, drawPaint);
}

private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
    @Override
    public boolean onScale(ScaleGestureDetector detector) {
        mScaleFactor *= detector.getScaleFactor();

        // Don't let the object get too small or too large.
        mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 10.0f));

        invalidate();
        return true;
    }
}

private void setupDrawing(){
    mPath = new Path();
    drawPaint = new Paint();
    drawPaint.setColor(paintColor);
    drawPaint.setAntiAlias(true);
    drawPaint.setStrokeWidth(20);
    drawPaint.setStyle(Paint.Style.STROKE);
    drawPaint.setStrokeJoin(Paint.Join.ROUND);
    drawPaint.setStrokeCap(Paint.Cap.ROUND);
    canvasPaint = new Paint(Paint.DITHER_FLAG);
}

public void setZoomEnabled(boolean b){
    this.zoomEnabled = b;
}

private void touchStart(float x, float y) {
    // mPath.reset();
    mPath.moveTo(x, y);
    mX = x;
    mY = y;
}

private void touchMove(float x, float y) {
    float dx = Math.abs(x - mX);
    float dy = Math.abs(y - mY);
    if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
        mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
        mX = x;
        mY = y;
    }
}

private void touchUp() {
    mPath.lineTo(mX, mY);
    // commit the path to our offscreen
    drawCanvas.drawPath(mPath, drawPaint);
    // kill this so we don't double draw
    mPath.reset();
}

和活动:

 public class DrawActivity extends Activity{

DrawingView image;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.draw);

    final Paint paint = new Paint();
    paint.setColor(MyApp.getColorRes(R.color.primary));
    paint.setStrokeWidth(10);

    image = (DrawingView) findViewById(R.id.image);

    Bitmap bmp = BitmapFactory.decodeByteArray(
            getIntent().getByteArrayExtra("byteArray"), 0, getIntent().getByteArrayExtra("byteArray").length);


    Bitmap alteredBmp = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig());
    final Canvas canvas = new Canvas(alteredBmp);
    canvas.drawBitmap(bmp, 0, 0, paint);
    image.setImageBitmap(alteredBmp);

    ImageButton paintBtn = (ImageButton) findViewById(R.id.paint_btn);
    paintBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View button) {
            button.setSelected(!button.isSelected());
            image.setZoomEnabled(!button.isSelected());
        }
    });

}

解决方法:

在onDraw()中,您将使用View的画布直接绘制路径.而是通过drawCanvas将路径绘制到canvasBitmap.完成此操作后,canvasBitmap将包含图像和绘图.现在,当您缩放或移动时,两者都将适当更改,因为它们现在位于单个位图中.

而不是这个:

canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
canvas.drawPath(mPath, drawPaint);

做这样的事情:

drawCanvas.drawPath(mPath, drawPaint);
canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);

标签:android,android-imageview,android-canvas,android-bitmap
来源: https://codeday.me/bug/20190623/1271460.html