将图像转换为灰度
c#
image-processing
4
0

有没有一种方法可以将图像转换为每像素格式16位灰度,而不是将r,g和b分量分别设置为亮度。我目前有一个文件bmp。

Bitmap c = new Bitmap("filename");

我想要一个位图d,它是c的灰度版本。我确实看到了一个包含System.Drawing.Imaging.PixelFormat的构造函数,但我不知道如何使用它。我是图像处理和相关C#库的新手,但是对C#本身有一定的经验。

任何帮助,参考在线资源,提示或建议,将不胜感激。

编辑:d是c的灰度版本。

参考资料:
Stack Overflow
收藏
评论
共 6 个回答
高赞 时间 活跃

“我想要一个灰度的Bitmap d。我确实看到了一个包含System.Drawing.Imaging.PixelFormat的构造器,但我不知道如何使用它。”

这是怎么做的

Bitmap grayScaleBP = new 
         System.Drawing.Bitmap(2, 2, System.Drawing.Imaging.PixelFormat.Format16bppGrayScale);

编辑:转换为灰度

             Bitmap c = new Bitmap("fromFile");
             Bitmap d;
             int x, y;

             // Loop through the images pixels to reset color.
             for (x = 0; x < c.Width; x++)
             {
                 for (y = 0; y < c.Height; y++)
                 {
                     Color pixelColor = c.GetPixel(x, y);
                     Color newColor = Color.FromArgb(pixelColor.R, 0, 0);
                     c.SetPixel(x, y, newColor); // Now greyscale
                 }
             }
            d = c;   // d is grayscale version of c  

来自switchonthecode的 Faster版本,请点击以下链接进行全面分析:

public static Bitmap MakeGrayscale3(Bitmap original)
{
   //create a blank bitmap the same size as original
   Bitmap newBitmap = new Bitmap(original.Width, original.Height);

   //get a graphics object from the new image
   using(Graphics g = Graphics.FromImage(newBitmap)){

       //create the grayscale ColorMatrix
       ColorMatrix colorMatrix = new ColorMatrix(
          new float[][] 
          {
             new float[] {.3f, .3f, .3f, 0, 0},
             new float[] {.59f, .59f, .59f, 0, 0},
             new float[] {.11f, .11f, .11f, 0, 0},
             new float[] {0, 0, 0, 1, 0},
             new float[] {0, 0, 0, 0, 1}
          });

       //create some image attributes
       using(ImageAttributes attributes = new ImageAttributes()){

           //set the color matrix attribute
           attributes.SetColorMatrix(colorMatrix);

           //draw the original image on the new image
           //using the grayscale color matrix
           g.DrawImage(original, new Rectangle(0, 0, original.Width, original.Height),
                       0, 0, original.Width, original.Height, GraphicsUnit.Pixel, attributes);
       }
   }
   return newBitmap;
}
收藏
评论
Bitmap d = new Bitmap(c.Width, c.Height);

for (int i = 0; i < c.Width; i++)
{
    for (int x = 0; x < c.Height; x++)
    {
        Color oc = c.GetPixel(i, x);
        int grayScale = (int)((oc.R * 0.3) + (oc.G * 0.59) + (oc.B * 0.11));
        Color nc = Color.FromArgb(oc.A, grayScale, grayScale, grayScale);
        d.SetPixel(i, x, nc);
    }
}

这样,它也保留了Alpha通道。
请享用。

收藏
评论

ToolStripRenderer类中有一个静态方法,名为CreateDisabledImage 。它的用法很简单:

Bitmap c = new Bitmap("filename");
Image d = ToolStripRenderer.CreateDisabledImage(c);

它使用的矩阵与接受的答案中的矩阵略有不同,并且将其乘以0.7的透明度,因此效果与仅灰度略有不同,但是如果您只想使图像变灰,这是最简单且最好的解决方案。

收藏
评论

这里总结一些项目:有一些逐个像素的选项,尽管简单,但速度并不快。

@路易斯的评论链接到:(存档) https://web.archive.org/web/20110827032809/http://www.switchonthecode.com/tutorials/csharp-tutorial-convert-a-color-image-to-灰度极好。

他介绍了三个不同的选项,并为每个选项提供了时间。

收藏
评论

上面的示例均未创建8位(8bpp)位图图像。某些软件(例如图像处理)仅支持8bpp。不幸的是,MS .NET库没有解决方案。 PixelFormat.Format8bppIndexed格式看起来很有希望,但是经过很多尝试后我还是无法正常工作。

要创建真正的8位位图文件,您需要创建适当的标头 。最终,我找到了用于创建8位位图(BMP)文件的Grayscale库解决方案。代码很简单:

Image image = Image.FromFile("c:/path/to/image.jpg");
GrayBMP_File.CreateGrayBitmapFile(image, "c:/path/to/8bpp/image.bmp");

这个项目的代码远非漂亮,但它可以工作,但有一个简单易解决的问题。作者将图像分辨率硬编码为10x10。图像处理程序不喜欢这样。该修复程序是打开的GrayBMP_File.cs(是的,时髦的文件命名,我知道),并用下面的代码替换第50和51行。该示例将分辨率设置为200x200,但是您应该将其更改为适当的数字。

int resX = 200;
int resY = 200;
// horizontal resolution
Copy_to_Index(DIB_header, BitConverter.GetBytes(resX * 100), 24);
// vertical resolution 
Copy_to_Index(DIB_header, BitConverter.GetBytes(resY * 100), 28);
收藏
评论

下面的代码是最简单的解决方案:

Bitmap bt = new Bitmap("imageFilePath");

for (int y = 0; y < bt.Height; y++)
{
    for (int x = 0; x < bt.Width; x++)
    {
        Color c = bt.GetPixel(x, y);

        int r = c.R;
        int g = c.G;
        int b = c.B;
        int avg = (r + g + b) / 3;
        bt.SetPixel(x, y, Color.FromArgb(avg,avg,avg));
    }   
}

bt.Save("d:\\out.bmp");
收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号