使用JavaScript和HTML5从数组创建图像

12

这是我的代码。我在JavaScript中创建了名为imageData的2D数组。在将所有像素放入该数组之后,我想创建图像并将这些值放入图像中。

    var imageData = new Array(width);

    var image = new Image;

for (var i = 0; i < width; i++) {
    imageData[i] = new Array(height);
}

    image.src = imageData; //Here is the problem. I want to do that. 
3个回答

34

您可以按照以下方式从数组中创建图像:

var width = 400,
    height = 400,
    buffer = new Uint8ClampedArray(width * height * 4); // have enough bytes

末尾的* 4代表RGBA,我们需要与canvas兼容。

用一些数据填充缓冲区,例如:

for(var y = 0; y < height; y++) {
    for(var x = 0; x < width; x++) {
        var pos = (y * width + x) * 4; // position in buffer based on x and y
        buffer[pos  ] = ...;           // some R value [0, 255]
        buffer[pos+1] = ...;           // some G value
        buffer[pos+2] = ...;           // some B value
        buffer[pos+3] = 255;           // set alpha channel
    }
}

填充后,将缓冲区用作画布的源:

// create off-screen canvas element
var canvas = document.createElement('canvas'),
    ctx = canvas.getContext('2d');

canvas.width = width;
canvas.height = height;

// create imageData object
var idata = ctx.createImageData(width, height);

// set our buffer as source
idata.data.set(buffer);

// update canvas with new data
ctx.putImageData(idata, 0, 0);

请注意,您可以使用imageData缓冲区(此处为:idata.data)而不是创建自己的缓冲区。只有在使用浮点值或从其他源获取缓冲区时才会真正有用 - 尽管如上设置缓冲区将为您处理剪辑和舍入值。
现在,您的自定义数组中的数据被复制到画布缓冲区。下一步是创建图像文件。
var dataUri = canvas.toDataURL(); // produces a PNG file

现在您可以使用data-uri作为图像的来源:

image.onload = imageLoaded;       // optional callback function
image.src = dataUri

7

你不能像那样创建一个图片的src。

一个有效的dataURL是一个带有类型前缀的base64编码字符串,而不是一个数组。

与canvas相关联的图像数据数组是一个Uint8ClampedArray,而不是普通的javascript数组。

这里是一种创建可操作的像素数组的方法:

演示:http://jsfiddle.net/m1erickson/956kC/

// create an offscreen canvas
var canvas=document.createElement("canvas");
var ctx=canvas.getContext("2d");

// size the canvas to your desired image
canvas.width=40;
canvas.height=30;

// get the imageData and pixel array from the canvas
var imgData=ctx.getImageData(0,0,40,30);
var data=imgData.data;

// manipulate some pixel elements
for(var i=0;i<data.length;i+=4){
    data[i]=255;   // set every red pixel element to 255
    data[i+3]=255; // make this pixel opaque
}

// put the modified pixels back on the canvas
ctx.putImageData(imgData,0,0);

// create a new img object
var image=new Image();

// set the img.src to the canvas data url
image.src=canvas.toDataURL();

// append the new img object to the page
document.body.appendChild(image);

1
创建一个适当大小的canvas元素,并获取其2D渲染上下文。您不必将此画布添加到文档中。使用上下文创建一个ImageData对象。将数组中的值复制到ImageData对象中。在您的情况下,直接填充ImageData对象可能更有效,而不是使用单独的数组。使用上下文的putImageData来绘制像素数据。然后,根据“创建图像”的具体要求,您可能需要将画布序列化为数据URI,以便可以填充img元素的src

但如果我使用putImageData,它会绘制图像。我不想这样做。我必须用另一种方式来绘制这个图像。 - user3470518
只是出于好奇,你为什么不想这样做,而且为什么你必须用另一种方式来绘制这个图像呢? - guest
我想用WebGL发送图像。我按照您的方法操作,但重要的是我必须在WebGL中使用纹理。 - user3470518
你可以使用类型化数组在WebGL中指定纹理数据,这不是偏离主题。https://www.khronos.org/registry/webgl/specs/1.0/#5.14.8 - guest

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接