我得到了一个16bpp的位图

我通过下面的代码将其转换为32bpp:
void Rgb555ToRgb8(const UChar* bitmapData, UInt32 width, UInt32 height, UChar* buf)
{
UInt32 dst_bytes_per_row = width * 4;
UInt32 src_bytes_per_row = ((width * 16 + 31) / 32) * 4;
UInt16 red_mask = 0x7C00;
UInt16 green_mask = 0x3E0;
UInt16 blue_mask = 0x1F;
for (UInt32 row = 0; row < height; ++row)
{
UInt32 dstCol = 0, srcCol = 0;
do
{
UInt16 rgb = *(UInt16*)(bitmapData + row * src_bytes_per_row + srcCol);
UChar red_value = (rgb & red_mask) >> 10;
UChar green_value = (rgb & green_mask) >> 5;
UChar blue_value = (rgb & blue_mask);
buf[row*dst_bytes_per_row + dstCol] = blue_value << 3;
buf[row*dst_bytes_per_row + dstCol + 1] = green_value << 3;
buf[row*dst_bytes_per_row + dstCol + 2] = red_value << 3;
buf[row*dst_bytes_per_row + dstCol + 3] = rgb >> 15;
srcCol += 2;
dstCol += 4;
} while (srcCol < src_bytes_per_row);
}
}转换结果如下: 2:https://i.stack.imgur.com/1ajO7.png
我还尝试通过GdiPlus转换此图像:
Gdiplus::Bitmap* bmp = new Gdiplus::Bitmap(w,h,PixelFormat32bppRGB);
生成的图像是

。
请注意,这两个结果看起来并不完全相同(例如,GdiPlus结果中的背景是白色的)。如何修改代码以匹配GdiPlus结果?
发布于 2021-04-16 23:29:46
有两个问题需要解决:
未使用的位
当从5比特信息移动到8比特信息时,您将获得额外的3比特。在实现时,代码没有使用这个额外的范围,并且偏向于较暗的颜色分量。这是对blue_value << 3实际功能的说明:
5 bits per channel 8 bits per channel
bbbbb -> bbbbb000为了解决这个问题,最低有效的3位需要随着通道值的增加而增长。一个简单的(仍然是somewhat inaccurate)是只将最高有效的3位复制到最低有效的3位,即
buf[row*dst_bytes_per_row + dstCol] = (blue_value << 3) | (blue_value >> 2);
buf[row*dst_bytes_per_row + dstCol + 1] = (green_value << 3) | (green_value >> 2);
buf[row*dst_bytes_per_row + dstCol + 2] = (red_value << 3) | (red_value >> 2);精确的映射可能会涉及更多,例如
blue_value = static_cast<UChar>((blue_value * 255.0) / 31.0 + 0.5);这将从5位转换为最接近理想值的相应8位值,包括上面的位移位解决方案中偏移1/255的4个值。
如果选择后者,则可以构建一个存储映射值的查找表。这个表只有32个条目,每个条目一个字节,所以它可以放入单个缓存线中。
Alpha通道
假设源图像的MSB确实被解释为alpha值,那么您也需要将其移动到目标位置。由于源只有1比特的信息,所以原始转换很简单:
buf[row*dst_bytes_per_row + dstCol + 3] = rgb & (1 << 15) ? 255 : 0;这可能是也可能不是所需的全部。Windows假定预乘alpha,即颜色通道的存储值必须预乘alpha值(有关参考,请参见BLENDFUNCTION )。
如果alpha值为255,则颜色通道值已正确。如果alpha值为0,则需要将所有颜色通道乘以0(或仅设置为0)。转换不会产生任何其他alpha值。
https://stackoverflow.com/questions/67126397
复制相似问题