在不影响背景的情况下擦除图像画布上的线条

erase lines on image canvas without effecting background

本文关键字:图像 擦除 影响 背景 情况下      更新时间:2023-09-26

我正在编写一个需要注释图像的web应用程序。为此,我使用了html5的画布。感谢网络,我发现了许多相似的代码。但我在开发代码后遇到了一个问题。

context.clearRect(pos.x,pos.y,pos.x,pos.y);

这是我用来擦除画布中线条的代码。我希望代码能擦除鼠标指针所在的位置。但代码所做的是擦除行,即使鼠标指针离行更近。

编辑:我发现擦除有问题。clearRect()的语法是

context.clearRect(x,y,width,height);

当我把位置x和位置y分别作为宽度和高度时,它正在擦除一大片区域。现在我把这两个值改为5,5,我可以擦除指针所在的位置

此外,我需要在完全注释后保存注释图像。我将这些图像作为画布的背景。我在画布上画线。当点击查看图像时,我只能看到线条。请检查我的代码,告诉我如何执行这两项操作。这是我的密码。

<%@ taglib uri="/struts-tags" prefix="s" %>
<html>
<head>
    <title>Success: Upload User Image</title>   
    <style>
        canvas { background:url("images/<s:property value="userImageFileName"/>") ;
                 background-size: 100% 100%;
                 background-repeat: no-repeat;}
    </style>    
</head>
<body>
    <h2>utStruts2 File Upload Example</h2>
    <img id="result" src="images/<s:property value="userImageFileName"/>" width="565" height="584" class="annotatable"/>
    <canvas id="myCanvas" width="565" height="584" style="border:1px solid #d3d3d3;" >
        Please use a modern browser like Firefox, Chrome, Safari
    </canvas>
    <input type="button" value="draw" onClick="draw()">
    <input type="button" value="eraser" onClick="erase()">
    <canvas id="canvas2" width="565" height="584" hidden="true"></canvas>
    <script>
          var canvas = document.getElementById('myCanvas');           
          var coord = document.getElementById('coord');
          var context = canvas.getContext('2d');
          var canvas2 = document.getElementById('canvas2');
          var cantext2 = canvas2.getContext('2d');
        function draw(){
            mode="draw";    
            operate(mode);
        }
        function erase(){
            mode="erase";
            operate(mode);
        }
        function operate(mode)
        {
              var mousedown = false;
              context.strokeStyle = '#0000FF';
              context.lineWidth = 5;
              canvas.onmousedown = function(e) {
                  var pos = fixPosition(e, canvas);
                  mousedown = true;
                  context.beginPath();
                  context.moveTo(pos.x, pos.y);                       
                  //return false;
              };
              canvas.onmousemove = function(e) {
                  var pos = fixPosition(e, canvas);                 
                  if (mousedown) {
                      if(mode=="draw"){
                          context.lineTo(pos.x, pos.y);
                          context.stroke();
                      }
                      if(mode=="erase"){
                          context.clearRect(pos.x,pos.y,pos.x,pos.y);
                          context2.drawImage(canvas, 0, 0);
                          context.clearRect(0, 0, 565, 584);
                          context.drawImage("images/<s:property value="userImageFileName"/>", 0, 0);
                          context.drawImage(canvas2, 0, 0); 
                      }
                  }
              };
              canvas.onmouseup = function(e) {
                  mousedown = false;
              };
              function fixPosition(e, gCanvasElement) {
                    var x;
                    var y;
                    x = e.pageX;
                    y = e.pageY;
                    x -= gCanvasElement.offsetLeft;
                    y -= gCanvasElement.offsetTop;
                    return {x:x, y:y};
                }
        }  
    </script>
</body>
</html>

clearRect接受以下参数:(xpos, ypos, width, height)

问题:
canvas.onmousemove功能中(在"擦除"模式下),您有:context.clearRect(pos.x,pos.y,pos.x,pos.y);

嗯,那不可能是对的。。

然后,根据鼠标位置擦除区域大小后,将context的剩余部分复制到某个缓冲画布context2:context2.drawImage(canvas, 0, 0);

然后清除整个绘图画布:context.clearRect(0, 0, 565, 584);

解决方案
一旦你修复了上面的问题(这样鼠标指针就可以像橡皮擦一样工作),你就想添加一个函数来组合/导出/存储你的注释图像:

首先使用缓冲区context2绘制(原始)图像,然后在此基础上绘制注释图像(均使用drawImage())(考虑图层)。

最后,使用.toDataURL()方法从context2缓冲区输出组合图像(并使用AJAX等发送结果(base64编码的数据url,这是一个简单的字符串))。

此外:

  • 你可能想知道你不需要标记你的缓冲区,只需要在内存中创建它:var canvas2=document.createElement('canvas');
  • 你的var mode正在泄漏到全局(我只会发布operate('draw')等,并保存腰部操作,以利于更好的用户体验响应能力("无工作可做"))