将调色板应用于图片
本文关键字:应用于 调色板 | 更新日期: 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;