关于16位BMP图片的显示问题

sailinghz 2008-05-04 10:03:50
16位的bmp文件的图像数据区中,每个像素用2个字节表示。未压缩时,低5位代表蓝色分量,中间5位代表绿色分量,高5位代表红色分量,最高一位保留,设为0.
根据像素点的各颜色分量的信息可以得到其RGB颜色值,由于每个颜色分量只用5位表示,即其最大值为31,因此很大一部分颜色值在16位的BMP图片中是不能够显示的。而且图片应该是很暗的。但是用ACDSEE,PS打开16位BMP图片,显示效果跟24位的BMP差不多。这是为什么呢?
...全文
932 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
heroesyao 2011-05-02
  • 打赏
  • 举报
回复
学习了,谢谢~
Vicent20138888 2010-09-24
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 sailinghz 的回复:]

visame,谢谢你的热心。我已经找到答案了。应该是把 5 位的 R ¦G ¦B 值转成 8 位的 R ¦G ¦B 值时,填充字节的高5位,每个颜色的最大值应为248。而我却误以为是将填充每个字节的低五位,最大颜色值为31。
[/Quote]
学习了。
sailinghz 2008-05-07
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 visame 的回复:]
你给一个16位的图像我看看。我用Matlab尝试一下。最好还发一个24位的过来对比一下。
我觉得应该可以看出来。
[/Quote]
好像往CSDN上传图片只能通过超链接。我本想把16位的BMP放到博客上,然后在这里加个链接,但是新浪博客不支持16位的BMP。我已通过MSN发邮件将图片给你。谢谢你!
visame 2008-05-07
  • 打赏
  • 举报
回复
你给一个16位的图像我看看。我用Matlab尝试一下。最好还发一个24位的过来对比一下。
我觉得应该可以看出来。
sailinghz 2008-05-07
  • 打赏
  • 举报
回复
visame,谢谢你的热心。我已经找到答案了。应该是把 5 位的 R ¦G ¦B 值转成 8 位的 R ¦G ¦B 值时,填充字节的高5位,每个颜色的最大值应为248。而我却误以为是将填充每个字节的低五位,最大颜色值为31。
sailinghz 2008-05-06
  • 打赏
  • 举报
回复
sailinghz 2008-05-06
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 vincen_cn 的回复:]
因为有16位这样的格式,所以你的这个东西不是你发明的,
ACDSEE等软件一定考虑到了这个方面。
我记得16位的有两种的,按照哪一种来解释你的图像也差不了多少。
[/Quote]
是有两种,我刚才提到的是第一种,也就是未压缩的555 16位位图。
sailinghz 2008-05-06
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 visame 的回复:]
虽然数值是0-31。但是最后还是会映射到0-255上显示。
[/Quote]
16位的没有调色板,怎么映射呢?
vincen_cn 2008-05-06
  • 打赏
  • 举报
回复
因为有16位这样的格式,所以你的这个东西不是你发明的,
ACDSEE等软件一定考虑到了这个方面。
我记得16位的有两种的,按照哪一种来解释你的图像也差不了多少。
visame 2008-05-06
  • 打赏
  • 举报
回复
虽然数值是0-31。但是最后还是会映射到0-255上显示。
sailinghz 2008-05-05
  • 打赏
  • 举报
回复
先把代码发上来吧。


/*定义ONEBYTE为一个字节的类型*/
typedef unsigned char ONEBYTE;
//读取16位BMP图片的函数
void Bitmap::Sixteen_Bitmap()
{
ONEBYTE pixelByte1; //每个像素点占有的第一个字节
ONEBYTE pixelByte2; //每个像素点占有的第二个字节
int readNull; //图像数据区每行需补零的字节个数
ONEBYTE tempR, tempG, tempB;
int i,j,k;

//计算图像数据区每行需补零的字节个数
readNull = 4 - (width*2) % 4;

/* 读取像素点字节信息,文件头和信息头已经读出 */
for (i = height; i > 0; i--) //heigh和width是图像的高和宽,在位图信息头中得到
{,
for (j = 0; j < width; j++)
{
fread(&pixelByte1, 1, 1, fp); //fp是指向BMP文件的指针
fread(&pixelByte2, 1, 1, fp);

tempB = pixelByte1 & 0x1f;
tempG = ((pixelByte2 & 0x3) << 3) | (pixelByte1 >> 5);
tempR = (pixelByte2 >> 2) & 0x1f;

printf("%x %x %x\n", tempB, tempG, tempR);

pixelColor.push_back(RGB(tempR, tempG, tempB)); //pixelColor是存放所有像素点颜色值的向量
}
/* 读出填充的0字节 */
if (readNull != 4)
{
k = readNull;
while(k)
{
fgetc(fp);
k--;
}
}
}
}
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 studyall123 的回复:]
up
[/Quote]
sailinghz 2008-05-05
  • 打赏
  • 举报
回复
呵呵,继续顶。
ifei9999 2008-05-05
  • 打赏
  • 举报
回复
up
visame 2008-05-05
  • 打赏
  • 举报
回复
[Quote=引用楼主 sailinghz 的帖子:]
16位的bmp文件的图像数据区中,每个像素用2个字节表示。未压缩时,低5位代表蓝色分量,中间5位代表绿色分量,高5位代表红色分量,最高一位保留,设为0.
根据像素点的各颜色分量的信息可以得到其RGB颜色值,由于每个颜色分量只用5位表示,即其最大值为31,因此很大一部分颜色值在16位的BMP图片中是不能够显示的。而且图片应该是很暗的。但是用ACDSEE,PS打开16位BMP图片,显示效果跟24位的BMP差不多。这是为什么呢?
[/Quote]
把图像传上来看看!我感兴趣。或许用Matlab可以发现问题所在。
很久没有学习图像相关知识,都快忘光了。
看下面的网页:
http://www.china-askpro.com/msg50/qa39.shtml
sailinghz 2008-05-04
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 studyall123 的回复:]
up
[/Quote]
谢谢!继续顶
不想低调 2008-05-04
  • 打赏
  • 举报
回复
up
sailinghz 2008-05-04
  • 打赏
  • 举报
回复
顶上去,呵呵

69,364

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧