【问题标题】:HTML5 Canvas Saving Raw image data to data URLHTML5 Canvas 将原始图像数据保存到数据 URL
【发布时间】:2014-07-10 15:58:58
【问题描述】:

我有一个函数,它获取图像,将其绘制到画布上,将其拆分为块,然后使用 getImageData 方法将这些块保存为图像数据,并将数据对象推送到数组中。最后我的数组看起来像这样

[ImageData, ImageData, ImageData, ImageData, ImageData, ImageData, ImageData, ImageData, ImageData, ImageData, ImageData, ImageData, ImageData, ImageData, ImageData, ImageData, ImageData, ImageData, ImageData, ImageData, ImageData, ImageData, ImageData, ImageData, ImageData, ImageData, ImageData, ImageData, ImageData, ImageData, ImageData, ImageData, ImageData, ImageData, ImageData, ImageData]

每个具有这些属性的 Imagedata 对象

data: Uint8ClampedArray[17424]
height: 66
width: 66

我的问题是,除了将这些部分中的每一个都绘制回画布并将画布保存为 dataURL 之外,还有其他方法可以将这些原始数据转换为 url 字符串吗?

【问题讨论】:

    标签: javascript html canvas


    【解决方案1】:

    更新

    要将每个部分编码为单独的 PNG,您需要使用 js-png-encoder 和以下 JavaScript:

    var imageData = []; //Your image data array
    var images = []; //completed images
    
    for (i = 0; i < imageData.length; i++) { //Each block of canvas image
        var temp = "";
        for (j = 0; j < imageData[i].data.length; j++) { //Each byte
            temp += String.fromCharCode(imageData[i].data[j]);
        }
        var encoded = generatePng(imageData[i].width, imageData[i].height, temp);
        images.push("data:image/png;base64," + btoa(encoded)); //Push to final array
    }
    

    这个 JavaScript 的 sn-p 将画布图像的每个块中的数据转换为由代表每个字节的 ASCII 字符组成的字符串,并将其传递给 generatePng()。然后使用 btoa() 将返回的结果编码为 base64 并附加数据类型。生成的图像数组中的每个元素都可以设置为图像元素的 src 并显示。我对此进行了测试,它可以工作。

    上一个

    是的,您可以从块中的数据手动组装一个字符串,然后使用 btoa() JavaScript 函数将其转换为 base64 并添加数据类型信息。这样做的方法如下:

    var imageData = []; //Your image data array
    var blocksWide = 10; //The number of blocks across the width of the canvas data, eg. Math.ceil(canvas.width/66)
    var output = ""; //Where the base64 string will be stored
    
    for (i = 0; i < imageData.length; i += blocksWide) { //each row of blocks
    
        for (k = 0; k < imageData[i].height; k++) { //each row of bytes
    
            var row = imageData[i].width * k; //the current row of bytes across the width
    
            for (l = 0; l < blocksWide; l++) { //each block on imageData row
    
                for (m = 0; m < imageData[i + l].width; m++) { //each byte on the current row in current block
    
                    var row2 = imageData[i + l].width * row;
                    output += String.fromCharCode(imageData[i + l].data[row2 + m]);
                }
            }
        }
    }
    
    output = "data:image/png;base64," + btoa(output);
    console.log(output);
    

    可能需要稍作调整才能使其完美运行,但它的工作原理是计算穿过画布宽度所需的块数,然后遍历每一行块。对于每一行,它通过以正确的顺序组装数组的内容来组装每一行图像数据。最后,它将生成的字符串转换为 base64 并添加数据类型字符串。当然,有人会想知道为什么不简单地调用 toDataURL() 函数分割图像(消除对这个的需要),但不管怎样,这是另一种方法。

    【讨论】:

    • 我应该澄清一下,我希望图像作为部分。基本上我希望每个小部分都是自己的图像,因此我可以将它们作为元素对齐并在它们上操作 css 等。但这让我朝着正确的方向前进。谢谢
    • 只是一些调整的想法:此代码实际上并未将像素编码为 png。每个像素有四个字节,而不是一个。将数字附加到字符串表示十进制数。
    • 正如您评论的那样,我实际上正在调查。如果你对整个图像进行编码,它会工作得很好。给我几分钟,我会更新每个部分的编码方法。
    • @richbai90,我更新了我的答案,包括将图像数据分解为单个 PNG 的能力。它已经过测试并且可以正常工作,如果我的更新答案有帮助,请告诉我。
    • 非常喜欢。谢谢
    猜你喜欢
    • 2011-12-15
    • 2017-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多