简体   繁体   English

opengl c ++:如何将32位png文件转换为16位565RGB文件

[英]opengl c++: How to convert a 32bit png file to a 16 bit 565RGB file

I am trying to convert 32bit png files to 16 bit file formats, I understand how to convert 16 bit file formats between eachother (eg RGB565 RGBA4444) However I'm not sure how to go about converting from a 32 bit to a 16 bit. 我正在尝试将32位png文件转换为16位文件格式,我了解如何在彼此之间转换16位文件格式(例如RGB565 RGBA4444),但是我不确定如何从32位转换为16位。

My main questions are: How do I find how the 32 bit pngs stored (are 8 bits each assigned to R,B,G, and A values)? 我的主要问题是:如何找到32位png的存储方式(8位分别分配给R,B,G和A值)?

How do I lost precision but still maintain roughly the same value? 我如何失去精度但仍保持大致相同的值?

Thanks in advance 提前致谢

使用libpng会比手动实现更好。

I am not familiar with the exact layout of the 32bit png pixel, but assuming it is relatively consistent with other formats you probably want to do something similar to this: 我不熟悉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);  

Consider this pseudocode. 考虑这个伪代码。

One could argue that masking off the least significant bits, especially when converting from 8 bit to 4 bit, is not a very good way to convert between the two, and they would be right. 有人可能会说,掩盖最低有效位,特别是当从8位转换为4位时,不是在两者之间转换的一种很好的方法,它们是正确的。 You could instead use a conversion function: 您可以改用转换函数:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM