HTML5 Canvas将原始图像数据保存到数据URL

时间:2014-05-21 20:09:49

标签: javascript html5 canvas

我有一个函数,它接收图像,将其绘制到画布,将其拆分为块,并使用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字符串的方法吗?

1 个答案:

答案 0 :(得分: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代码将画布图像的每个块中的数据转换为由表示每个字节的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()函数(不需要这样做),但不管怎样,这是另一种方法。