【问题标题】:Load images from JSON object containing image references从包含图像引用的JSON对象加载图像
【发布时间】:2019-03-06 19:02:59
【问题描述】:

我正在构建一个 API,它将从 Konva 阶段获取 JSON 对象输出并将其转换为服务器端的图像。我正在使用konva-node npm 包,它工作得非常好,直到加载可能是原始“设计”一部分的远程图像。我可以看到 from this answer 关于我们将如何解决浏览器中的问题,但是这在 Konva 的 nodejs 实现中似乎并没有以相同的方式工作。

JSON 输入示例如下:

let json = {
"attrs": {
    "width": 600,
    "height": 600
},
"className": "Stage",
"children": [{
    "attrs": {},
    "className": "Layer",
    "children": [{
        "attrs": {
            "src": "https://ichef.bbci.co.uk/onesport/cps/480/cpsprodpb/1859A/production/_101883799_gettyimages-844211624.jpg"
        },
        "className": "Image"
    }]
}, {
    "attrs": {},
    "className": "Layer",
    "children": [{
        "attrs": {
            "text": "Hello world.",
            "x": 50,
            "y": 50,
            "fontSize": 20,
            "fill": "blue"
        },
        "className": "Text"
    }]
}]

}

如您所见,当我们再次将数据加载到画布中时,我已将 src 属性替换为一种占位符。

我遇到的问题是,一旦我在服务器端处理 JSON,实际上又要重新加载这些图像。

这是我当前的代码

var fs = require('fs')
const Konva = require('konva-node')
var Request = require('pixl-request')

let json = {"attrs":{"width":600,"height":600},"className":"Stage","children":[{"attrs":{},"className":"Layer","children":[{"attrs":{"src":"https://ichef.bbci.co.uk/onesport/cps/480/cpsprodpb/1859A/production/_101883799_gettyimages-844211624.jpg"},"className":"Image"}]},{"attrs":{},"className":"Layer","children":[{"attrs":{"text":"Hello world.","x":50,"y":50,"fontSize":20,"fill":"blue"},"className":"Text"}]}] }

var stage = new Konva.Stage()

let loadedDesign = Konva.Node.create(json)


loadedDesign.find('Image').forEach((imageNode) => {
  const imageURL = imageNode.getAttr('src')
  var request = new Request();

  request.get(imageURL, function(err, resp, data) {
    var img = new Konva.window.Image()
    img.onerror = err => { throw err }
    img.onload = () => {
      imageNode.image(img);
      imageNode.getLayer().batchDraw();
    }

    img.src = data;
  });
});

loadedDesign.toDataURL({
  callback: function(data) {
    var base64Data = data.replace(/^data:image\/png;base64,/, '');
    fs.writeFile('./images/out.png', base64Data, 'base64', function(err) {
      err && console.log(err)
      console.log('See out.png')
    });
  }
});

当前的输出结果是一个带有文本在画布上的图像,但该图像永远不会进入。

【问题讨论】:

    标签: konvajs


    【解决方案1】:

    您需要加载所有图像,然后才使用toDataURL()。我猜你的图片是不可见的,因为你在图片加载和渲染之前将 stage 转换为 dataURL

    var request = new Request();
    
    function loadImage(url) {
      return new Promise(resolve => {
        request.get(url, function(err, resp, data) {
          var img = new Konva.window.Image();
          img.onerror = err => {
            throw err;
          };
          img.onload = () => {
            resolve(img);
          };
          img.src = data;
        });
      });
    }
    
    async function run() {
      const stage = Konva.Node.create(json);
      const images = stage.find('Image');
    
      for (const imageNode of images) {
        const imageURL = imageNode.getAttr('src');
        const img = await loadImage(imageURL);
        imageNode.setImage(img);
      }
    
      stage.findOne('Layer').draw();
      const data = stage.toDataURL();
      var base64Data = data.replace(/^data:image\/png;base64,/, '');
      fs.writeFile('out.png', base64Data, 'base64', function(err) {
        err && console.log(err);
        console.log('See out.png');
      });
    }
    
    run().catch(e => {
      console.error(e);
    });
    

    【讨论】:

      猜你喜欢
      • 2019-06-17
      • 2014-08-13
      • 2018-11-06
      • 1970-01-01
      • 2018-04-05
      • 2019-07-27
      • 1970-01-01
      • 2015-10-06
      • 1970-01-01
      相关资源
      最近更新 更多