bmp的那个什么要是4的倍数

xxxrenwu 2005-03-16 10:52:17
我现在要转24位色跟16位色bmp文件互转
bmp的头都不用管,每个像素各是3个字节及2个字节表示
比如一个24位的图数据如下
00000000h: 42 4D 9E 02 00 00 00 00 00 00 36 00 00 00 28 00 ; BM?......6...(.
00000010h: 00 00 12 00 00 00 0B 00 00 00 01 00 18 00 00 00 ; ................
00000020h: 00 00 68 02 00 00 00 00 00 00 00 00 00 00 00 00 ; ..h.............
00000030h: 00 00 00 00 00 00 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 ; ......
00000040h: F8 F8 B8 18 18 B8 18 18 F8 F8 F8 F8 F8 F8 F8 F8 ; ?.?.
00000050h: F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 ; 
00000060h: F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 00 00 F8 F8 ; ..
00000070h: F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 B8 18 18 B8 18 18 ; ?.?.
00000080h: F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 ; 
00000090h: F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 ; 
000000a0h: F8 F8 F8 F8 00 00 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 ; ..
000000b0h: F8 F8 B8 18 18 B8 18 18 F8 F8 F8 F8 F8 F8 F8 F8 ; ?.?.
000000c0h: F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 ; 
000000d0h: F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 00 00 F8 F8 ; ..
000000e0h: F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 B8 18 18 B8 18 18 ; ?.?.
000000f0h: F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 ; 
00000100h: F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 ; 
00000110h: F8 F8 F8 F8 00 00 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 ; ..
00000120h: F8 F8 B8 18 18 B8 18 18 F8 F8 F8 F8 F8 F8 F8 F8 ; ?.?.
00000130h: F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 ; 
00000140h: F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 00 00 F8 F8 ; ..
00000150h: F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 B8 18 18 B8 18 18 ; ?.?.
00000160h: F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 ; 
00000170h: F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 ; 
00000180h: F8 F8 F8 F8 00 00 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 ; ..
00000190h: F8 F8 B8 18 18 B8 18 18 F8 F8 F8 F8 F8 F8 F8 F8 ; ?.?.
000001a0h: F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 ; 
000001b0h: F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 00 00 F8 F8 ; ..
000001c0h: F8 F8 F8 F8 F8 F8 F8 B8 18 18 B8 18 18 B8 18 18 ; ..?.?.
000001d0h: B8 18 18 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 ; ?.?
000001e0h: F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 ; 
000001f0h: F8 F8 F8 F8 00 00 F8 F8 F8 F8 F8 F8 B8 18 18 F8 ; ..?.?
00000200h: F8 F8 B8 18 18 B8 18 18 F8 F8 F8 B8 18 18 F8 F8 ; ?.?...
00000210h: F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 ; 
00000220h: F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 00 00 F8 F8 ; ..
00000230h: F8 B8 18 18 F8 F8 F8 F8 F8 F8 B8 18 18 B8 18 18 ; ..?.?.
00000240h: F8 F8 F8 F8 F8 F8 B8 18 18 F8 F8 F8 F8 F8 F8 F8 ; ?.?
00000250h: F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 ; 
00000260h: F8 F8 F8 F8 00 00 B8 18 18 B8 18 18 B8 18 18 B8 ; ..?.?.?.?
00000270h: 18 18 B8 18 18 B8 18 18 B8 18 18 B8 18 18 B8 18 ; ..?.?.?.?.?
00000280h: 18 B8 18 18 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 ; .?.
00000290h: F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 F8 00 00 ; ..
相应的16位数据为

00000000h: 42 4D C2 01 00 00 00 00 00 00 36 00 00 00 28 00 ; BM?......6...(.
00000010h: 00 00 12 00 00 00 0B 00 00 00 01 00 10 00 00 00 ; ................
00000020h: 00 00 00 00 00 00 C4 0E 00 00 C4 0E 00 00 00 00 ; ......?..?....
00000030h: 00 00 00 00 00 00 FF 7F FF 7F FF 7F FF 7F 77 0C ; ......w.
00000040h: 77 0C FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F ; w.
00000050h: FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F ; 
00000060h: FF 7F 77 0C 77 0C FF 7F FF 7F FF 7F FF 7F FF 7F ; w.w.
00000070h: FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F ; 
00000080h: FF 7F FF 7F FF 7F 77 0C 77 0C FF 7F FF 7F FF 7F ; w.w.
00000090h: FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F ; 
000000a0h: FF 7F FF 7F FF 7F FF 7F FF 7F 77 0C 77 0C FF 7F ; w.w.
000000b0h: FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F ; 
000000c0h: FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F 77 0C ; w.
000000d0h: 77 0C FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F ; w.
000000e0h: FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F ; 
000000f0h: FF 7F 77 0C 77 0C FF 7F FF 7F FF 7F FF 7F FF 7F ; w.w.
00000100h: FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F ; 
00000110h: FF 7F FF 7F FF 7F 77 0C 77 0C FF 7F FF 7F FF 7F ; w.w.
00000120h: FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F ; 
00000130h: FF 7F FF 7F FF 7F FF 7F 77 0C 77 0C 77 0C 77 0C ; w.w.w.w.
00000140h: FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F ; 
00000150h: FF 7F FF 7F FF 7F FF 7F FF 7F 77 0C FF 7F 77 0C ; w.w.
00000160h: 77 0C FF 7F 77 0C FF 7F FF 7F FF 7F FF 7F FF 7F ; w.w.
00000170h: FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F 77 0C FF 7F ; w.
00000180h: FF 7F 77 0C 77 0C FF 7F FF 7F 77 0C FF 7F FF 7F ; w.w.w.
00000190h: FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F 77 0C ; w.
000001a0h: 77 0C 77 0C 77 0C 77 0C 77 0C 77 0C 77 0C 77 0C ; w.w.w.w.w.w.w.w.
000001b0h: 77 0C FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F ; w.
000001c0h: FF 7F ; 

我在生成bmp文件的时候,完成了像素对应的转换外,是不是还要考虑别的
在论坛上看到有些网友说要什么的值是4的倍数,请指教
...全文
819 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
pomelowu 2005-03-17
  • 打赏
  • 举报
回复
To ipgk

我粗心了。:)
flyhigh 2005-03-17
  • 打赏
  • 举报
回复
好象楼上的都没有说到问题的顶子上。
我以为这主要是为了CPU处理数据的方便。
就象我的的程序中有字节对齐的问题一样,为什么要字节对齐?因为用4字节对齐处理速度更快,虽然用1字节对齐可以节省存储空间。同样在位图的格式定义中我以为也是基于这个问题的考虑。
可以肯定的是,就算不用4字节对齐同样可以实现对各种位图的存储。
以上只是我的猜测。
ipgk 2005-03-17
  • 打赏
  • 举报
回复
倒,怎么1+1 = 1*1,我晕头了。反正我的意思你明白。
ipgk 2005-03-17
  • 打赏
  • 举报
回复
我发现了一个公式a*b = a+b
1+1=1*1
2+2=2*2
检验没问题。楼上你明白了吗?你说我是信MSDN还是信你?
我看你对DDB和DIB的概念还不是很清楚。你那种方法就是DIB处理,Bitblt是操作DDB的,当然不能那样画。有个windows API :LoadImage,可以加载图片文件,加载到内存中的就是DDB,是跟你当前屏幕DC兼容,例如你的屏幕是16位色,这个API得到的位图就是16位色,无论你的图片文件原来是多少位。

请你再充分测试你的函数,再把你的函数改为4字节(不是4像素)对齐看有无问题,如果你说前者没问题,改为字节对齐就出问题,那请你鄙视我。
sboom 2005-03-17
  • 打赏
  • 举报
回复
这不是WINDOWS的DIB或者DDB问题,这是BMP文件标准的字节对齐问题,8位和24位我都试过没问题,所以我觉得是象素对齐。我那样提取出来的是象素矩阵,是一个2维数组,不能用Bitblt函数画的,我自己用dc->SetPixel来画的。
pomelowu 2005-03-16
  • 打赏
  • 举报
回复
嗯,是楼上的意思。但是楼主是直接做数据块的转换,不会影响到每行的像素数的啊
sboom 2005-03-16
  • 打赏
  • 举报
回复
每行象素数是4的倍数,如果不是,则在末尾补齐。
ipgk 2005-03-16
  • 打赏
  • 举报
回复
16位色基本不用考虑对齐了,因为每个象素刚好是2Byte,24位色是要考虑的。
ipgk 2005-03-16
  • 打赏
  • 举报
回复
每一行字节数必须WORD ALIGN,也就是必须为2的倍数,不是4。
pomelowu 2005-03-16
  • 打赏
  • 举报
回复
如果只考虑数据块的话,就只要注意色值的重新计算啊。
ipgk 2005-03-16
  • 打赏
  • 举报
回复
Platform SDK: Windows GDI
BITMAP
The BITMAP structure defines the type, width, height, color format, and bit values of a bitmap.

typedef struct tagBITMAP {
LONG bmType;
LONG bmWidth;
LONG bmHeight;
LONG bmWidthBytes;
WORD bmPlanes;
WORD bmBitsPixel;
LPVOID bmBits;
} BITMAP, *PBITMAP;
Members
bmType
Specifies the bitmap type. This member must be zero.
bmWidth
Specifies the width, in pixels, of the bitmap. The width must be greater than zero.
bmHeight
Specifies the height, in pixels, of the bitmap. The height must be greater than zero.
bmWidthBytes
Specifies the number of bytes in each scan line. This value must be divisible by 2, because the system assumes that the bit values of a bitmap form an array that is word aligned.
bmPlanes
Specifies the count of color planes.
bmBitsPixel
Specifies the number of bits required to indicate the color of a pixel.
bmBits
Pointer to the location of the bit values for the bitmap. The bmBits member must be a long pointer to an array of character (1-byte) values.
ipgk 2005-03-16
  • 打赏
  • 举报
回复
楼上的,BITMAPINFOHEADER并没有指出每个扫描行的字节数,BITMAP结构就有!biWidth是指位图宽度,不是扫描行的字节数,这是两个不同的概念,biWidth也没有什么对齐,位图宽度可以任意。你说MSDN中有说BITMAPINFOHEADER的biWidth 4字节对齐,我倒要你贴出来看看?

DDB扫描行是2字节对齐,DIB是4字节对齐,楼主说的“那个什么”就是DIB的扫描行。
caoweiguo 2005-03-16
  • 打赏
  • 举报
回复
每行的字节数必须是4的整数倍,可以用MSDN查看BMP文件的信息头结构体BITMAPINFOHEADER,使该结构体的第二项biWidth%4==0;如果biWidth%4!=0,则在每行后面补(4-biWidth%4)个{0,0,0,0},然后再对图象数据进行处理。可以试一下!
ipgk 2005-03-16
  • 打赏
  • 举报
回复
pomelowu(羽战士),SetDIBits不就是操作DIB的吗?你看看MSDN BITMAP结构的帮助,同时在MFC检验一下。


sboom(+-LingCh-+)(怪你过分美丽)
说的 ...
_____________________________
我没意见。不过提醒一下你用24位位图试试。DIB应该是4字节对齐的,如果刚好是8bit位图的话,你的4象素对齐是对的。
sboom 2005-03-16
  • 打赏
  • 举报
回复
#pragma once
#pragma pack(1)//结构单字节对齐(重要)

//BMP文件头
struct BITMAPFILEHEADER_
{
short type;
int bfSize;
short re1,re2;
int Offbits;
};

//BMP信息头
struct BITMAPINFO_
{
int size;
int width,height;
short planes,bitCount;
int comp,sizeImg;
int xpels,ypels;
int used,important;
};

sboom 2005-03-16
  • 打赏
  • 举报
回复

sboom(+-LingCh-+)(怪你过分美丽)
说的
每行象素数是4的倍数,如果不是,则在末尾补齐。

确实是象素对齐,我写过自己分解BMP的函数,用象素对齐没错。
函数读8位灰度图,其中data返回正向存储的象素矩阵,24位的真彩图像同样读,不过1个象素3字节。
bool ReadBMP(char *file,BITMAPFILEHEADER_ *bmph,BITMAPINFO_ *bmpi,unsigned char **data)
{
int i,pos;

FILE *f=fopen(file,"rb");

if(f==NULL) //判断文件是否打开成功
{
return false;
}

fseek(f,0,0);//移动到开头

//----------读BMP文件头
if(fread((char*)bmph,sizeof(BITMAPFILEHEADER_),1,f)==NULL)
{
return false;
}

//-----------读BMP信息头
if(fread((char*)bmpi,sizeof(BITMAPINFO_),1,f)==NULL)
{
return false;
}

fseek(f,bmph->Offbits,0); //定位位图矩阵

int skip=0; //填充象素数
if(bmpi->width%4==0)
skip=0;
else
skip=4-bmpi->width%4;

long N=(bmpi->width)*(bmpi->height);//有效象素总数
*data=(unsigned char*)malloc(N);
for(i=0;i<(bmpi->width)*(bmpi->height);i++) //清空,变白色.
{
(*data)[i]=0xff;
}

unsigned char waste[8];
pos=N-bmpi->width;
for(i=0;i<bmpi->height;i++) //读入位图矩阵
{
fread(&(*data)[pos],bmpi->width,1,f);
fread(waste,skip,1,f);
pos=pos-bmpi->width;
}

fclose(f);

return true;
}
pomelowu 2005-03-16
  • 打赏
  • 举报
回复
DDB应该也是DWORD对齐的啊
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_0qk3.asp
这是MSDN上关于SetDIBits的文档,注意Remarks中的:
The scan lines must be aligned on a DWORD except for RLE-compressed bitmaps
shchenren 2005-03-16
  • 打赏
  • 举报
回复
每行象素数是4的倍数,如果不是,则在末尾补齐。
ipgk 2005-03-16
  • 打赏
  • 举报
回复
楼上说的也是字节对齐,不是象素对齐。同时MSDN中说的是WORD对齐,VC中实现也是这样的,难道DDB是WORD对齐,DIB是DWORD对齐?
lpvBits
Pointer to an array of color data used to set the colors in a rectangle of pixels. Each scan line in the rectangle must be word aligned (scan lines that are not word aligned must be padded with zeros). If this parameter is NULL, the new bitmap is undefined.
pomelowu 2005-03-16
  • 打赏
  • 举报
回复
紧跟在彩色表之后的是图象数据字节阵列。图象的每一扫描行由表示图象象素的连续的字节组成,每一行的字节数取决于图象的颜色数目和用象素表示的图象宽度。扫描行是由底向上存储的,这就是说,阵列中的第一个字节表示位图左下角的象素,而最后一个字节表示位图右上角的象素。(只针对与倒向DIB,如果是正向DIB,则扫描行是由顶向下存储的),倒向DIB的原点在图像的左下角,而正向DIB的原点在图像的左上角。同时,每一扫描行的字节数必需是4的整倍数,也就是DWORD对齐的。
加载更多回复(2)

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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