C# 将图像转换为灰度
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2265910/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Convert an image to grayscale
提问by 0fnt
Is there a way to convert an image to grayscale 16 bits per pixel format, rather than setting each of the r,g and b components to luminance. I currently have a bmp from file.
有没有办法将图像转换为每像素 16 位的灰度格式,而不是将每个 r、g 和 b 分量设置为亮度。我目前有一个来自文件的 bmp。
Bitmap c = new Bitmap("filename");
I want a Bitmap d, that is grayscale version of c. I do see a constructor that includes System.Drawing.Imaging.PixelFormat, but I don't understand how to use that. I'm new to Image Processing and the relevant C# libraries, but have a moderate experience with C# itself.
我想要一个位图 d,即 c 的灰度版本。我确实看到了一个包含 System.Drawing.Imaging.PixelFormat 的构造函数,但我不明白如何使用它。我是图像处理和相关 C# 库的新手,但对 C# 本身有一定的经验。
Any help, reference to an online source, hint or suggestion will be appreciated.
任何帮助、参考在线资源、提示或建议将不胜感激。
EDIT: d is the grayscale version of c.
编辑:d 是 c 的灰度版本。
采纳答案by Asad
"I want a Bitmap d, that is grayscale. I do see a consructor that includes System.Drawing.Imaging.PixelFormat, but I don't understand how to use that."
“我想要一个位图 d,即灰度。我确实看到了一个包含 System.Drawing.Imaging.PixelFormat 的构造函数,但我不明白如何使用它。”
Here is how to do this
这是如何做到这一点
Bitmap grayScaleBP = new
System.Drawing.Bitmap(2, 2, System.Drawing.Imaging.PixelFormat.Format16bppGrayScale);
EDIT:To convert to grayscale
编辑:转换为灰度
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
Faster Version from switchonthecodefollow link for full analysis:
来自switchonthecode 的更快版本,请点击链接进行全面分析:
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;
}
回答by Vercas
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);
}
}
This way it also keeps the alpha channel.
Enjoy.
这样它也保持了 alpha 通道。
享受。
回答by Brent Matzelle
None of the examples above create 8-bit (8bpp) bitmap images. Some software, such as image processing, only supports 8bpp. Unfortunately the MS .NET libraries do not have a solution. The PixelFormat.Format8bppIndexedformat looks promising but after a lot of attempts I couldn't get it working.
上述示例均未创建 8 位 (8bpp) 位图图像。某些软件,例如图像处理,仅支持 8bpp。不幸的是,MS .NET 库没有解决方案。该PixelFormat.Format8bppIndexed格式看起来很有希望,但很多尝试后,我无法得到它的工作。
To create a true 8-bit bitmap file you need to create the proper headers. Ultimately I found the Grayscale librarysolution for creating 8-bit bitmap (BMP) files. The code is very simple:
要创建真正的 8 位位图文件,您需要创建正确的标题。最终我找到了用于创建 8 位位图 (BMP) 文件的灰度库解决方案。代码非常简单:
Image image = Image.FromFile("c:/path/to/image.jpg");
GrayBMP_File.CreateGrayBitmapFile(image, "c:/path/to/8bpp/image.bmp");
The code for this project is far from pretty but it works, with one little simple-to-fix problem. The author hard-coded the image resolution to 10x10. Image processing programs do not like this. The fix is open GrayBMP_File.cs (yeah, funky file naming, I know) and replace lines 50 and 51 with the code below. The example sets the resolution to 200x200 but you should change it to the proper number.
这个项目的代码远非漂亮,但它可以工作,有一个简单的小问题。作者将图像分辨率硬编码为 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);
回答by jeffreypriebe
To summarize a few items here: There are some pixel-by-pixel options that, while being simple just aren't fast.
在这里总结一些项目: 有一些逐像素选项,虽然简单但速度不快。
@Luis' comment linking to: (archived) https://web.archive.org/web/20110827032809/http://www.switchonthecode.com/tutorials/csharp-tutorial-convert-a-color-image-to-grayscaleis superb.
@Luis 的评论链接到:(存档)https://web.archive.org/web/20110827032809/http://www.switchonthecode.com/tutorials/csharp-tutorial-convert-a-color-image-to-灰度是极好的。
He runs through three different options and includes timings for each.
他遍历了三个不同的选项,并包括每个选项的时间。
回答by Prakash Ekhande
The code below is the simplest solution:
下面的代码是最简单的解决方案:
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");
回答by Szybki
There's a static method in ToolStripRenderer
class, named CreateDisabledImage
.
Its usage is as simple as:
类中有一个静态方法ToolStripRenderer
,名为CreateDisabledImage
. 它的用法很简单:
Bitmap c = new Bitmap("filename");
Image d = ToolStripRenderer.CreateDisabledImage(c);
It uses a little bit different matrix than the one in the accepted answer and additionally multiplies it by a transparency of value 0.7, so the effect is slightly different than just grayscale, but if you want to just get your image grayed, it's the simplest and best solution.
它使用与接受的答案中的矩阵略有不同的矩阵,并另外将其乘以值 0.7 的透明度,因此效果与灰度略有不同,但如果您只想让图像变灰,这是最简单的最佳解决方案。