进行画布图像像素操作的步骤是啥?
Posted
技术标签:
【中文标题】进行画布图像像素操作的步骤是啥?【英文标题】:What are the steps to do canvas image pixel manipulation?进行画布图像像素操作的步骤是什么? 【发布时间】:2021-04-20 22:11:11 【问题描述】:好吧,我一直在尝试对画布上的图像进行像素操作。
基本上,我想要实现的是用其他自定义颜色交换/替换图像中已经上传到画布上的颜色。正如您在所附图片中看到的那样,我的画布设计师上传了图片,设计师的左下角有来自图像的带有项目符号的颜色(图像中存在带有项目符号的颜色),上面是我的自定义调色板。
这是我在将图像上传到画布后交换/替换图像颜色的步骤
-
将图像上传到画布
点击画布上上传图片的颜色复选框(例如,用图片中显示的复选框选中紫色)
单击自定义调色板中的任何颜色(例如图像中显示的黄色)以替换图像中的颜色(例如,紫色应替换为图像中的黄色)
这是迄今为止我对像素操作所做的工作。在选中图像中的颜色框后单击自定义颜色,就会触发以下部分
jQuery('ul').on('click','li.licolors',function()
console.log("licolors");
var activeObject = canvas.getActiveObject();
if (activeObject && (activeObject.type === 'path'))
activeObject.set("stroke",jQuery(this).css('background-color'));
activeObject.dirty = true;
canvas.renderAll();
updateCanvasState();
else if(activeObject && (activeObject.type === "image"))
if($('.checkboxlicolorsfromimage').is(':checked'))
var colorfromimage = $('.checkboxlicolorsfromimage').val().split(",");//splitting color of checked checkbox purple rgb(83,70,128,255)
var Rcfi = colorfromimage[0];//Red from image
console.log(Rcfi);
var Gcfi = colorfromimage[1];//Green from image
console.log(Gcfi)
var Bcfi = colorfromimage[2];//Blue from image
console.log("bcfi"+Bcfi);
var Acfi = colorfromimage[3];//Alpha from image
var colortoimage = getRGB(jQuery(this).css('background-color'));//this variable holds rgbvalue (yellow color rgb(255, 205, 0)) which I have to apply to the image
var Rcti = colortoimage.red;//Red apply to image
console.log(Rcti);
var Gcti = colortoimage.green;//Green apply to image
console.log(Gcti);
var Bcti = colortoimage.blue;//Blue apply to image
console.log(Bcti);
var target = new Image();
target.src = canvas.toDataURL();
canvas.getContext('2d').drawImage(target,0,0);
const imageData = canvas.getContext('2d').getImageData(0, 0, target.width, target.height);
for (var i = 0; i < imageData.data.length; i += 4)
if(parseInt(imageData.data[i]) == parseInt(Rcti))console.log(imageData.data[i]);
imageData.data[i] = Rcfi;//Red
console.log(Rcfi);
if(parseInt(imageData.data[i + 1]) == parseInt(Gcti))console.log(imageData.data[i + 1]);
imageData.data[i + 1] = Gcfi;//Green
console.log(Gcfi);
if(parseInt(imageData.data[i + 2]) == parseInt(Bcti))console.log(imageData.data[i + 2]);
imageData.data[i + 2] = Bcfi;//Blue
console.log(Bcfi);
canvas.getContext('2d').putImageData(imageData, 0, 0);
activeObject.dirty = true;
canvas.renderAll();
updateCanvasState();
);
我没有收到任何错误或警告,我可以在控制台中看到我能够运行上述代码,但它没有在画布上已上传的图像中交换我的颜色。
-
是否可以在图像上传到画布后交换/替换图像中的颜色?然后用我们自己的颜色交换/替换特定的颜色通道
我发现的大部分参考资料都在图片
.onload
上
https://pictureelement.github.io/html5tech/canvas-pixel-manipulation-and-animations.html
https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas
https://www.tutorialspoint.com/Change-colour-of-an-image-drawn-on-an-HTML5-canvas-element
【问题讨论】:
你试过用调试器调试代码吗? 您是否想要进行精确的颜色匹配 - 因为它看起来好像您的图像在颜色方面非常复杂。 是的,通过在我的浏览器控制台中放置断点来调试它,我可以看到我的 console.logs 在控制台中打印像素 我的几块钱不禁对您已正确更新画布的可能性视而不见,但不知何故又用canvas.renderAll
或updateCanvasState
调用它。你试过绝育它们吗?我所期待的最后一件事是图像数据被放回 - 我不熟悉的其他东西,所以它是我的主要嫌疑人。
是的,我相信应该可以用我的自定义颜色像素替换特定的颜色像素,不确定是否仅在图像为.onload
时有效,或者在上传到画布后有效
【参考方案1】:
我会把这个留在这里让你玩。我做的最后一件事实际上是putImageData
。我想问题在于我不认识的位之一,正如 cmets 中提到的那样。
"use strict";
//window.addEventListener('load', onLoadedCreateB64url, false);
window.addEventListener('load', onLoadedUseEmbeddedImage, false);
// 33x33 pixel image of front wheel
var b64ImgSrc2 = 'data:image/png;base64,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';
function onLoadedUseEmbeddedImage(evt)
let img = document.querySelector('img');
img.addEventListener('load', imgLoaded, false);
img.src = b64ImgSrc2;
function imgLoaded(evt)
let img = this;
let can = document.querySelector('canvas');
let ctx = can.getContext('2d');
can.width = img.naturalWidth;
can.height = img.naturalHeight;
ctx.drawImage(img, 0, 0);
//141,127,143 - a few vertical pixels on right hand side of rim
// color: #8d7f8f;
recolourInPlace(can, 141,127,143, 255,0,0)
function onLoadedCreateB64url(evt)
let img = document.querySelector('img');
let can = document.querySelector('canvas');
can.width = img.naturalWidth;
can.height = img.naturalHeight;
let ctx = can.getContext('2d');
ctx.drawImage(img,0,0);
let src = can.toDataURL();
console.log(src);
function recolourInPlace(canvas, rin,bin,gin, rout,gout,bout)
let ctx = canvas.getContext('2d');
let imgData = ctx.getImageData(0,0, canvas.width, canvas.height);
let width = canvas.width, height = canvas.height;
let data = imgData.data;
for (var y=0; y<height; y++)
for (var x=0; x<width; x++)
let index = ((y*width)+x) *4;
if (data[index+0]==rin && data[index+1]==bin && data[index+2]==gin)
data[index+0] = rout;
data[index+1] = gout;
data[index+2] = bout;
ctx.putImageData(imgData, 0, 0);
<img/>
<canvas></canvas>
【讨论】:
以上是关于进行画布图像像素操作的步骤是啥?的主要内容,如果未能解决你的问题,请参考以下文章