【发布时间】:2012-04-09 21:44:04
【问题描述】:
C# 中有什么方法可以在不影响其纹理的情况下替换图像某些部分的颜色?
您可以看到很好的结果示例here
谢谢
【问题讨论】:
标签: c# image-processing
C# 中有什么方法可以在不影响其纹理的情况下替换图像某些部分的颜色?
您可以看到很好的结果示例here
谢谢
【问题讨论】:
标签: c# image-processing
有效替换颜色的一种方法是使用重映射表。在以下示例中,在图片框内绘制了图像。在 Paint 事件中,颜色 Color.Black 更改为 Color.Blue:
private void pictureBox_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
using (Bitmap bmp = new Bitmap("myImage.png"))
{
// Set the image attribute's color mappings
ColorMap[] colorMap = new ColorMap[1];
colorMap[0] = new ColorMap();
colorMap[0].OldColor = Color.Black;
colorMap[0].NewColor = Color.Blue;
ImageAttributes attr = new ImageAttributes();
attr.SetRemapTable(colorMap);
// Draw using the color map
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
g.DrawImage(bmp, rect, 0, 0, rect.Width, rect.Height, GraphicsUnit.Pixel, attr);
}
}
更多信息:http://msdn.microsoft.com/en-us/library/4b4dc1kz%28v=vs.110%29.aspx
【讨论】:
在进行研究时,我发现没有有效/平滑的方法,所以我自己不这样做,代码可以清理很多,但它可以完成工作,它效率不高,但它更流畅,并允许您设置容忍度。
public static Image ColorReplace(this Image inputImage, int tolerance, Color oldColor, Color NewColor)
{
Bitmap outputImage = new Bitmap(inputImage.Width, inputImage.Height);
Graphics G = Graphics.FromImage(outputImage);
G.DrawImage(inputImage, 0, 0);
for (Int32 y = 0; y < outputImage.Height; y++)
for (Int32 x = 0; x < outputImage.Width; x++)
{
Color PixelColor = outputImage.GetPixel(x, y);
if (PixelColor.R > oldColor.R - tolerance && PixelColor.R < oldColor.R + tolerance && PixelColor.G > oldColor.G - tolerance && PixelColor.G < oldColor.G + tolerance && PixelColor.B > oldColor.B - tolerance && PixelColor.B < oldColor.B + tolerance)
{
int RColorDiff = oldColor.R - PixelColor.R;
int GColorDiff = oldColor.G - PixelColor.G;
int BColorDiff = oldColor.B - PixelColor.B;
if (PixelColor.R > oldColor.R) RColorDiff = NewColor.R + RColorDiff;
else RColorDiff = NewColor.R - RColorDiff;
if (RColorDiff > 255) RColorDiff = 255;
if (RColorDiff < 0) RColorDiff = 0;
if (PixelColor.G > oldColor.G) GColorDiff = NewColor.G + GColorDiff;
else GColorDiff = NewColor.G - GColorDiff;
if (GColorDiff > 255) GColorDiff = 255;
if (GColorDiff < 0) GColorDiff = 0;
if (PixelColor.B > oldColor.B) BColorDiff = NewColor.B + BColorDiff;
else BColorDiff = NewColor.B - BColorDiff;
if (BColorDiff > 255) BColorDiff = 255;
if (BColorDiff < 0) BColorDiff = 0;
outputImage.SetPixel(x, y, Color.FromArgb(RColorDiff, GColorDiff, BColorDiff));
}
}
return outputImage;
}
【讨论】:
试试这个:
Color color = Color.Black; //Your desired colour
byte r = color.R; //For Red colour
Bitmap bmp = new Bitmap(this.BackgroundImage);
for (int x = 0; x < bmp.Width; x++)
{
for (int y = 0; y < bmp.Height; y++)
{
Color gotColor = bmp.GetPixel(x, y);
gotColor = Color.FromArgb(r, gotColor.G, gotColor.B);
bmp.SetPixel(x, y, gotColor);
}
}
【讨论】:
GetPixel 很慢,见:stackoverflow.com/questions/4235731/…
找到了方法,这需要 RGBHSL 转换(可以找到 HSL 颜色的好类 here)
1. 获取代表您要替换的颜色的参考值(以 hsl 为单位)
2. 获取目标颜色的 hsl 值
3. 获取图像像素和每个像素:
4.计算像素的hsl值,替换为(pixelHsl / refHsl) * targetHsl
这为我完成了工作,感谢所有帮助过的人
【讨论】:
尝试读出所有像素并将它们填充到一个 3 数组 (rgb) 中,您可以设置一个算法来替换您的颜色。
【讨论】: