我有以下任务,我试图以最有效的方式完成:我有不同数量的不同大小的图片作为像素数组,我需要逐个像素地添加到画布中。每个像素的值都必须添加到画布的 ImageData 中,以便结果是两个或多个图像的混合。
我目前的解决方案是从图片需要与图片大小混合的位置检索 ImageData。然后我将图片的 ImageData 添加到检索到的 ImageData 并将其复制回相同的位置。
从某种意义上说,这是canvas globalCompositeOperation“更轻”的手动实现。
"use strict";
let canvas = document.getElementById("canvas");
let width = canvas.width = window.innerWidth;
let height = canvas.height = window.innerHeight;
let ctx = canvas.getContext("2d");
ctx.fillStyle="black";
ctx.fillRect(0, 0, width, height);
let imageData = ctx.getImageData(0,0,width,height);
let data = imageData.data;
function random(min, max) {
let num = Math.floor(Math.random() * (max - min + 1)) + min;
return num;
}
function createColorArray(size, color) {
let arrayLength = (size*size)*4;
let array = new Uint8ClampedArray(arrayLength);
for (let i = 0; i < arrayLength; i+=4) {
switch (color) {
case 1:
array[i+0] = 255; // r
array[i+1] = 0; // g
array[i+2] = 0; // b
array[i+3] = 255; // a
break;
case 2:
array[i+0] = 0; // r
array[i+1] = 255; // g
array[i+2] = 0; // b
array[i+3] = 255; // a
break;
case 3:
array[i+0] = 0; // r
array[i+1] = 0; // g
array[i+2] = 255; // b
array[i+3] = 255; // a
}
}
return array;
}
function picture() {
this.size = random(10, 500);
this.x = random(0, width);
this.y = random(0, height);
this.color = random(1,3);
this.colorArray = createColorArray(this.size, this.color);
}
picture.prototype.updatePixels = function() {
let imageData = ctx.getImageData(this.x, this.y, this.size, this.size);
let data = imageData.data;
for (let i = 0; i < data.length; ++i) {
data[i]+=this.colorArray[i];
}
ctx.putImageData(imageData, this.x, this.y);
}
let pictures = [];
let numPictures = 50;
for (let i = 0; i < numPictures; ++i) {
let pic = new picture();
pictures.push(pic);
}
function drawPictures() {
for (let i = 0; i < pictures.length; ++i) {
pictures[i].updatePixels();
}
}
drawPictures();
<!DOCTYPE html>
<html>
<head>
<title>...</title>
<style type="text/css">
body {margin: 0px}
#canvas {position: absolute}
</style>
</head>
<body>
<div>
<canvas id="canvas"></canvas>
</div>
<script type="text/javascript" src="js\script.js"></script>
</body>
</html>
该解决方案工作正常,但速度很慢。我不知道逐像素混合是否可以非常有效,但性能缓慢的一个原因可能是每次将新图像混合到画布中时我都需要获取 ImageData 并将其放回原处。
因此,主要问题是我如何才能在开始时获得整个画布 ImageData,然后根据需要混合到画布中的每张图片的位置和大小来查找正确的像素以更新,最后将更新后的 ImageData 放回画布?此外,非常感谢有关如何使混合更有效的任何其他想法。