Конвертировать 24-битный бит в 16 бит?
Я знаю, что .NET Framework имеет класс преобразования изображений (метод System.Drawing.Image.Save).
Но мне нужно конвертировать 24-битное (R8G8B8) растровое изображение в 16-битное (X1R5G5B5), и я действительно не знал об этом виде преобразования и 24-к-16-битных изменениях в bmp заголовок не будет работать (поскольку нам нужно преобразовать все данные изображения).
Также я хотел бы знать, могу ли я контролировать изображение Dither и т.д.
Идеи?
Любая помощь будет оценена.
Ответы
Ответ 1
Формат 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;
}
Ответ 2
Вам нужно сохранить растровое изображение с параметром 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);
Ответ 3
Очень простой способ сделать это - перебрать старые битмап-данные и скрывать каждую пару значений 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 allocated
for(char *p=data; p<data+len*3; p+=3)
*(short *)newdata=transform(*(long *)data);
}