将调色板应用于图片

时间:2014-10-20 11:17:13

标签: c# compression color-palette

我需要为.img二进制图像文件制作压缩算法。图像是512x512。我正在使用BinaryReader逐个像素地获取二进制文件,我将其保存在short[,]中。它是这样的:

br1 = new BinaryReader(File.Open(openFileDialog1.FileName, FileMode.Open));
short[,] num = new short[512, 512];
for (int i = 0; i < 512; i++)
    for (int j = 0; j < 512; j++)
    {
         num[i, j] = (short)br1.ReadInt16();
    }

我不明白的是如何使用调色板(导入的.pal文件)将[-2048,2047]之间的值转换为位图。

我真的很感激任何帮助,建议,代码,教程,等等。 提前谢谢。

1 个答案:

答案 0 :(得分:0)

这是一个示例,它从数据源创建一个基于8位调色板的图像,该数据源的值范围为-2048 - +2047。请注意,这是一个12位的值范围,因此实际上需要一个16位的调色板。

但是不支持此功能。即使RGB也不支持它们,也不会支持任何非专用显卡。

如果您需要全方位的精确度,则必须使用外部工具。

您可以尝试使用位抖动来创建基于RGB的解决方案,通过改变R,G和B值来模拟4096个灰度值。

   using System.Drawing.Imaging;
   using System.Runtime.InteropServices;
   //..   

    // 8-bit grayscale
    Bitmap bmp = new Bitmap(512,512, PixelFormat.Format8bppIndexed);

    List<Color> colors = new List<Color>();

    byte[] data = new byte[512 * 512];

    for (int y = 0; y < 512; y++)
    for (int x = 0; x < 512; x++)
    {
        int v = getValue() + 2048;      // replace by your data reader!

        int r = v >> 4;                 // < here we lose 4 bits!
        int g = r;
        int b = r;
        Color c = Color.FromArgb(r, g, b);
        int cIndex = 0;
        if (colors.Contains(c)) cIndex = colors.IndexOf(c);
        else { colors.Add(c); cIndex = colors.Count; }

        //bmp.SetPixel(x,y,c);    // this would be used for rgb formats!
        data[y * 512 + x] = (byte) cIndex;
    }

    // prepare a locked image memory area
    var bmpData = bmp.LockBits(
                new Rectangle(0, 0, bmp.Width, bmp.Height),
                ImageLockMode.WriteOnly, bmp.PixelFormat);

    // move our data in
    Marshal.Copy(data, 0, bmpData.Scan0, data.Length);
    bmp.UnlockBits(bmpData);

    // create the palette
    var pal = bmp.Palette;
    for (int i = 0; i < colors.Count; i++) pal.Entries[i] = colors[i];
    bmp.Palette = pal;

    // display
    pictureBox1.SizeMode = PictureBoxSizeMode.AutoSize;
    pictureBox1.Image = bmp;