如何从 Web 服务返回的 PNG 数据创建 FabricJS 图像?

How to create a FabricJS image from PNG data returned by a web service?

我有一个包含 FabricJS 的页面 canvas。当用户按下某个按钮时,就会向 Web 服务发送请求。响应包含 PNG 图像的数据,我想将其插入 canvas.

在下面的代码片段中,图像数据包含在 $xhr.responseText.

function downloadButtonPressed() {
    var username = $("input#username").val();
    var password = $("input#password").val();
    $.ajax({
        type: "GET",
        url: "http://myserver/myapp/map",
        headers: {
            "Authorization": "Basic " + btoa(username + ":" + password),
          },
        crossDomain: true,
        xhrFields: {
                withCredentials: true
            },
        success: function (data, status, xhr) {
            alert("success");
        }
    }).fail(function ($xhr) {
        console.log("response: " + $xhr);
        // Here, $xhr.responseText contains the data of the PNG image
    });
}

我想将 $xhr.responseText 中的 PNG 图像添加到 FabricJS canvas。

我该怎么做?

有一个方法fabric.Image.fromURL,但我需要一些东西,它可以将字符串(或字节流)转换为 FabricJS 图像。

如果您的响应文本是包含图像数据的二进制字符串,您可以构建一个 dataurl 并从 datayurl 加载标准图像。

function downloadButtonPressed() {
    var username = $("input#username").val();
    var password = $("input#password").val();
    $.ajax({
        type: "GET",
        url: "http://myserver/myapp/map",
        headers: {
            "Authorization": "Basic " + btoa(username + ":" + password),
        },
        crossDomain: true,
        xhrFields: {
            withCredentials: true
        },
        success: function (data, status, xhr) {
            alert("success");
        }
    }).fail(function ($xhr) {
        var myDataURL = "data:image/png;base64," + btoa($xhr.responseText);
        var img = document.createElement("IMG");
        img.onload = function(){
            var fImg = new fabric.Image(img, {options});
        }
        img.src = myDataURL
    });
}

如果您的响应是一个 utf8 字符串,从而产生非法字符错误,如 MDN 所述,请尝试使用此替代解决方案将其转换为 base 64:

https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/btoa

function utf8_to_b64(str) {
    return window.btoa(unescape(encodeURIComponent(str)));
}

btoa(unescape(encodeURIComponent($xhr.responseText)));
  return new Promise(function (resolve, reject) {
    axios
        .get(imgSrcURl, {
                responseType: 'arraybuffer'
            })
        .then(response => {
            var data_url = Buffer.from(response.data, 'binary').toString('base64');
            data_url = "data:application/octet-stream;base64," + data_url;
            fabric.Image.fromURL(
                data_url,
                img => {
                    resolve(img);
                });
        });
});