我知道.NET Framework附带了一个图像转换类(System.Drawing.Image.Save方法)。
但我需要将24位(R8G8B8)位图图像转换为16位(X1R5G5B5),我真的不知道这种转换,以及bmp中24到16位的变化标头不起作用(因为我们需要转换整个图像数据)。
此外,我想知道我是否可以控制图像抖动等。
想法? 任何形式的帮助将不胜感激。
答案 0 :(得分:20)
声明了Format16bppRgb1555像素格式,但GDI +实际上并不支持它。没有使用该像素格式的主流视频驱动程序或图像编解码器。 GDI +设计师猜测可能的事情发生了,他们的时间机器不够准确。否则,程序员可以使用System.Drawing进行相当粗糙的复制/粘贴。
Rgb555是最接近可用硬件和编解码器的匹配项:
public static Bitmap ConvertTo16bpp(Image img) {
var bmp = new Bitmap(img.Width, img.Height,
System.Drawing.Imaging.PixelFormat.Format16bppRgb555);
using (var gr = Graphics.FromImage(bmp))
gr.DrawImage(img, new Rectangle(0, 0, img.Width, img.Height));
return bmp;
}
答案 1 :(得分:1)
您需要使用指定颜色深度的Encoder参数保存位图。
myEncoder = Encoder.ColorDepth;
myEncoderParameters = new EncoderParameters(1);
// Save the image with a color depth of 24 bits per pixel.
myEncoderParameter = new EncoderParameter(myEncoder, 24L);
myEncoderParameters.Param[0] = myEncoderParameter;
myBitmap.Save("MyBitmap.bmp", myImageCodecInfo, myEncoderParameters);
答案 2 :(得分:1)
一种非常直接的方法是循环旧的位图数据并将每对r8-g8-b8值转换为x1-r5-g5-b5,类似于此函数:
char condense(char i)
{
return (char)(i*255.0f/31.0f);
}
short transform(long input)// note that the last 8 bytes are ignored
{
return condense(input&0xff) || (condense((input&0xff00)>>8)<<5)
|| (condense((intput&0xff0000)>>16)<<10);
}
// and somewhere in your program
{
int len; // the length of your data in pixels
char *data; // your data
char *newdata; // this is where you store the new data; make sure it's allocated
for(char *p=data; p<data+len*3; p+=3)
*(short *)newdata=transform(*(long *)data);
}