关于读写位图的疑问?

jesjes 2003-10-10 09:07:39
我想把得到的数据写出位图形式,8bit灰度图,信息头和文件头一共54字节,加上调色板256×4字节,数据是352*288,那么算一下文件应该是18c00h,可是用ultraedit查看数据,已经存到4a435h了,那里多出那么多数据???
另外,信息头的bfsize的大小不管怎么定义对文件都没有影响,奇怪啊!还有如果不要调色板会怎么样?现在的结果是信息头是以BM开头,但文件不是位图,没法打开,真是百思不得其解!!
...全文
79 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
zzwu 2003-10-13
  • 打赏
  • 举报
回复
bf是写24bit彩色图时定义的,而bfgray是为8位图像定义的,所以,虽然图像的大小(宽和高)一样,但因每个像素的bit数相差了几倍,文件的大小就要相差几倍了.
ThenLong 2003-10-13
  • 打赏
  • 举报
回复
要不你直接使用Bitmap类,Delphi里是TBitmap VC里应该是CBipmap吧?很方便的
red-fly 2003-10-13
  • 打赏
  • 举报
回复
竟没有BITMAPINFORHEADER结构,行吗?不会吧,一般都是在BITMAPINFORHEADER里加入调色板信息,同时把此结构的其它位补充完整再写入文件,然后写入数据
jesjes 2003-10-12
  • 打赏
  • 举报
回复
是不是调色板的写法不对呢?
jesjes 2003-10-12
  • 打赏
  • 举报
回复
to 涛涛
lpbuff是24bit彩色图的数据指针,3个字节对应1个象素,通过red*0.299+green*0.587+blue*0.114得到灰度再存到lpbuffgray1(灰度图象数据指针),这样做不对吗?unsigned int和int都是16bit,只是数据范围不一样,对于0——255之间的数好像没有区别吧?
jesjes 2003-10-12
  • 打赏
  • 举报
回复
在前面有一个BITMAPFILEHEADER bf;是写24bit彩色图时定义的,在这忘了改成sizeof(bfgray)但是大小都一样吧?
devspace 2003-10-12
  • 打赏
  • 举报
回复
如楼上所说,一些变量定义我都不知道如何定义的,而且也不知道你的结构体是什么样的,你把程序不知道在不在,我试试吧,不保证调通呵呵 email:devspace@etang.com
devspace 2003-10-12
  • 打赏
  • 举报
回复
看看:

其中数据部分由:
for(K=0;K<bmih.biHeight*bmih.biWidth;K++)
{
blue=(unsigned char)(*lpbuff);lpbuff++;
green=(unsigned char)(*lpbuff);lpbuff++;
red=(unsigned char)(*lpbuff);lpbuff++;
y=(float)(red*0.299+green*0.587+blue*0.114);
*lpbuffgray1=(int)y;
lpbuffgray1++;
}得到


你的出错就在这里,256色灰度图象的每象素只占一个字节的存储,
但你理解成了4个,而且别把类型(unsigned int搞错了)


灰度图象和彩色图象在写数据时,由于前者用到了调色板,写数据实际是在写
索引值,你再看看数据类型千万别搞错,我以前吃过大亏的
zzwu 2003-10-12
  • 打赏
  • 举报
回复
请问
fff.Write(&bfgray, sizeof(bf));
中的sizeof(bf)=?
何处定义了bf?
wolfslash 2003-10-11
  • 打赏
  • 举报
回复
位图存成文件时,列的数目必须是4的倍数,如果不足,就用0补,这和前面的仁兄说法是一致的。这个列数有可能和文件信息头中的不一样。
jesjes 2003-10-11
  • 打赏
  • 举报
回复
看看我的程序,怎么也不知道那里出了毛病。
BITMAPFILEHEADER bfgray;
bfgray.bfOffBits=(DWORD)(256*sizeof(RGBQUAD)+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER));
bfgray.bfSize=256*4+54+352*288;
bfgray.bfType = (int)'M' * 256 + 'B';
bfgray.bfReserved1 = 0;
bfgray.bfReserved2 = 0;
RGBQUAD rgb[256];
for(int j=0;j<256;j++)
{
rgb[j].rgbBlue=(BYTE)j;
rgb[j].rgbGreen=(BYTE)j;
rgb[j].rgbRed=(BYTE)j;
rgb[j].rgbReserved=(BYTE)0;
}
CFile fff("d:\\original\\a\\d", CFile::modeWrite | CFile::modeCreate);
fff.Write(&bfgray, sizeof(bf));
fff.Write(&bmihgray, 40);
fff.Write(&rgb,256*sizeof(RGBQUAD));
fff.Write(lpbuffgray, 352 * 288);
fff.Close();
delete lpbuffgray;
其中数据部分由:
for(K=0;K<bmih.biHeight*bmih.biWidth;K++)
{
blue=(unsigned char)(*lpbuff);lpbuff++;
green=(unsigned char)(*lpbuff);lpbuff++;
red=(unsigned char)(*lpbuff);lpbuff++;
y=(float)(red*0.299+green*0.587+blue*0.114);
*lpbuffgray1=(int)y;
lpbuffgray1++;
}得到
文件头由:
BITMAPINFOHEADER bmihgray
memcpy(&bmihgray,&bmih,sizeof(BITMAPINFOHEADER));//bmih是24bit彩色图的文件头
bmihgray.biBitCount=8;
bmihgray.biClrUsed=256;
bmihgray.biSize=352*288;
得到
devspace 2003-10-11
  • 打赏
  • 举报
回复
整个文件大小应该是:54+256*4+352*288
信息头的大小必须是40,这在填写头信息时要写入的,
分析你产生的文件大小,我想是在一个方面写错了,就是在 写入图象数据的时候,一定要是
unsigned int型,因为你定义的是256色的调色板,只需要8位(即一个字节就行了),
如果你定义的是int,前面高8位肯定要填0,后果你想想就知道了
再看看你在定义调色板时是否有相同的错误

下面是我些的程序,编译-》运行程序就会产生一个256*256大小的灰度图象,也是8bit灰度图
256大小是便于rgb值从00变化到FF

用tc2.0编译就行了:

#include <stdio.h>
struct color
{
char blue;
char green;
char red;
char reserved;
}rgb[256];
struct map
{
char type1;
char type2;
long size;
long resrved;
long offset;
long sizestruct;
long width;
long heith;
int planes;
int bitcount;
long compression;
long sizeimage;
long xpelspermeter;
long ypelspermeter;
long clrused;
long clrimportant;
}bmphead={'B','M',65536+1078,0,1078,40,256,256,1,8,0,256*256,0,0,256,0 };
create()
{
FILE *fp;
if((fp=fopen("qwj.bmp","wb+"))==NULL)
{printf("can't open file\n");
return; }
if(fwrite(&bmphead,sizeof(struct map),1,fp)!=1)
printf("file write error\n");
fclose(fp);
}

write()
{
int i;
int j;
char k;
FILE *fp;
for(i=0;i<256;i++)
{
rgb[i].blue=i;
rgb[i].green=i;
rgb[i].red=i;
rgb[i].reserved=0;
}
fp=fopen("qwj.bmp","ab");
for(i=0;i<256;i++)
fwrite(&rgb[i],sizeof(struct color),1,fp);
for(j=0;j<256;j++)
for(k=0;k<=255;k++)
{fwrite(&k,1,1,fp);}



fclose(fp);
}

void main()
{
create();//产生文件头和信息头
write();//调色板和图象数据
printf("success\n");
}

jesjes 2003-10-10
  • 打赏
  • 举报
回复
前面的问题搞清楚了,现在的疑问是:信息头的bfsize的大小不管怎么定义对文件都没有影响,奇怪啊!还有如果不要调色板可以显示8bit灰度位图吗?现在的结果是已经写入文件头,调色板,图象数据,但是不能形成位图,更不能显示。
jesjes 2003-10-10
  • 打赏
  • 举报
回复
8bit灰度图每个象素一个字节,不涉及补足4字节的问题吧
ac1998 2003-10-10
  • 打赏
  • 举报
回复


BMP文件在主要信息部分是要每行4字节对齐的,不足的行要补0。

这与用不用调色板是没有关系 的。
jesjes 2003-10-10
  • 打赏
  • 举报
回复
能否简述一下24bit彩色转8bit位图的基本过程,目前最费解的就是按着位图格式转换了却不能正确显示?
ThenLong 2003-10-10
  • 打赏
  • 举报
回复
我刚看了宽度为87的8bit的DIB数据,要对齐的
呵呵,有点类似Fat系统,都要浪费一点4k的族
jesjes 2003-10-10
  • 打赏
  • 举报
回复
是啊,就是因为这个才那么费劲。
ThenLong 2003-10-10
  • 打赏
  • 举报
回复
你用Vc++吗???

4,446

社区成员

发帖
与我相关
我的任务
社区描述
图形图像/机器视觉
社区管理员
  • 机器视觉
  • 迪菲赫尔曼
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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