我试图将图像变成双色并将其贴在画布上。
适用于桌面浏览器:
移动浏览器失败:
Workable demo on JSFiddle,此示例适用于Chrome,但在Android的默认浏览器中失败。
代码是:
<style>
body {
background-color: gray;
}
</style>
<canvas id="mycanvas" width="64" height="64"></canvas>
<script>
var image = new Image();
image.src = 'image.png';
image.onload = function () { //once the image finishes loading
var context = document.getElementById("mycanvas").getContext("2d");
context.drawImage(image, 0, 0);
var imageData = context.getImageData(0, 0, 64, 64);
var pixels = imageData.data;
var numPixels = pixels.length;
for (var i = 0; i < numPixels; i++) { //for every pixel in the image
var index = i * 4;
var average = (pixels[index] + pixels[index + 1] + pixels[index + 2]) / 3;
pixels[index] = average + 255; //red is increased
pixels[index + 1] = average; //green
pixels[index + 2] = average; //blue
//pixels[index + 3] = pixels[index + 3]; //no changes to alpha
}
context.clearRect(0, 0, 64, 64); //clear the image
context.putImageData(imageData, 0, 0); //places the modified image instead
}
</script>
摘要是:
笑脸看起来像这样(块引用,所以你可以说它是透明的):
然而,与chrome和android浏览器相比,
android绘图的背景是红色的,而chrome绘图是完全透明的。
因此...
注意:我已经尝试了if (pixels[index + 3] == 0) continue;
,我知道这一点,但它不适用于不透明度不同的图片。
答案 0 :(得分:4)
好的,我有result
。
首先看看你的循环:
for (var i = 0; i < numPixels; i++) { //for every pixel in the image
var index = i * 4;
index
将比numPixels
大3倍以上。并且会获得undefined
个值。平均值为NaN
。但是,我解决了这个问题 - 结果是一样的。
所以我尝试对每个像素使用fillStyle
和fillRect
。一切都变好了。我的code
:
function putImageData(ctx, imageData, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight) {
var data = imageData.data;
var height = imageData.height;
var width = imageData.width;
dirtyX = dirtyX || 0;
dirtyY = dirtyY || 0;
dirtyWidth = dirtyWidth !== undefined ? dirtyWidth : width;
dirtyHeight = dirtyHeight !== undefined ? dirtyHeight : height;
var limitBottom = dirtyY + dirtyHeight;
var limitRight = dirtyX + dirtyWidth;
for (var y = dirtyY; y < limitBottom; y++) {
for (var x = dirtyX; x < limitRight; x++) {
var pos = y * width + x;
//adding red increased here
ctx.fillStyle = 'rgba(' + data[pos * 4 + 0] + 255 + ',' + data[pos * 4 + 1] + ',' + data[pos * 4 + 2] + ',' + (data[pos * 4 + 3] / 255) + ')';
ctx.fillRect(x + dx, y + dy, 1, 1);
}
}
};
var image = new Image();
image.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gcVBAYmslkm5QAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAABc0lEQVR42u2a3QrDMAiFZ9j7v7K7CpTRVtt4NCEnsJt1BP1y4l8nqvrZebXP5osACIAACIAACIAACIAACIAACIAAqpaIlPXkgpwHiIiqqtw5efa8f7csgIgTVVU5AlwGAELOSAjfLKndOWFBQyohVAHWPR/dCwEBCiDCYDSIViH5p/v87xUZZ8IUkJHGEGpoyLu/QjZomffeE+37xwthFH5aKdwNtQyOyhjT1QGzXosWaYBljMdY72laPUZZDLBq+6jTPO41xRXwGB/1Gw5ECOC6StxSASMQ2o5OQ9Jg5VxviYFI5KxgSQBXzmYNPlLaYctw72jr7ncd2DQx4KkCKud/cACeQNghvAmaCDjhCvBCOFODJX2Pgkp7gben+vR5pAqgL0aip8KI2ABNgyMRGzFiT1FARI+eWTDB3w7P6nhKHVBd5pYDGFVABsCU/wccHblLaxUNEwzACvKHB8EVFoeiBEAABEAABEAABEAABEAAe64fre4tZAeLAbcAAAAASUVORK5CYII=';
image.onload = function () {
var context = document.getElementById("mycanvas").getContext("2d"),
imageData;
context.drawImage(image, 0, 0);
imageData = context.getImageData(0, 0, 64, 64);
putImageData(context, imageData, 0, 0);
}