简体   繁体   English

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

[英]HTML5 Canvas Saving Raw image data to data URL

I have a function which takes an image, draws it to the canvas, splits it up into blocks, and saves those blocks as image data using the getImageData method, and pushes the data objects to an array. 我有一个获取图像的函数,将其绘制到画布上,将其拆分为块,然后使用getImageData方法将这些块另存为图像数据,然后将数据对象推入数组。 In the end my array looks like this 最后我的数组看起来像这样

[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]

With each of those Imagedata objects having these properties 每个具有这些属性的Imagedata对象

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

My question is, apart from drawing each of these sections back to the canvas and saving the canvas as a dataURL is there another way to convert this raw data to a url string? 我的问题是,除了将每个部分绘制回画布并将画布另存为dataURL之外,还有另一种方法可以将该原始数据转换为url字符串吗?

Update 更新

To encode each section as an individual PNG, you'll need to use js-png-encoder and the following JavaScript: 要将每个部分编码为单独的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
}

This snippet of JavaScript converts the data in each block of the canvas image to a string composed of the ASCII characters representing each byte and passes it to generatePng(). 该JavaScript代码段将画布图像的每个块中的数据转换为由表示每个字节的ASCII字符组成的字符串,并将其传递给generatePng()。 The returned result is then encoded to base64 using btoa() and prepended with the datatype. 然后,使用btoa()将返回的结果编码为base64,并在数据类型之前添加。 Each element in the resulting images array can be set as the src for an image element and displayed. 可以将结果图像数组中的每个元素设置为图像元素的src并显示。 I tested this and it works. 我对此进行了测试,并且有效。

Previous 以前

Yes, you can assemble a string manually from the data in the blocks and convert it to base64 using the btoa() JavaScript function and prepend the datatype information. 是的,您可以使用块中的数据手动组装字符串,然后使用btoa() JavaScript函数将其转换为base64,并添加数据类型信息。 Here's how that can be done: 这是可以做到的:

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);

It may need a little tweaking to get it working perfectly, but it works by computing the number of blocks it would take to cross the width of the canvas, then iterates through each row of blocks. 可能需要进行一些调整才能使其正常工作,但是它可以通过计算跨越画布宽度所需的块数,然后遍历每一行块来工作。 For each row, it assembles each line of image data by assembling the content of the arrays in the correct order. 对于每一行,它通过以正确的顺序组装数组的内容来组装图像数据的每一行。 Finally, it converts the resulting string to base64 and prepends the datatype string. 最后,它将结果字符串转换为base64并添加数据类型字符串。 Of course, one would wonder why you wouldn't simply call the toDataURL() function before splitting the image (eliminating the need for this), but either way, this is another method. 当然,您会想知道为什么分割图像之前不会简单地调用toDataURL()函数(消除对此的需要),但是无论哪种方式,这都是另一种方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM