我知道.NET Framework自带一个图像转换类(System.Drawing.Image.Save方法)。
但我需要将24位(R8G8B8)的位图图像转换为16位(X1R5G5B5),对于这种类型的转换,我真的一无所知,并且在bmp标头中进行24位到16位的更改也行不通(因为我们需要转换整个图像数据)。
此外,我想知道是否可以控制图片的抖动等参数。
有什么好的建议吗?任何形式的帮助都将不胜感激。
格式为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;
}
您需要使用编码器参数指定颜色深度来保存位图。
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);
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);
}
System.Drawing.Image
,您可以使用我绘图库中的ConvertPixelFormat
。它支持抖动,实际上不仅可以用于 GDI+ 图像,而且可以用于任何托管或非托管像素缓冲区。 - György Kőszeg