Заменить цвет в изображении в С#

Каким образом в С# можно заменить цвет для некоторых частей изображения, не влияя на его текстуру?

Вы можете увидеть хороший пример результата здесь Благодаря

5 ответов

Нашел способ сделать это, для этого нужны преобразования RGB ↔ HSL (хороший класс для цвета HSL можно найти здесь) 1. Получить опорное значение (в HSL), представляющий цвет, который вы хотите заменить 2. Получите значение hsl для целевого цвета 3. Получите пиксели изображения и для каждого пикселя: 4. вычислите значение hsl пикселя и замените его (pixelHsl/refHsl) * targetHsl

Это помогло мне, спасибо всем, кто помог


Одним из способов эффективной замены цвета является использование таблицы переназначения. В следующем примере изображение рисуется внутри поля изображения. В событии 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 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


попробуйте следующее:

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);
 }
}


Попробуйте прочитать все пиксели и наполнить их в массиве 3 (rgb), где вы можете установить в alogrithm, чтобы заменить ваши цвета.


После исследования я не нашел эффективного /smoothe способа сделать это, поэтому я не делаю этого сам, код можно очистить ALOT, но он выполняет свою работу, неэффективен, но он более плавный и позволяет вам установить допуск.

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;
 }

licensed under cc by-sa 3.0 with attribution.