【问题标题】:How apply Color Lut over bitmap image in c#如何在 C# 中将 Color Lut 应用于位图图像
【发布时间】:2010-10-22 07:27:49
【问题描述】:

我正在打开不同类型的图像,例如(8 位和 16 位),它们是(单色、RGB、调色板颜色)。

我有这些图像的原始像素数据。 我为 8 位图像创建这样的位图。

          //for monocrome images i am passing PixelFormat.Format8bppIndexed.
          //for RGB images i am passing PixelFormat.Format24bppRgb
           PixelFormat format = PixelFormat.Format8bppIndexed;
           Bitmap bmp = new Bitmap(Img_Width, Img_Height,format);

           Rectangle rect = new Rectangle(0, 0, Img_Width, Img_Height);

           //locking the bitmap on memory
           BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, format);

           // copy the managed byte array to the bitmap's image data
           Marshal.Copy(rawPixel, 0, bmpData.Scan0, rawPixel.Length);
           bmp.UnlockBits(bmpData);

问题是,当我绘制该 bmp 图像时,它的颜色与原始图像不同。 那么有什么方法可以在彩色图像上应用 lut(查找表)。

我想要任何不安全的代码,因为我尝试了 getixel 和 setPixel,但它们非常慢。 我也不想要 Image.fromSource() 方法。

【问题讨论】:

    标签: c# imaging


    【解决方案1】:

    我解决了这个问题,看看如何。 我在某处读到 GDI+ 返回 BGR 值而不是 RGB。 所以我颠倒了顺序,一切都很好。 但是速度有点慢。

           PixelFormat format = PixelFormat.Format8bppIndexed;
           Bitmap bmp = new Bitmap(Img_Width, Img_Height,format);
    
           Rectangle rect = new Rectangle(0, 0, Img_Width, Img_Height);
    
           //locking the bitmap on memory
           BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, format);
           Marshal.Copy(rawPixel, 0, bmpData.Scan0, rawPixel.Length);
    
           int stride = bmpData.Stride;
           System.IntPtr Scan0 = bmpData.Scan0;
    
           unsafe
           {
               byte* p = (byte*)(void*)Scan0;
               int nOffset = stride - bmp.Width * SAMPLES_PER_PIXEL ;
               byte red, green, blue;
    
               for (int y = 0; y < bmp.Height; ++y)
                {
                    for (int x = 0; x < bmp.Width; ++x)
                    {
                        blue = p[0];
                        green = p[1];
                        red = p[2];
                        p[0] = red;
                        p[1] = green;
                        p[2] = blue;
                        p += 3;
                    }
                    p += nOffset;
                }
            }
    
            ////unlockimg the bitmap
            bmp.UnlockBits(bmpData);
    

    谢谢

    任何人都可以拥有比这更快的代码吗?

    【讨论】:

    • 嗨,它也只适用于 RGB 图像。因为 RGB 图像具有所有三个分量(R、G、B)。 PaletteColor 图像呢?我无法理解调色板图像中颜色的索引。有人处理调色板颜色图像吗?
    【解决方案2】:

    GetPixel 和 SetPixel 确实很慢。如果您想对单个像素进行操作,请考虑使用FastBitmap。它允许快速着色像素。使用这个不安全的位图会大大提高你的速度。

    【讨论】:

      【解决方案3】:

      据我所知,.NET 不支持 ICC 颜色配置文件,因此,例如,如果您打开使用 Adob​​eRGB 颜色配置文件的图像,与打开时相比,颜色会显得更暗淡且更“灰色”在 Photoshop 或其他颜色配置文件感知软件中使用相同的图像文件。

      This post discusses some color profile issues;你可能会在那里找到感兴趣的东西。

      【讨论】:

      • 我得到 image.Palette = 256 用于调色板彩色和单色图像。但是我怎样才能将这些调色板反映到图像中。因为图像看起来不正确。
      【解决方案4】:

      查看位图的Image.Palette 属性。

      【讨论】:

      • 我看到了,但对于 RGB 图像 Image.palette 为 0。对于单色和调色板彩色图像,我得到 Image.Palette = 256。但是对于调色板彩色图像,我如何分别获取 RGB 字节数组以及如何在 Image.Palette 上应用。我试过了,但假设原始图像是绿色的。我从我的代码中得到图像颜色紫罗兰色。如果我将采用单独的 RGB 并应用于 Image.palette,它是否会给出原始的绿色。谢谢
      • 我不知道您从哪里获取源数据,但您应该能够写入到调色板,因此:bmp.Palette.Entries[0] .r = red_value;等等。ImagePalette 是一个“ColorPalette”对象,而不仅仅是条目数。
      • 谢谢,ColorPalette 的第一个是密封类,所以你不能自己制作调色板。如果图像没有。 bmp.Palette 是一个属性。但是您不能在其上设置直接值。因为如果 bmp.Palette = 0 所以他们没有任何条目。因此,如果您尝试 bmp.Palette.Entries[i] 会给您超出限制的异常。如果要设置 bmp.Palette.Entries[i].R 是只读属性。
      猜你喜欢
      • 2021-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-28
      • 2021-06-17
      • 2018-07-29
      • 1970-01-01
      相关资源
      最近更新 更多