OpenGL的C++:如何将32位png文件转换为16位565RGB文件

问题描述:

我尝试32位PNG文件转换为16位的文件格式,我知道如何转换海誓山盟(如RGB565 RGBA4444)之间的16种文件格式但是我不知道如何去从32位转换到16位。OpenGL的C++:如何将32位png文件转换为16位565RGB文件

我的主要问题是:如何查找32位png如何存储(每个8位分配给R,B,G和A值)?

我该如何失去精度但仍保持大致相同的值?

在此先感谢

+1

这实在是两个问题:1)我该如何解压缩PNG?和2)如何将32位颜色转换为16位颜色? #1的答案是使用libpng。如果您“想要了解”这一点,那么您必须阅读[PNG规范文档](http://www.libpng.org/pub/png/spec/)。解压缩PNG并不是一件简单的事情。 PNG是压缩图像;他们以压缩形式存储信息。所以阅读它们很复杂。这就是为什么几乎所有读取PNG的工具都使用libpng来解压缩它们。 – 2012-02-22 04:40:58

你会好得多使用libpng比手工实现这一点。

+0

这是我想了解,虽然 – James 2012-02-22 03:42:48

我不熟悉的32位PNG像素的确切布局,但假设它是你可能想要做类似的事情到此等格式比较一致:

// Get the pixel from the png: 
unsigned int pngPixel = getPngPixel(); 

unsigned char r = (pngPixel & 0xFF000000) >> 24; 
unsigned char g = (pngPixel & 0x00FF0000) >> 16; 
unsigned char b = (pngPixel & 0x0000FF00) >> 8; 
unsigned char a = (pngPixel & 0x000000FF); 

// you can collapse this to one line, but for clarity... 
// masking off the least significant bits. 
unsigned short rgb565Pixel = (r & 0xF8) << 11; 
rgb565Pixel |= (g & 0xFC) << 5; 
rgb565Pixel |= (b & 0xF8); 

// Again you could collapse this down to one line, but for clarity... 
// masking off the least significant bits. 
unsigned short rgba4Pixel = (r & 0xF0) << 12; 
rgba4Pixel |= (g & 0xF0) << 8; 
rgba4Pixel |= (b & 0xF0) << 4; 
rgba4Pixel |= (a & 0xF0); 

考虑这个伪代码。

有人可能会说,从8位转换为4位的时候屏蔽掉至少显著位,特别是,是不是在两者之间转换一个很好的方法,他们会是正确的。你可以使用转换功能:

unsigned int convertColor(unsigned char c, unsigned int oldMax, unsigned int newMax) { 
    double oldColor = c; 
    double percentOfMax = oldColor/oldMax; 
    return ((unsigned int)(newMax * percentOfMax)) & newMax; 
} 

// now we can do this 
unsigned short rgba4Pixel = convertColor(r, 0xFF, 0x0F) << 12; 
rgba4Pixel |= convertColor(g, 0xFF, 0x0F) << 8; 
rgba4Pixel |= convertColor(b, 0xFF, 0x0F) << 4; 
rgba4Pixel |= convertColor(a, 0xFF, 0x0F); 
+0

PNG的是* *压缩。这是他们的观点。他们不将数据存储在简单的32位RGBA格式中。 – 2012-02-22 04:37:39

+0

我猜我错过了那一点。我以为他已经解压缩了png。 – grieve 2012-02-22 04:46:27