4

我正在尝试编辑 8bpp 的像素。由于此 PixelFormat 已编入索引,因此我知道它使用颜色表来映射像素值。尽管我可以通过将位图转换为 24bpp 来编辑位图,但 8bpp 的编辑速度要快得多(13 毫秒对 3 毫秒)。但是,在访问 8bpp 位图时更改每个值会导致一些随机 rgb 颜色,即使 PixelFormat 仍然是 8bpp。

我目前正在用c#开发,算法如下:

(C#)

1- 以 8bpp 加载原始位图

2-创建与原始大小相同的 8bpp 空临时位图

两个位图的 3-LockBits,并使用 P/Invoke 调用 c++ 方法,其中我传递每个 BitmapData 对象的 Scan0。(我使用了 C++ 方法,因为它在遍历位图的像素时提供了更好的性能)

(C++)

4- 根据一些参数创建一个 int[256] 调色板,并通过将原始像素值传递给调色板来编辑临时位图字节。

(C#)

5-解锁比特。

我的问题是如何在没有奇怪的 rgb 颜色的情况下编辑像素值,或者更好地编辑 8bpp 位图的颜色表?

4

3 回答 3

11

根本不需要进入 C++ 领域或使用 P/Invoke;C# 完美支持指针和不安全代码;我什至可能会猜测这是导致您的问题的原因。

颜色可能来自默认调色板。您会发现更改 Palette 一点也不应该很慢。这就是我创建灰度调色板的方法:

image = new Bitmap( _size.Width, _size.Height, PixelFormat.Format8bppIndexed);
ColorPalette pal = image.Palette;
for(int i=0;i<=255;i++) {
    // create greyscale color table
    pal.Entries[i] = Color.FromArgb(i, i, i);
}
image.Palette = pal; // you need to re-set this property to force the new ColorPalette
于 2010-04-18T22:01:27.910 回答
4

想象一下,您的索引 8ppp graysacle 存储在线性数组 dataB 中(为了速度)

试试这个代码:

//Create 8bpp bitmap and look bitmap data
bmp = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
bmp.SetResolution(horizontalResolution, verticalResolution);
bmpData = bmp.LockBits(new Rectangle(0, 0, width, height), System.Drawing.Imaging.ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);

//Create grayscale color table
ColorPalette palette = bmp.Palette;
for (int i = 0; i < 256; i++)
    palette.Entries[i] = Color.FromArgb(i, i, i);
bmp.Palette = palette;

//write data to bitmap
int dataCount = 0;
int stride = bmpData.Stride < 0 ? -bmpData.Stride : bmpData.Stride;
unsafe
{
    byte* row = (byte*)bmpData.Scan0;
    for (int f = 0; f < height; f++)
    {
        for (int w = 0; w < width; w++)
        {
            row[w] = (byte)Math.Min(255, Math.Max(0, dataB[dataCount]));
            dataCount++;
        }
        row += stride;
    }
}

//Unlock bitmap data
bmp.UnlockBits(bmpData);
于 2016-08-29T17:32:35.263 回答
0

您是否尝试过加载 a System.Drawing.Image?该类使您可以访问调色板。然后,一旦设置了调色板,您就可以将其包裹System.Drawing.Image起来。System.Drawing.Bitmap

我不确定如何System.Drawing.BitMap.SetPixel()处理索引彩色图像。可能是它试图将其映射到调色板中最接近的颜色。

于 2010-04-07T15:14:19.807 回答