java - 如何将 Canvas 绘图转换为图像然后在屏幕上拖动它?

标签 java android

我试图在 Canvas 上绘图,然后单击将其更改为位图图像,然后我想让它可拖动。我可以成功地在 Canvas 上画画 但是如何将此绘图转换为图像然后使其可拖动?我不介意是否可以在不转换为图像的情况下拖动绘图。有人可以帮忙吗。

public class MainActivity extends AppCompatActivity implements ColorPickerDialog.OnColorChangedListener {

    protected DrawView canvasView;
    private ImageButton blackCircle;
    private Button pens,select;
    private Paint mPaint;
    Bitmap viewCapture = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mPaint = new Paint();

        canvasView = (DrawView) findViewById(R.id.canvas_view);//The drawing mechanism
        colorChanged(mPaint.getColor());

        blackCircle = (ImageButton) findViewById(R.id.black_circle);           
        blackCircle.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                canvasView.setPathColor(Color.BLACK));
                blackCircle.setPressed(true);
            }
        });

        select = (Button) findViewById(R.id.ic_select);
        select.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {

                canvasView.setVisibility(View.VISIBLE);
                canvasView.setPathColor(0);
                //Drag the drawn image
                setContentView(R.layout.activity_main);
                relativeLayout = (RelativeLayout) findViewById(R.id.main);
                drawingView = new DrawingView(MainActivity.this);
                relativeLayout.addView(drawingView);

                //Create a bitmap image of current drawing
                canvasView.setDrawingCacheEnabled(true);
                viewCapture = Bitmap.createBitmap(canvasView.getDrawingCache());
                canvasView.setDrawingCacheEnabled(false);
            }
        });

    }// End of Create();

    private void clearCanvas(View v) {
        canvasView.clear();
    }       

@Override
public void colorChanged(int color) {
    mPaint.setColor(color);
    canvasView.setPathColor(mPaint.getColor());
}


/**************   OnTouch ***************/

class DrawingView extends View{
    float x,y;

    public DrawingView(Context context){
        super(context);
        viewCapture = BitmapFactory.decodeResource(context.getResources(), R.id.main);
    }

    public boolean onTouchEvent(MotionEvent event){
        switch(event.getAction()){
            case MotionEvent.ACTION_DOWN:
            break;
            case MotionEvent.ACTION_MOVE:
                x =(int)event.getX();
                y =(int)event.getY();
                invalidate();
            break;
            case MotionEvent.ACTION_UP:
                x =(int)event.getX();
                y =(int)event.getY();
                invalidate();
            break;
        }
        return true;
    }

    @Override
    public void onDraw(Canvas canvas) {
        Paint paint = new Paint();
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(Color.CYAN);
        canvas.drawBitmap(viewCapture, x, y, paint); 
    }
  }
}//End of Class


public class DrawView extends View {

private Paint drawPaint, canvasPaint;
private Canvas drawCanvas;
private Bitmap canvasBitmap;
private SparseArray<Path> paths;

public DrawView(Context context) {
    super(context);
    setupDrawing();
}

public DrawView(Context context, AttributeSet attrs) {
    super(context, attrs);
    setupDrawing();
}

public DrawView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    setupDrawing();
}

private void setupDrawing() {
    paths = new SparseArray<>();
    drawPaint = new Paint();
    drawPaint.setColor(Color.BLACK);
    drawPaint.setAntiAlias(true);
    drawPaint.setStrokeWidth(9);
    drawPaint.setStyle(Paint.Style.STROKE);
    drawPaint.setStrokeJoin(Paint.Join.ROUND);
    drawPaint.setStrokeCap(Paint.Cap.ROUND);
    canvasPaint = new Paint(Paint.DITHER_FLAG);
}

@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
protected void onDraw(Canvas canvas) {
    canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
    for (int i=0; i<paths.size(); i++) {
        canvas.drawPath(paths.valueAt(i), drawPaint);
    }
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    int index = event.getActionIndex();
    int id = event.getPointerId(index);

    Path path;
    switch (event.getActionMasked()) {
        case MotionEvent.ACTION_DOWN:
        case MotionEvent.ACTION_POINTER_DOWN:
            path = new Path();
            path.moveTo(event.getX(index), event.getY(index));
            paths.put(id, path);
            break;

        case MotionEvent.ACTION_MOVE:
            for (int i=0; i<event.getPointerCount(); i++) {
                id = event.getPointerId(i);
                path = paths.get(id);
                if (path != null) path.lineTo(event.getX(i), event.getY(i));
            }
            break;

        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_POINTER_UP:
            path = paths.get(id);
            if (path != null) {
                drawCanvas.drawPath(path, drawPaint);
                paths.remove(id);
            }
            break;
        default:
            return false;
    }
    invalidate();
    return true;
}

public void setPathColor(int color) {
    drawPaint.setColor(color);
}

public void clear() {
    canvasBitmap.eraseColor(Color.TRANSPARENT);
    paths.clear();
    invalidate();
    System.gc();
 }
}

最佳答案

对于接下来的步骤,我假设您想让用户拖动他们刚刚使用 DrawView 创建的图片。因此,我将介绍另一个 View,它可以显示位图并设置其位置和尺寸,与 DrawView 完全相同。 (实现这一点的最佳方法取决于您使用的 ViewGroup 的类型)

从 Canvas 创建位图,如 converting a canvas into bitmap image in android 所示

使用setBackground(Drawable) 将位图设置为新View 的背景, 根据需要切换两个 View 的可见性。

要使新的 View 可拖动,请使用 View.OnTouchListener 并根据 MotionEvent 更改位置

另一种选择:只需拖动 DrawView,方法是使用标志指示用户是否可以拖动它或在其上绘图。您已经覆盖了 onTouchEvent(),现在首先检查标志,如果它设置为“拖动”,则评估两个 MOVE 之间的增量并相应地调整位置。

关于java - 如何将 Canvas 绘图转换为图像然后在屏幕上拖动它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51791143/

相关文章:

java - 空指针异常是否会导致 android 应用程序的性能?

java - 无法排除小于当前日期的日期

java - 使用计时器刷新 JLabel 中的图像

android - react 原生 : ViewManager for tag could not be found

android - GPS 和网络的标准

java - Gradle 错误 'Unable to resolve dependency' 找不到 'com.applovin:applovin-sdk'

java - 使用 Sax 解析大型 XML 文件

java - 如何确定哪个接口(interface)属于每个网络目标 - Java?

java - 将 TextView 设置为可见时崩溃

java - findViewById(R.id.searchView) 导致java空指针异常