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

画布-在画布保存为图像后,用橡皮擦在画布上绘制黑线

龙亮
2023-03-14

在画布上画画是非常好的。即使橡皮擦也能工作得很好。问题是当画布保存为图像时,它画的是黑线,而不是橡皮擦。

为了更好地理解,我添加了屏幕、镜头和代码。

1.在擦除图的同时-

erase(){
      this.ctx.globalCompositeOperation = 'destination-out';
    } 

handleMove(ev){

  // let ctx = this.canvasElement.getContext('2d');
  let currentX = ev.touches[0].pageX - this.offsetX;
  let currentY = ev.touches[0].pageY - this.offsetY;

  this.ctx.beginPath();
  this.ctx.lineJoin = "round";
  this.ctx.moveTo(this.lastX, this.lastY);
  this.ctx.lineTo(currentX, currentY);
  this.ctx.closePath();
  this.ctx.strokeStyle = this.currentColour;
  this.ctx.lineWidth = this.brushSize;
  this.ctx.stroke();      


  this.undoList.push({
    x_start: currentX,
    y_start: currentY,
    x_end: this.lastX,
    y_end: this.lastY,
    color: this.currentColour,
    size: this.brushSize,
    mode: this.ctx.globalCompositeOperation
  });

  this.lastX = currentX;
  this.lastY = currentY;
  
}

this.ctx.clearRect(0, 0, this.canvasElement.width, this.canvasElement.height);
    setTimeout(() => {
      
      // this.drawImg(this.newImg);
       for(let i=0; i<this.textAreasList.length; i++){
         let txt = this.textAreasList[i];
         this.ctx.font = this.textAreasList[i].bold + ' ' + this.textAreasList[i].italic + ' ' + this.textAreasList[i].fontSize + ' ' + 'Comic Sans MS';
         this.ctx.fillStyle = this.textAreasList[i].color;  
         if(this.textAreasList[i].left=="" || this.textAreasList[i].left==undefined) {
           this.textAreasList[i].left = 50;
         }
         if(this.textAreasList[i].top=="" || this.textAreasList[i].top==undefined) {
          this.textAreasList[i].top = 50;
        }
         this.ctx.fillText(this.textAreasList[i].value, this.textAreasList[i].left, this.textAreasList[i].top);
       }

       this.redrawCanvas(this.undoUseList);
       let imgPath = this.canvasElement.toDataURL('image/png');
       let message= "";
       this.base64ToGallery.base64ToGallery(imgPath).then(
         res => message = "Image saved to gallery!",
         err => message = "Something went wrong!!"
       );
       this.spinner.hide();
       let toast = this.toastCtrl.create({
         message: message,
         duration: 3000,
         position: 'bottom',
         cssClass: 'changeToast'
       });
       this.navCtrl.push(HomePage);
     }, 5000);
  }



redrawCanvas(arr){
      // this.ctx.globalCompositeOperation = 'source-over';
      for(let i=0; i<arr.length; i++){
        for(let j=0; j< arr[i].length; j++){
          let ctx = this.canvasElement.getContext('2d');
          ctx.globalCompositeOperation = arr[i][j].mode;
          console.log('x start', arr[i][j].x_start);
          console.log('y start', arr[i][j].y_start);
          console.log('x end', arr[i][j].x_end);
          console.log('y end', arr[i][j].y_end);
          ctx.beginPath();
          ctx.lineJoin = "round";
          ctx.moveTo(arr[i][j].x_start, arr[i][j].y_start);
          ctx.lineTo(arr[i][j].x_end, arr[i][j].y_end);
          ctx.closePath();
          ctx.strokeStyle = arr[i][j].color;
          ctx.lineWidth = arr[i][j].size;
          ctx.stroke();
        }
        
      }
      
    }

**b. Output -** 

我不明白为什么橡皮移动被替换为黑色,而保存画布作为一个图像。

共有1个答案

朱昊乾
2023-03-14

最后我解决了这个问题。我做了以下改动。

redrawCanvas(arr){
      // this.ctx.globalCompositeOperation = 'source-over';
      for(let i=0; i<arr.length; i++){
        for(let j=0; j< arr[i].length; j++){
          let ctx = this.canvasElement.getContext('2d');
          // ctx.globalCompositeOperation = arr[i][j].mode;

          if(arr[i][j].mode== "destination-out"){
            // ctx.globalCompositeOperation = "destionation-out";
            // ctx.strokeStyle = "rgba(0,0,0,0.2)";
            let cImg = new Image();
            cImg.src = this.selectedImage;
            let pattern = ctx.createPattern(cImg, "no-repeat");
            ctx.strokeStyle = pattern;
          }else{
            ctx.strokeStyle = arr[i][j].color;
          }
          console.log('x start', arr[i][j].x_start);
          console.log('y start', arr[i][j].y_start);
          console.log('x end', arr[i][j].x_end);
          console.log('y end', arr[i][j].y_end);
          ctx.beginPath();
          ctx.lineJoin = "round";
          ctx.moveTo(arr[i][j].x_start, arr[i][j].y_start);
          ctx.lineTo(arr[i][j].x_end, arr[i][j].y_end);
          ctx.closePath();
          ctx.lineWidth = arr[i][j].size;
          ctx.stroke();
        }

      }

    }

正如你所看到的,我增加了一个检查是刷子还是橡皮擦。对于橡皮擦,我正在检查它是否是目的地输出

如果是橡皮擦,我正在创建新的图像,使strokestyle

所以你可以说我做了以下改变。

if(arr[i][j].mode== "destination-out"){
            // ctx.globalCompositeOperation = "destionation-out";
            // ctx.strokeStyle = "rgba(0,0,0,0.2)";
            let cImg = new Image();
            cImg.src = this.selectedImage;
            let pattern = ctx.createPattern(cImg, "no-repeat");
            ctx.strokeStyle = pattern;
          }else{
            ctx.strokeStyle = arr[i][j].color;
          }
 类似资料:
  • 我已经在谷歌上搜索了这个问题,并提出了各种解决方案。 但是,没有一个对我有效。 我在一个应用程序中有一个绘图画布。 画布的背景被设置为活动中的png图像,该活动使用自定义视图(drawView); 在DrawingView类(drawview是实例)中,我将绘制的路径存储在一个PathPaints集合中,该集合有3个属性(路径、使用的油漆以及如果是橡皮擦); 我已经尝试在drawpath上设置油漆

  • 我想使用Fabric.js在我的web应用程序中实现eraser。在Fabric.js中有没有实现橡皮擦的方法?例如,如在MS Paint?

  • 实际上,我可以使用函数来完成。我从“HTML5画布-如何在图像背景上画一条线?”中得到的东西。但是我需要在不使用from函数的情况下绘制图像,如下所示:

  • 我编写了这段代码,可以在JavaFX画布上绘制。它可以很好地工作,但我不知道如何重新绘制画布(比如在Swing中),以便在新画布上重新开始绘制。这是我的代码,非常感谢你的帮助!马里奥

  • 我已经创建了一个HTML5绘图应用程序,它具有基本功能,允许用户选择一种颜色来绘制,改变绘图工具的大小(半径),撤消,重做,以及完全清除画布。 我最近添加了一个橡皮擦工具,使用globalCompositionProperty(desitnation-out)擦除画布的选定区域。这部分工作良好,但当我去撤销擦除,整个画布被清除,重做功能不起作用。当我用常规的绘图工具(使用source-over)恢

  • 5.2.3 在画布上绘图 本节介绍如何在画布上绘制图形。为了完整起见,我们将前面介绍过的首先需要执行的 几条语句合在一起复制如下: >>> from Tkinter import * >>> root = Tk() >>> c = Canvas(root,width=300,height=200,bg='white') >>> c.pack() 如前所述,c 是一个画布对象,而画布对象提供了若干