2017-10-29 175 views
-2

在构造如何更改方法,以便在黑色背景上创建位图图像白色?

Bitmap bitmap = new Bitmap(@"I:\test\Untitled3.jpg");); 
Bitmap GrayScaleBitmap = GrayScale(bitmap); 

而且方法灰度:

private Bitmap GrayScale(Bitmap bmp) 
    { 
     //get image dimension 
     int width = bmp.Width; 
     int height = bmp.Height; 

     //color of pixel 
     System.Drawing.Color p; 

     //grayscale 
     for (int y = 0; y < height; y++) 
     { 
      for (int x = 0; x < width; x++) 
      { 
       //get pixel value 
       p = bmp.GetPixel(x, y); 

       //extract pixel component ARGB 
       int a = p.A; 
       int r = p.R; 
       int g = p.G; 
       int b = p.B; 

       //find average 
       int avg = (r + g + b)/3; 

       //set new pixel value 
       bmp.SetPixel(x, y, System.Drawing.Color.FromArgb(a, avg, avg, avg)); 
      } 
     } 

     return bmp; 
    } 

这是原始图像我在油漆做了测试:

而结果我” m得到GrayScale:

​​

红色的形状现在是白色背景上的黑色。 但是,我想要红色的形状在黑色背景上是白色的,这就是我不知道如何改变GrayScale方法。

+1

这个问题是移动,几乎不挽救目标。 – wp78de

回答

0

你正在做的是灰度正确的。你想要的是灰度和反转的组合。

鉴于RGB以[0 - 255]的比例运行,您需要使用它来反转当前颜色。我会建议进行以下更改;

int avg = 255 - ((r + g +b)/3)

哪些应该达到你以后。

为了说明这是为什么起作用的;
白色是255,255,255 黑色为0,0,0

所以255 - ((255 + 255 + 255)/ 3)= 0(即,白色变为黑色)。

+1

_“你正在做的是灰度正确的”_ - 这是值得商榷的。该算法将为给定的RGB颜色计算有效的灰色。但从人类认知角度来看,OP的实施并不正确。也就是说,真正的“灰度”图像就是各种颜色的人眼所感知的光度值,而不是三个RGB分量的直线平均值。当然,在OP和你的部件上的这个错误不会影响整个问题的反转计算的意义,但恕我直言,了解错误的代码很重要。 –

+0

好吧,我再次测试了一下,我需要的是让背景变成白色,而我画的形状变成黑色。即使我画黄色的油漆背景和棕色的形状,最终的结果应该是白色背景和黑色的形状。 –

+0

你的问题说:“......黑色背景上的白色。”哪个是对的? – Trent

0

我想要背景是白色的,我画的形状是黑色。

要做到这一点,您avg(灰度)值转换成0/1,255。

//find white-black value 
int bw = (r + g + b)/384; // or /3/128 if you prefer 
//set new pixel value 
bmp.SetPixel(x, y, System.Drawing.Color.FromArgb(a, bw*255, bw*255, bw*255)); 

它给你一个纯粹的黑色和白色图像乘:

enter image description here

即使我在黄色背景上画一个棕色形状,最后的 结果应该是黑色在白色背景上的形状。

我建议的方法涵盖了这个要求,但某些“threshold”(例如在Photoshop中)对于某些色调是必需的。

int threshold = 128; // [1-254] 
//find avg value [0-255] 
int wb = (r + g + b)/3; 
//transform avg to [0-1] using threshold 
wb = (wb >= threshold) ? 1 : 0; 
//set new pixel value 
bmp.SetPixel(x, y, System.Drawing.Color.FromArgb(a, wb*255, wb * 255, wb * 255)); 

如果阈值太小,您的结果将全部为白色,或者如果阈值为0大全黑色。在边界情况下,您也可能会变形形状/背景(如在图像编辑器中)。值128将颜色空间均匀分开(如我的原始算法一样)。

答:使用阈值70与黄色输入棕色。 B:使用阈值60,输入黄色的输入为褐色。
enter image description here

完整的源代码:

using System.Drawing; 
using System.Drawing.Imaging; 
using System.IO; 
using System.Windows.Forms;  

namespace BwImgSO 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Bitmap bitmap = new Bitmap(@"C: \Users\me\Desktop\color.jpg"); 
      Bitmap grayScaleBitmap = GrayScale(bitmap); 
      string outputFileName = @"C: \Users\me\Desktop\bw.jpg"; 
      using (MemoryStream memory = new MemoryStream()) 
      { 
       using (FileStream fs = new FileStream(outputFileName, FileMode.Create, FileAccess.ReadWrite)) 
       { 
        grayScaleBitmap.Save(memory, ImageFormat.Jpeg); 
        byte[] bytes = memory.ToArray(); 
        fs.Write(bytes, 0, bytes.Length); 
       } 
      } 
     } 

     private static Bitmap GrayScale(Bitmap bmp) 
     { 
      //get image dimension 
      int width = bmp.Width; 
      int height = bmp.Height; 
      int threshold = 128; 

      //color of pixel 
      System.Drawing.Color p; 

      //grayscale 
      for (int y = 0; y < height; y++) 
      { 
       for (int x = 0; x < width; x++) 
       { 
        //get pixel value 
        p = bmp.GetPixel(x, y); 

        //extract pixel component ARGB 
        int a = p.A; 
        int r = p.R; 
        int g = p.G; 
        int b = p.B; 

        //find average, transform to b/w value 
        //int bw = (r + g + b)/3/128; // or 384 if you prefer 
        int wb = (r + g + b)/3; // avg: [0-255] 
        //transform avg to [0-1] using threshold 
        wb = (wb >= threshold) ? 1 : 0; 
        //set new pixel value 
        bmp.SetPixel(x, y, System.Drawing.Color.FromArgb(a, bw*255, bw*255, bw*255)); 
       } 
      } 

      return bmp; 
     } 
    } 
} 
相关问题