KonjaJs 使用 toDataUrl 保存背景图像

Posted

技术标签:

【中文标题】KonjaJs 使用 toDataUrl 保存背景图像【英文标题】:KonjaJs saving background image with toDataUrl 【发布时间】:2020-06-07 02:10:38 【问题描述】:

我正在使用 konvajs (https://konvajs.org) 创建一个网页,用户可以在其中将家具图像拖放到带有背景图像的画布中。然后用户可以单击提交按钮,我调用 stage.toDataUrl() ,将其存储在 textarea 中并保存到数据库。一切正常,除了当我加载 base 64 字符串时,我的背景图像丢失了,但所有其他拖放图像都在那里。下面是我的详细代码。请帮忙..

          var stage = new Konva.Stage(
             container: 'container',
             width: 800,
             height: 600
           );


           var canvasBg = new Image();
           canvasBg.src = 'mybackgroundimage.png'; // --->> this is the image that fails to be saved as image
           canvasBg.onload = function() 
               initStage(canvasBg);
           

           function initStage(canvasBg)
               var background = new Konva.Layer();
               background.id('background');
               var layer = new Konva.Layer();
               layer.id('items');
               stage.add(background);
               stage.add(layer);
               drawBackground(background, canvasBg);

               var item = '';

               $('#product_container').on('dragstart', (e) => 
                   item = ;
                   item.src = e.target.dataset.imgsrc;
                   item.alt = e.target.dataset.imgalt;
                   item.id = e.target.dataset.imgid;
                   item.qty = 1;
                   item.price = e.target.dataset.price;
               );

               var con = stage.container();
               con.addEventListener('dragover', function(e) 
                   e.preventDefault(); // !important
               );

               con.addEventListener('drop', function(e) 
                   e.preventDefault();
                   stage.setPointersPositions(e);
                   var group = new Konva.Group(
                       draggable: true
                   );
                   Konva.Image.fromURL(item.src, function(image) 
                     image.addName(item.alt);
                     image.setAttr('src', item.src);
                     image.id(item.id);

                     var stagePos = stage.getPointerPosition();
                     var imgPos = 
                       x : stagePos.x - image.width()/2,
                       y : stagePos.y - image.height()/2,
                     ;
                     image.position(imgPos);

                     var text = new Konva.Text(
                       x: imgPos.x,
                       y: imgPos.y + image.height() + 4,
                       width: image.width(),
                       height: 20,
                       align: 'center',
                       verticalAlign: 'middle',
                       fontFamily: 'Calibri',
                       fontSize: 14,
                       text: item.alt,
                       fill: 'black'
                     );

                     group.add(image);
                     group.add(text);
                     layer.add(group);
                     layer.draw();
                   );
               );
           


           function drawBackground(background, bgImage) 
               var context = background.getContext();
               context.drawImage(bgImage, 0, 0, bgImage.width, bgImage.height, 0, 0, cWidth, cHeight);                
           

           // When user submit the form, i store stage.toDataURL() in textarea
           $("#frmCanvas").submit(function()
               $("#stageimage").val(stage.toDataURL());
               return true;
           );

这是截图

保存前 https://i.stack.imgur.com/kywbH.png

保存后 https://i.stack.imgur.com/yCpn5.png

【问题讨论】:

【参考方案1】:

不建议直接使用layercontext

stage.toDataURL() 不会保存此类更改。要修复它,您有两种方法:

    使用自定义形状绘制背景:
var background = new Konva.Layer();
var back = new Konva.Shape(
  sceneFunc: ctx => 
    ctx.drawImage(bgImage, 0, 0, bgImage.width, bgImage.height, 0, 0, cWidth, cHeight);
  
);
background.add(back);
    或者直接添加Konva.Image:
var background = new Konva.Layer();
var back = new Konva.Image(
  image: bgImage
);
background.add(back);

如果你有特殊的逻辑来剪辑/裁剪图像,你可以使用外部画布:

function createBackgroundCanvas(image) 
   var canvas = document.createElement('canvas');
   var ctx = canvas.getContext('2d');
   ctx.drawImage(image, 0, 0, image.width, image.height, 0, 0, cWidth, cHeight);


var background = new Konva.Layer();
var back = new Konva.Image(
  image: createBackgroundCanvas(bgImage)
);
background.add(back);

【讨论】:

以上是关于KonjaJs 使用 toDataUrl 保存背景图像的主要内容,如果未能解决你的问题,请参考以下文章

toDataURL() 小屏幕,小保存图片

toDataURL() 无法在 Blazor Webassembly 中使用 JS 互操作保存 HTML5 画布的内容?

toDataURL() 从 iOS 设备返回空白图像

html5 Canvas getImageData 或 toDataURL 的结果 - 哪个占用更多内存?

canvas.toDataURL() 安全错误 操作不安全

canvas.toDataURL() 导致安全错误