将调色板应用于图片

本文关键字:应用于 调色板 | 更新日期: 2023-09-27 18:27:12

我需要为.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文件)将[-20482047]之间的值转换为位图。

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

将调色板应用于图片

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

但是,这是不受支持的。即使是RGB也不支持它们,任何非专业显卡也不支持。

如果你需要全方位的精度,你将不得不使用外部工具。

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

   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;