【问题标题】:Create real grayscale images using C#使用 C# 创建真正的灰度图像
【发布时间】:2015-11-04 19:13:31
【问题描述】:

我正在尝试创建一个真正的灰度图像,但是当我的设计师检查文件时,他说图像仍然是 RGB。

您可以在此处查看 Photoshop 打印:

目前我已经尝试了两种方法:

1) 使用 MakeGrayScale3 方法:

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

        //get a graphics object from the new image
        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
        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);

        //dispose the Graphics object
        g.Dispose();
        return newBitmap;
    }

2) 通过以下代码使用 ImageMagick.Net 库:

                            using (MagickImage image = new MagickImage(file))
                            {
                                image.ColorSpace = ColorSpace.GRAY;

                                image.Write(originalFile);
                            }

如果有人之前遇到过这个问题,或者知道如何改变它..

谢谢!

原图:

结果图像(ImageMagick):

结果图像(MakeGrayscale3):

【问题讨论】:

  • 你使用的是什么文件格式,他是如何检查图像的(我看不到你的截图)? Photoshop 有一些图像配置文件,对于 jpeg 文件,这些配置文件始终是 RGB,即使它只包含灰色阴影。如果是 Photoshop,那么我认为您需要将文件另存为 .PSD 文件并以某种方式设置配置文件以使其显示为灰度图像。
  • 你能发布结果图像吗?我想尝试用 Matlab 或其他软件打开它,以确保它是 RGB 的图像,而不是告诉你是 RGB 的 PS。
  • 他在 Photoshop(我已经添加了屏幕截图)和 FastStone Photo Resizer(光度选项)上检查图像。
  • 我刚刚用最新版本尝试了你的 Magick.NET 示例,我得到了一张只有一个通道并且是灰色的图像。您使用的是最新版本的 Magick.NET 吗?

标签: c# image image-processing


【解决方案1】:

jpeg isn't available 在经典的System.Drawing 类中使用的灰度格式。但是,它在System.Windows.Media 中可用。您需要添加 PresentationCoreWindowsBase 作为使用它们的参考(这在 Linux 上不可移植)。

public static void SaveAsGrayscaleJpeg(String loadPath, String savePath)
{
    using (FileStream fs = new FileStream(savePath, FileMode.Create))
    {
        BitmapSource img = new BitmapImage(new Uri(new FileInfo(loadPath).FullName));
        FormatConvertedBitmap convertImg = new FormatConvertedBitmap(img, PixelFormats.Gray8, null, 0);
        JpegBitmapEncoder encoder = new JpegBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(convertImg));
        encoder.Save(fs);
    }
}

作为奖励,它会自动进行灰度转换。

如果您实际上是从Image/Bitmap 类开始,则有some solutions around 用于在它们之间进行转换。

另外你应该注意:

【讨论】:

    【解决方案2】:

    感谢所有答案,但在阅读了 Hans 在那里提到的主题后,他们谈到了我用来解决问题的 FreeImageNET 库。

    使用此代码,我设法将图像保存为灰度图像:

    FreeImageAPI.FreeImage.ConvertTo8Bits(newimg)
    

    【讨论】:

    • 查看该方法的文档,它只会为您提供调色板(索引)图像,而不是 jpeg 8 位灰度格式。
    【解决方案3】:

    问题是这一行:

    Bitmap newBitmap = new Bitmap(original.Width, original.Height);
    

    如果您查看MSDN page,它会说:

    此构造函数创建一个 PixelFormat 枚举值为 Format32bppArgb 的位图。

    所以,您只是在创建另一个彩色图像。您需要做的是使用a different constructor 强制使用不同的格式:

    Bitmap newBitmap = new Bitmap( original.Width, original.Height,
                                   PixelFormat.Format8bppIndexed );
    

    但这又给您带来了另一个问题 - 您无法使用Graphics 对象绘制具有该像素格式的位图。有一个 PixelFormat.Format16bppGrayScale 似乎工作得更少。

    所以,我的建议是手动进行。使用LockBits 访问原始位图并自己进行转换。这有点多工作(即你不能使用ColorMatrix 的东西,你必须注意检查源位图是 24 位还是 32 位),但它会工作得很好。

    需要注意的一个问题是它不是“真正的”灰度格式,它是 8 位索引的。因此,您还必须创建一个调色板。只需将 256 个值中的每一个映射到相同的值,即 0 -> 0、100 -> 100、255 -> 255。

    【讨论】:

    • 实际上,灰度 jpeg 本身就是一种格式。它不仅仅是 8 位索引。
    • @Nyerguds 当然。不幸的是,System.Drawing.Imaging.PixelFormat 中没有这种格式。
    • System.Windows.Media.PixelFormats ;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-29
    • 2012-09-09
    • 1970-01-01
    • 2015-05-30
    • 2015-10-26
    相关资源
    最近更新 更多