C# &引用;着色“;NET中的位图
如果您有一个包含灰度图像的C# &引用;着色“;NET中的位图,c#,.net,image-processing,image-manipulation,system.drawing,C#,.net,Image Processing,Image Manipulation,System.drawing,如果您有一个包含灰度图像的System.Drawing.Bitmap实例,是否有一种内置的方法可以在另一种颜色的影响下对其进行“着色” 例如,如果你有一个咖啡杯的黑白(灰度)图片,你想以编程方式创建红色、绿色和紫色版本的单独图像。我会创建原始图像的副本,并将其放置在顶部所需颜色的单独半透明图像上 更新:参见中的示例 我过去用过这个。你想专门看看托塞皮亚。 您可能需要对其进行一点解构,但它对我很有用。我没有代码示例,但这里有一种方法可以做到这一点。将每个像素从RGB转换为HSV,并更改每个像素上的
System.Drawing.Bitmap
实例,是否有一种内置的方法可以在另一种颜色的影响下对其进行“着色”
例如,如果你有一个咖啡杯的黑白(灰度)图片,你想以编程方式创建红色、绿色和紫色版本的单独图像。我会创建原始图像的副本,并将其放置在顶部所需颜色的单独半透明图像上 更新:参见中的示例 我过去用过这个。你想专门看看托塞皮亚。
您可能需要对其进行一点解构,但它对我很有用。我没有代码示例,但这里有一种方法可以做到这一点。将每个像素从RGB转换为HSV,并更改每个像素上的色调和饱和度分量。色调控制颜色。该值应保持不变。结果将是一个明暗度相同但颜色不同的位图 编辑:这里有一个例子。请注意色调和饱和度的更新
public static Color ColorFromAhsb(int a, float h, float s, float b)
{
if (0 > a || 255 < a)
{
throw new Exception("a");
}
if (0f > h || 360f < h)
{
throw new Exception("h");
}
if (0f > s || 1f < s)
{
throw new Exception("s");
}
if (0f > b || 1f < b)
{
throw new Exception("b");
}
if (0 == s)
{
return Color.FromArgb(a, Convert.ToInt32(b * 255),
Convert.ToInt32(b * 255), Convert.ToInt32(b * 255));
}
float fMax, fMid, fMin;
int iSextant, iMax, iMid, iMin;
if (0.5 < b)
{
fMax = b - (b * s) + s;
fMin = b + (b * s) - s;
}
else
{
fMax = b + (b * s);
fMin = b - (b * s);
}
iSextant = (int)Math.Floor(h / 60f);
if (300f <= h)
{
h -= 360f;
}
h /= 60f;
h -= 2f * (float)Math.Floor(((iSextant + 1f) % 6f) / 2f);
if (0 == iSextant % 2)
{
fMid = h * (fMax - fMin) + fMin;
}
else
{
fMid = fMin - h * (fMax - fMin);
}
iMax = Convert.ToInt32(fMax * 255);
iMid = Convert.ToInt32(fMid * 255);
iMin = Convert.ToInt32(fMin * 255);
switch (iSextant)
{
case 1:
return Color.FromArgb(a, iMid, iMax, iMin);
case 2:
return Color.FromArgb(a, iMin, iMax, iMid);
case 3:
return Color.FromArgb(a, iMin, iMid, iMax);
case 4:
return Color.FromArgb(a, iMid, iMin, iMax);
case 5:
return Color.FromArgb(a, iMax, iMin, iMid);
default:
return Color.FromArgb(a, iMax, iMid, iMin);
}
}
private void Form1_Load(object sender, EventArgs e)
{
var bmp = new Bitmap("c:\\bw.bmp");
foreach (int y in Enumerable.Range(0, bmp.Height))
{
foreach (int x in Enumerable.Range(0,bmp.Width))
{
var p = bmp.GetPixel(x, y);
var h = p.GetHue();
var c = ColorFromAhsb(p.A, p.GetHue() + 200, p.GetSaturation() + 0.5f, p.GetBrightness());
bmp.SetPixel(x, y, c);
}
}
pictureBox1.Image = bmp;
//bmp.Dispose();
}
AHSB的公共静态颜色(int a、float h、float s、float b)
{
如果(0>a | | 255h | | 360f(1,1,1) "white" * (1,0,0) "red" = (1,0,0) "red"
(0.5,0.5, 0.5) "grey" * (0,1,0) "green" = (0,0.5,0) "dark green"
但是,您确实需要按像素应用此功能。如果是8位图像,您可以在调色板中使用不同的颜色(image.palete)。这本质上是一个查找表,为每个可能的像素字节值分配颜色值。比在循环中更改所有像素快得多。如何操作?您必须指定“调制”而不是添加类型的图层混合,对吗?谢谢。“HSV”方法为我提供了更好的外观效果-我不完全理解为什么:)谢谢。稍微修改一下效果会更好。“p.GetSaturation()+0.5f”的意义是什么?如果“着色”颜色本身是灰色,0.5似乎会把事情搞砸(输出为略带红色),但在其他情况下是必需的。@frou-在我使用的位图中,饱和度为0。如果饱和度为零,修改色调不会改变颜色。我只是在零值上添加了任意0.5。饱和度应为大于零且小于或等于1的任何值。