【问题标题】:replace color in an image in c#在c#中替换图像中的颜色
【发布时间】:2012-04-09 21:44:04
【问题描述】:

C# 中有什么方法可以在不影响其纹理的情况下替换图像某些部分的颜色?

您可以看到很好的结果示例here
谢谢

【问题讨论】:

    标签: c# image-processing


    【解决方案1】:

    有效替换颜色的一种方法是使用重映射表。在以下示例中,在图片框内绘制了图像。在 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

    【讨论】:

      【解决方案2】:

      在进行研究时,我发现没有有效/平滑的方法,所以我自己不这样做,代码可以清理很多,但它可以完成工作,它效率不高,但它更流畅,并允许您设置容忍度。

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

      【讨论】:

      • 我发现如果不删除“this”就无法使用它,然后它没有任何错误发生但是如何实现这个例子?
      • 像魅力一样工作!,tyvm。
      • 图片尺寸相同但略有改进:codeproject.com/Articles/42869/Color-Replacer
      【解决方案3】:

      试试这个:

      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/…
      • 是的,不是很快,但是对于小图像的颜色变化非常有效。
      • 改变图像颜色的一个问题是没有选择性。即,在图像中,您想在某个部分将黑色变为红色,这是不可能的。例如,如果您想在人物图像中将头发的颜色更改为红色,那么这是不可能的。无论它们出现在图像中的哪个位置,它都会用红色替换所有黑色像素。
      • 您可以通过 X 和 Y 检查图像的各个部分,以便并非所有包含红色的部分都变为黑色,但我同意您的观点,它不会 100% 准确跨度>
      • 谢谢,我认为这应该是从源到目标的某种颜色范围/调色板操作,但我不知道这样做的方法是什么......
      【解决方案4】:

      找到了方法,这需要 RGBHSL 转换(可以找到 HSL 颜色的好类 here
      1. 获取代表您要替换的颜色的参考值(以 hsl 为单位)
      2. 获取目标颜色的 hsl 值
      3. 获取图像像素和每个像素:
      4.计算像素的hsl值,替换为(pixelHsl / refHsl) * targetHsl

      这为我完成了工作,感谢所有帮助过的人

      【讨论】:

      • 是的,它就像一个魅力。你能评论一下为什么吗?
      • 你能写出你用来替换它的代码是什么吗?
      【解决方案5】:

      尝试读出所有像素并将它们填充到一个 3 数组 (rgb) 中,您可以设置一个算法来替换您的颜色。

      【讨论】:

      • 嗨,谢谢 - 但这与我的需要无关。我真正需要的是在图像中应用替换颜色以保持纹理
      • 那是一样的,质地只是颜色的变化。像蓝天和白云可以是紫色的天空和更深的紫色云或类似的东西。
      猜你喜欢
      • 2010-12-05
      • 2011-07-19
      • 2018-05-11
      • 1970-01-01
      • 2010-12-09
      • 2013-01-12
      • 1970-01-01
      • 2020-10-07
      • 1970-01-01
      相关资源
      最近更新 更多