【问题标题】:Dominant color conversion of image in html canvashtml画布中图像的主色转换
【发布时间】:2016-09-29 10:02:56
【问题描述】:

在使用画布工作/学习几个小时后,我设法获得了图像克隆,它现在是像素,我让用户从颜色光谱中选择一种颜色,并且我的函数中有该颜色十六进制:

move: function (color) {

 // 'color' is the value user selected

var img_id = jQuery(".selected_bg_img").attr("id");

alert(img_id);

var x = 0;
var y = 0;
var width = 409;
var height = 409;


var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var img=document.getElementById(img_id);
ctx.drawImage(img,x,y,width,height);

var imageData = ctx.getImageData(0,0,width,height);

var data = imageData.data;

alert(data);

}

现在有两个任务正在进行中,
1.我们如何从数据中提取主色?
2. 我们如何将主色转换为我们在函数中得到的颜色?对于现场工作示例,我在末尾给出了链接
注意:从产品图像的左侧选择图像(任何最后3个),并且当颜色选择它克隆到画布上的图像。
在这里,我试图用用户选择的颜色替换最大颜色来克隆图像..

for (var i=0;i<imgData.data.length;i+=4)
{
  imgData.data[i]=255-imgData.data[i];
  imgData.data[i+1]=255-imgData.data[i+1];
  imgData.data[i+2]=255-imgData.data[i+2];
  imgData.data[i+3]=255;
  }

*****编辑*****
我的问题不是很复杂我想我有这张图片在此处输入图片描述
所以我们可以清楚地看到主色是灰色,通过任何方法我只是想用我在函数中使用的新颜色替换该颜色移动并用新颜色绘制该图像。我拍摄的图像并显示了另一个示例: http://www.art.com/products/p14499522-sa-i3061806/pela-silverman-colorful-season-i.htm?sOrig=CAT&sOrigID=0&dimVals=729271&ui=573414C032AA44A693A641C8164EB595 在图像左侧,当我们选择相似图像​​时,它们在图像底部中心有“更改颜色”选项。这正是我想要做的。

所以现在我尝试读取 1x1 的图像,这就是我在记录它时在控制台中得到的(尤其是我显示的图像):

[166, 158, 152, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…]

所以它可能是从左上角开始的第一个开始,我想它需要遍历整个图像,这就是我遍历整个图像时得到的结果:

[110, 118, 124, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255…]

我用于迭代的循环是:

var imageData = ctx.getImageData(0,0,width,height);

var data = imageData.data;

for (var i=0;i<data.length;i+=4)
{
  data[i]=255-data[i];
  data[i+1]=255-data[i+1];
  data[i+2]=255-data[i+2];
  data[i+3]=255;
}
console.log(data);

这个迭代对吗?如果是,它现在似乎正在计算和替换主色,我在这里是空白的,但我现在在 rgb 中有用户值,需要寻找应该放置该值的位置

【问题讨论】:

  • 他们使用 2 张图片 - 一张您看到,一张用作遮罩。蒙版使选择要着色的部分变得容易。要着色,只需抓取一个像素的 rgb,转换为 hsv 或 hsl,然后将色调更改为所需的色调并转换回 rgb。当蒙版不透明时,只需对源图像中的每个像素执行此操作即可。看看这两张图片:(彩色)cache1.artprintimages.com/images/spp/living_61_70.jpg 和(反式/白色)cache1.artprintimages.com/images/spp/living_61_70_mask.png
  • @enhzflep 感谢一大群人告诉我,我的技术缺陷也是如此,我们不能这样做吗?无论如何,如果他们使用面具并且如果它的简单技术我现在应该看到这个。有什么资源可以查看我们如何进行掩码(意味着转换以及转换后我们如何编写它)?
  • @enhzflep 你能看看我刚刚找到的东西吗:stackoverflow.com/questions/18379818/… 这是我要做的吗?
  • 是的,准确。该死!尽管我阅读了几篇关于使用它们的教程,但我已经忘记了画布的内置合成模式。这个答案看起来很适合你。
  • 如果您可以访问原始 RAW(来自相机 HDRI),自动创建蒙版会简单得多。 JPJ 压缩通过减少颜色分量来减少大部分大小。当您需要精细的颜色选择时,这使得它们几乎无法处理。我从未见过一种可以很好地替换 JPG 中的颜色的方法,您总是会流血。您唯一的选择是手动创建蒙版或为整个图像着色。

标签: javascript jquery canvas html5-canvas


【解决方案1】:

给你。当我说您找到的链接将是合适的时,看起来我之前提供了错误和误导性的信息。 对不起!

基本上,您需要使用multiply 组合模式。 这是一个演示供您尝试。点击第三张图片会选择一种新颜色。

function byId(id){return document.getElementById(id)}
window.addEventListener('load', onDocLoaded, false);

function onDocLoaded(evt)
{
	byId('canvas2').addEventListener('click', onCanvasClicked, false);
	colorize('green');
}

function onCanvasClicked(evt)
{
	var newColour = getRandomColour();
	colorize(newColour);
}

function getRandomColour()
{
	return '#' + Math.floor(Math.random() * (Math.pow(2,24)-1)).toString(16);
}

function colorize(colourToUse)
{
	var mask = byId('maskImg');
	var colorImg = byId('colorImg');

	var width = colorImg.naturalWidth;
	var height = colorImg.naturalHeight;

	// draw the mask image to a canvas
	var can = byId('canvas1');
	var ctx = can.getContext('2d');
	can.width = width;
	can.height = height;
	ctx.drawImage(mask, 0, 0);
	
	// colorize the non transparent areas
	ctx.globalCompositeOperation = "source-in";
	ctx.fillStyle = colourToUse;
	ctx.fillRect(0, 0, can.width, can.height);
	
	
	// draw the combined output
	var can2 = byId('canvas2');
	var ctx2 = can2.getContext('2d');
	can2.width = width;
	can2.height = height;
	
	ctx2.drawImage(colorImg, 0, 0);
	ctx2.globalCompositeOperation = 'multiply';
	ctx2.drawImage(can,0,0);
}
body {
  background-color: ivory;
  padding: 20px;
}

canvas 
{
  border: 1px solid red;
  width: 275px;
  height: 275px;
}

.dontShow
{
	display: none;
}
	<img style='width:275px; height:275px' id='colorImg' src='http://cache1.artprintimages.com/images/spp/living_61_70.jpg'/><canvas id="canvas1"></canvas><canvas id='canvas2'></canvas>

	<!-- much easier than using image pre-loaders. onDocLoaded wont be fired until the html with images,script and css are available or have failed to load-->
	<img class='dontShow' id='maskImg' src='http://cache1.artprintimages.com/images/spp/living_61_70_mask.png'/>

【讨论】:

  • 最后一个问题,如果我想对其他人做同样的事情,我该如何更改第二张图片?
  • 太棒了,我们俩都过得更好!嗯,掩码 url 只是我在评论中留下的,也是示例应用程序使用的那个。两个图像都没有改变,它们只是被绘制到具有不同压缩模式的 2 个画布之一。
  • 糟糕!好吧,您可以将颜色和蒙版图像的 .src 设置为新图像的 URL。例如 byId('colorImg').src = *yourUrlHere*;byId('maskImg').src = *yourUrlHere* - 您也可以像小提琴一样预加载它们,而不是使用 html 中的 img 元素作为源图像进行绘制,您可以使用 2 个 pre 数组中的正确对- 加载的 - 1 个颜色数组和另一个蒙版数组。
  • 哦,不,是的,这就是我在为那个 nvm 感到抱歉之前所说的话
  • 宾果游戏!我想您只需将彩色图像加载到 Photoshop 中,创建一个新图层,然后使用彩色图层作为指南将蒙版绘制到新图层中。然后只需将新图层(仅)保存为PNG,瞧!一个新制作的面具。 :)
猜你喜欢
  • 2017-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-05
  • 2021-11-23
  • 1970-01-01
相关资源
最近更新 更多