改变图像的色调更快的方法? [英] Faster method of changing an image hue?

查看:158
本文介绍了改变图像的色调更快的方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有更好的方法来改变图像的色调如顺利通过我一个滑动的TrackBar?我在做什么是获得每个像素的RGB值,计算饱和度,然后亮度把值。图像的大小影响的色调被更新的速度。 Photoshop的图像色调功能改变了从0到360顺利色调这是我想尝试并获得什么。

 数据= editImage .LockBits(新矩形(0,0,editWidth,editHeight)
ImageLockMode.ReadWrite,PixelFormat.Format24bppRgb);
字节* dataPtr =(BYTE *)data.Scan0;
H = trackBar1.Value / 60.0;
D = 1 - Math.Abs​​((H%2) - 1);如果

(H> = 0&放大器;&安培; H< 1)
{
的for(int i = 0; I< editHeight;我++)
{
offsetStride = I * data.Stride;
为(INT J = 0; J< editWidth; J ++)
{
蓝色= dataPtr [(J * 3)+ offsetStride];
绿色= dataPtr [(J * 3)+ offsetStride + 1];
红色= dataPtr [(J * 3)+ offsetStride + 2];

如果(绿色>蓝色)最大=绿色;
,否则最大=蓝色;
如果(红色>最大)最大=红色;

如果(绿色<蓝色)分=绿色;
,否则分钟=蓝色;
如果(红色<分)分=红色;

S =(最大== 0)? 0:1D - (1D *最小/最大);
)(V =最大值/ 255D;

C = V * S;
X = C * D;
é= V - ℃;

dataPtr [(J * 3)+ offsetStride] =(字节)(分钟);
dataPtr [(J * 3)+ offsetStride + 1] =(字节)((X + E)* 255);
dataPtr [(J * 3)+ offsetStride + 2] =(字节)(最大);
}
}
}


解决方案

如果你想改变色相那么最有效的方法是产生红,黄,绿,青,蓝,洋红图像,并在必要时之间插入一个黑白图像。



所以要产生10%的旋转图像您会增加50/60 *红色+ 10/60 *黄色显示。



在事实上,你并不真的需要生成所有6张图片。这将是足够的,以产生红色和黄色图像。其他可以产生上飞,因为,例如,在蓝色的图像仅仅是红色图象,但与红色和蓝色像素交换(并且甚至可以得到从红色的黄色)。但它也许是最简单的开始与6图像,然后后来添加的优化。



生成初始彩色图像中的一个代码是类似于你有什么上面(在乍看之下),但HSV到RGB的最后一步看起来有点可疑 - 维基百科页面善于解释这一点(这是可能的C#包含一个库函数来完成这种转换)



[鉴于你澄清,下面是不相关的,你在做什么]



如果你想色调,逐个像素移位(所以红魔的举动到黄色作为绿色移到青色),那么您会通过首先对整个图像转换到HSV,然后从该工作节省一些时间。



您可能节省更多的时间(通过生成多个图像(比如每10度旋转色调),然后在它们之间插入移色调时)。但它比单色情况比较复杂,因为有些像素(那些它通过60度插补时多色调移动)需要特殊对待。所以,你还需要预先检测这些,然后计算它们的飞行。有一个折衷,在您有多个中间图像,更少的像素需要特殊情况。并在实践中产生独立的图像懒洋洋地(需求)是要给更快的启动,因为通常人们只作小的修改。


Is there a better method to change the hue of an image smoothly as I slide through a trackbar? What I'm doing is getting the RGB value per pixel, calculating the saturation and brightness then putting the values in. The size of the image affects the speed the hue is updated. Photoshop's image hue function changes the hue from 0 to 360 smoothly which is what I want to try and get to.

data = editImage.LockBits(new Rectangle(0, 0, editWidth, editHeight), 
ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
byte* dataPtr = (byte*)data.Scan0;
h = trackBar1.Value / 60.0;
D = 1 - Math.Abs((h % 2) - 1);

if (h >= 0 && h < 1)
{
    for (int i = 0; i < editHeight; i++)
    {
        offsetStride = i * data.Stride;
        for (int j = 0; j < editWidth; j++)
        {
            blue = dataPtr[(j * 3) + offsetStride];
            green = dataPtr[(j * 3) + offsetStride + 1];
            red = dataPtr[(j * 3) + offsetStride + 2];

            if (green > blue) max = green;
            else max = blue;
            if (red > max) max = red;

            if (green < blue) min = green;
            else min = blue;
            if (red < min) min = red;

            s = (max == 0) ? 0 : 1d - (1d * min / max);
            v = max / 255d;

            C = v * s;
            X = C * D;
            E = v - C;

            dataPtr[(j * 3) + offsetStride] = (byte)(min);
            dataPtr[(j * 3) + offsetStride + 1] = (byte)((X + E) * 255);
            dataPtr[(j * 3) + offsetStride + 2] = (byte)(max);
        }
    }
}

解决方案

If you want a monochrome image that changes hue then the most efficient method would be to generate red, yellow, green, cyan, blue and magenta images and interpolate between them as necessary.

So to generate an image at 10% rotation you would add 50/60 * red + 10/60 * yellow and display that.

In fact, you don't really need to generate all 6 images. It would be enough to generate the red and yellow images. The others you can generate on the fly, because, for example, the blue image is just the red image, but with the red and blue pixels swapped (and you could even derive the yellow from the red). But it's perhaps simplest to start with 6 images and then add that optimisation later.

The code to generate one of the initial coloured images is similar to what you have above (at first glance), but your final step from HSV to RGB looks a little suspect - the wikipedia pages are good at explaining this (and it's possible C# contains a library function to do this conversion).

[Given your clarification, below is not relevant to what you are doing]

If you want to shift the hue, pixel by pixel (so reds move to yellow as greens move to cyan) then you would save some time by first converting the entire image to HSV, and then working from that.

You might save more time (when shifting hue) by generating multiple images (say every 10 degrees rotated in hue) and then interpolating between them. But it's more complex than the monochrome case, because some pixels (those for which hue moves through a multiple of 60 degrees during the interpolation) need special treatment. So you also need to pre-detect those and then calculate them on the fly. There's a trade-off, in that the more intermediate images you have, the less pixels you need to special-case. And in practice generating the separate images lazily (on demand) is going to give quicker startup, because typically people only make small changes.

这篇关于改变图像的色调更快的方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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