2017-10-29 103 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; 
     } 
    } 
} 
相關問題