当前位置: 首页 > 知识库问答 >
问题:

Android画布的位图撤消和重做

孟彦
2023-03-14

我在画布上的撤消和重做操作有问题。我注意到,如果在Ondraw()方法中不使用canvas.drawbitmap,下面的代码可以工作,但是我需要绘制到位图,这样我就可以保存画布图像和加载图像。好心帮帮我。下面是我的代码。

import java.util.ArrayList;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Cap;
import android.graphics.Paint.Join;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.PorterDuff.Mode;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import com.akinslove.drawingapp.activities.DrawingCanvasActivity;

public class DrawView extends View {

    // for bitmap
    private Bitmap mainBitmap;
    private Canvas mainCanvas;
    private Paint mainbitmapPaint;

    // for canvas
    private Path currentPath;
    private Paint currentpathPaint;


    private ArrayList<Path> paths = new ArrayList<Path>();
    private ArrayList<Path> undonePaths = new ArrayList<Path>(); 

    public DrawView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initialiseMyComponents();
    }

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

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

    private void initialiseMyComponents() {
        currentPath = new Path();

        currentpathPaint = new Paint();
        currentpathPaint.setColor(Color.BLACK);
        currentpathPaint.setStrokeWidth(10);
        currentpathPaint.setStyle(Style.STROKE);
        currentpathPaint.setStrokeJoin(Join.ROUND);
        currentpathPaint.setStrokeCap(Cap.ROUND);
        currentpathPaint.setAntiAlias(true);

        mainbitmapPaint = new Paint();
    }

    @Override
    protected void onDraw(Canvas canvas) {

        for (Path p : paths){
            canvas.drawPath(p, currentpathPaint);
        }
        canvas.drawPath(currentPath, currentpathPaint);

            **//I wish to use the below line of code
            canvas.drawBitmap(mainBitmap, 0, 0, mainbitmapPaint);**
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        if (mainBitmap == null) {
            mainBitmap = Bitmap.createBitmap(w, h, Config.ARGB_8888);
            mainCanvas = new Canvas(mainBitmap);
            mainCanvas.drawColor(Color.WHITE);
        }
    }

    float lastX;
    float lastY;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getAction();
        float x = event.getX();
        float y = event.getY();

        switch (action) {
        case MotionEvent.ACTION_DOWN:
            undonePaths.clear();


            DrawingCanvasActivity.IMAGEDRAWN = true;
            currentPath.moveTo(x, y);
            lastX = x;
            lastY = y;
            invalidate();
            break;
        case MotionEvent.ACTION_MOVE:
            currentPath.quadTo(lastX, lastY, (lastX + x) / 2, (lastY + y) / 2);
            mainCanvas.drawPath(currentPath, currentpathPaint);
            lastX = x;
            lastY = y;
            invalidate();
            break;
        case MotionEvent.ACTION_UP:
            currentPath.lineTo(x, y);
            mainCanvas.drawPath(currentPath, currentpathPaint);

                    // kill this so we don't double draw
                    paths.add(currentPath);
                    currentPath = new Path(); 

            currentPath.rewind();
            invalidate();
            break;
        }

        return true;
    }



    // method to get bitmap
    public Bitmap getMainBitmap() {
        return mainBitmap;
    }

    // method to set bitmap
    public void setMainBitmap(Bitmap mpt) {
        mainBitmap = mpt;
        mainCanvas = new Canvas(mainBitmap);
        postInvalidate();

    }

    public void onClickUndo () { 

        if (paths.size()>0) 
        { 
           undonePaths.add(paths.remove(paths.size()-1));
           invalidate();
         }
    }

    public void onClickRedo (){

        if (undonePaths.size()>0) 
        { 
            paths.add(undonePaths.remove(undonePaths.size()-1)); 
            invalidate();
        } 
    }
}

共有1个答案

朱浩大
2023-03-14

我刚刚发现case motionevent.action_up:case motionevent.action_move:中的maincanvas.drawpath(currentPath,currentpathpatain);行不应该在那里。它似乎将路径重新绘制到位图和画布上。不确定我是否说对了android术语。

 类似资料:
  • 我有一个加载了位图的ImageView。当用户触摸位图时,我使用画布在位图上的触摸位置绘制一个圆。现在,我需要撤消绘制的圆。在任何地方,我都能找到一些片段来撤销绘制的路径,而不是直接撤销一个圆。有人有办法撤消先前绘制的圆吗?

  • Git提供了多种修复你开发过程中的错误的方法. 方法的选择取决于你的情况: 包含有错误的文件是否提交了(commited); 如果你把它已经提交了, 那么你是否把有错误的提交已与其它人共享这也很重要. 修复未提交文件中的错误(重置) 如果你现在的工作目录(work tree)里搞的一团乱麻, 但是你现在还没有把它们提交; 你可以通过下面的命令, 让工作目录回到上次提交时的状态(last commi

  • 我正在运行Ubuntu 16.04。在Android Studio上,当我试图在模拟器中运行我的应用程序时,我得到以下错误: 致命的例外:主要过程:项目名称在这里,PID: 2528java.lang.运行时间例外:画布:试图绘制太大(216090000bytes)位图。在android.view.DisplayListCanvas.throw如果不能绘制(DisplayListCanvas.ja

  • 问题内容: 如果我有画布,则可以在其上绘制如下的位图: 然后缩放位图: 我想获得比例尺后位图的位置。如果小数位数前的位置是(0,0),小数位数后的位置有一个偏移量,那么我需要该偏移量。如何获取? 谢谢你,很抱歉这个简单的问题,新手在这里… 问题答案: 好吧,让我们尝试为此制定最佳的公式 对于objectNewY也是一样。位图的新宽度和高度当然将是旧大小和比例的倍数。

  • 我试图使用矩阵旋转位图。然后我试着把它画在画布上。但它就这么消失了! 下面是我的代码: } 我已经删除了缩放画布和事件监听器等的函数。使代码小而易读。 我周期性地调用setDirection方法,但是在它被调用之后,“userImage”drawable就消失了。有人能告诉我这里出了什么问题吗。。 谢谢

  • 我正在使用而不是将背景、边框和/或背景色应用到页面的某个区域(主要是因为需要页面来构建,而不需要。因为我的内容可能会持续几页)。问题是,如果坐标(x=0,y=0)意味着左下角,则图像的位置不会像预期的那样。我还想将画布定位到一个固定的位置,但是似乎不起作用。请参阅附上的原始图像和要定位在{x,y,width,height}={100f,100f,200f,200f}的图像,该图像应该在页面的底部(