2010-03-04 224 views
11

我知道.NET Framework带有一个图像转换类(System.Drawing.Image.Save方法)。将24位bmp转换为16位?

但我需要将一个24位(R8G8B8)位图图像转换为16位(X1R5G5B5),我真的不知道这种类型的转换,以及一个24位到16位的变化BMP头不起作用(因为我们需要转换整个图像数据)。

此外,我想知道我是否能够在图像抖动控制等

想法? 任何形式的帮助,将不胜感激。

回答

18

格式16bppRgb1555像素格式被声明,但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

您需要使用指定颜色深度的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

我测试了这一点,这是行不通的。不管是否通过24,8或32,输出格式不会改变。我甚至可以传递像-8这样的无效值。颜色深度从不改变。 – Elmue 2015-04-18 03:58:06

+0

取决于mimetype。得到它为tif工作,没有注意到不同格式的变化 – 2016-11-29 14:25:31

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); 
}