Javascript画布像素操纵 [英] Javascript canvas pixel manipulation

查看:144
本文介绍了Javascript画布像素操纵的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有产品图片,每个图片都有两个可配置的区域,如下所示:
1. background
2.前景





我的问题是,我通过图像读取旧的像素值,并用新的更改它



位旧像素值不一致。



如何实现所需的功能?

$



示例图片链接:
b
$ b

如果您可以向我建议任何其他方法, a href =http://developersbench.com/canvas/img/design_2.jpg =nofollow> http://developersbench.com/canvas/img/design_2.jpg

解决方案

如果我想是的,你想要的是将一个给定颜色的近像素更改为另一种颜色。



最简单的方法是使用h,s,l颜色空间:在这个自然颜色空间中,具有相似色调的颜色将被眼。你可以只移动色调,同时保持相同的饱和度(==颜色'强度')和亮度。



br>
•将点r,g,b转换为色相,饱和度,亮度

•?从sourceHue到当前的色调是否足够近?

---- >>将其移到newHue(保持相同的饱和度/亮度)



这里:



http://jsfiddle.net/9GLNP/



您可以使用参数进行游戏。您提供的纹理具有18平均色调,因此如果源色调离18太远,则不会进行任何更改。 8-10似乎是一个很好的容忍。



  //提供一个包含[img]的新画布其中
//所有像素超过[tolerance]
//从[tgtHue]开始,将被[newHue]替换
function shiftHue(img,tgtHue,newHue,tolerance){
//正常化输入
var normalizedTargetHue = tgtHue / 360;
var normalizedNewHue = newHue / 360;
var normalizedTolerance = tolerance / 360;
//创建输出canvas
var cv2 = document.createElement('canvas');
cv2.width = img.width;
cv2.height = img.height;
var ctx2 = cv2.getContext('2d');
ctx2.drawImage(img,0,0);
// get canvad img data
var imgData = ctx2.getImageData(0,0,img.width,img.height);
var data = imgData.data;
var lastIndex = img.width * img.height * 4;
var rgb = [0,0,0];
var hsv = [0.0,0.0,0.0];
//在所有像素上循环
for(var i = 0; i< lastIndex; i + = 4){
//检索r,g,b
var r = data [i];
var g = data [i + 1];
var b = data [i + 2];
// convert to hsv
RGB2HSV(r,g,b,hsv);
//如果hue接近足够,从tgtHue改变颜色
var hueDelta = hsv [0] - normalizedTargetHue;
if(Math.abs(hueDelta)< normalizedTolerance){
// adjust hue
//?或不添加delta ???
hsv [0] = normalizedNewHue // + hueDelta;
//转换回rgb
hsvToRgb(rgb,hsv);
// store
data [i] = rgb [0];
data [i + 1] = rgb [1];
data [i + 2] = rgb [2];
}
}
ctx2.putImageData(imgData,0,0);
return cv2;
}

编辑:
要获得色相,我consoled.log hues ... ;-)但许多(如果不是全部)
图像软件有一个颜色选择器显示hsl。

对于hsl,我没有特定的链接。 google it,并在图形软件中玩


为了避免编码噩梦,我想你必须决定一个约定
在你使用的纹理,如他们是60 +/- 5色相或类似。所以,你只有
必须决定你的游戏中的最终色调。检测可能很棘手。


I have product images and each image has two configurable areas as below: 1. background 2. Foreground

I have to develop a feature where customer can change the color of both areas and save the design.

My problem is, i am traversing the image to read old pixel value and change it with new selected color.

Bit old pixel values are not consistent. There is textured effect on the image, which is causing the pixel value to be changed at every pixel.

How can i achieve the desired the functionality?

or, if you can suggest me any other approach, that will be great.

sample image link: http://developersbench.com/canvas/img/design_2.jpg

解决方案

If i guess right, what you want is to change the pixels that are 'near' from a given color to be changed into another color.

Easiest way i see is to use h,s,l color space : in this 'natural' color space, colors that have a similar hue will be similarly perceived by the eye. And you can just 'shift' the hue, while keeping same saturation (== color 'strength'), and lightness.

So process your image point by point :
• Convert point r, g, b to hue, saturation, lightness
• ? Is the current hue near enough from sourceHue ?
---->> shift it to newHue (keeping same saturation / lightness)

fiddle is here :

http://jsfiddle.net/9GLNP/

You can play around with parameters. The texture you provided has 18 avg hue, so if the source hue is too far from 18, no changes will be done. 8-10 seems a good tolerance.

// Provides a new canvas containing [img] where
// all pixels having a hue less than [tolerance] 
// distant from [tgtHue] will be replaced by [newHue]
function shiftHue(img, tgtHue, newHue, tolerance) {
    // normalize inputs
    var normalizedTargetHue = tgtHue / 360;
    var normalizedNewHue = newHue / 360;
    var normalizedTolerance = tolerance / 360;
    // create output canvas
    var cv2 = document.createElement('canvas');
    cv2.width = img.width;
    cv2.height = img.height;
    var ctx2 = cv2.getContext('2d');
    ctx2.drawImage(img, 0, 0);
    // get canvad img data 
    var imgData = ctx2.getImageData(0, 0, img.width, img.height);
    var data = imgData.data;
    var lastIndex = img.width * img.height * 4;
    var rgb = [0, 0, 0];
    var hsv = [0.0, 0.0, 0.0];
    // loop on all pixels
    for (var i = 0; i < lastIndex; i += 4) {
        // retrieve r,g,b (! ignoring alpha !) 
        var r = data[i];
        var g = data[i + 1];
        var b = data[i + 2];
        // convert to hsv
        RGB2HSV(r, g, b, hsv);
        // change color if hue near enough from tgtHue
        var hueDelta = hsv[0] - normalizedTargetHue;
        if (Math.abs(hueDelta) < normalizedTolerance) {
            // adjust hue
            // ??? or do not add the delta ???
            hsv[0] = normalizedNewHue  //+ hueDelta;
            // convert back to rgb
            hsvToRgb(rgb, hsv);
            // store
            data[i] = rgb[0];
            data[i + 1] = rgb[1];
            data[i + 2] = rgb[2];
        }
    }
    ctx2.putImageData(imgData, 0, 0);
    return cv2;
}

EDIT : To get the hue, i consoled.log the hues... ;-) But many (if not all) image software have a color picker that shows hsl.
For hsl, i have no specific links. google it, and also play with it within a graphic software.
To avoid coding nightmare, i guess you have to decide of a convention on the textures you use, like they are 60 +/- 5 hue or like. So then you only have to decide of the final hue in your game. Detection might be tricky.

这篇关于Javascript画布像素操纵的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆