失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 位图(BMP)文件格式(一)

位图(BMP)文件格式(一)

时间:2023-06-21 01:38:26

相关推荐

位图(BMP)文件格式(一)

位图文件分四部份数据块

1.位图文件头

BITMAPFILEHEADERtypedef struct tagBITMAPFILEHEADER {WORD bfType;//文件类型,对于位图格式,其值是'MB'19778, 由于字节存放次序问题的原故,实际为'BM'DWORD bfSize;//文件总大小WORD bfReserved1; //保留,置0WORD bfReserved2; //保留,置0DWORD bfOffBits; //位图数据偏移长度} BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER;

2.位图信息头

BITMAPINFOHEADERtypedef struct tagBITMAPINFOHEADER{DWORDbiSize;//信息头大小,sizeof(BITMAPINFOHEADER)

LONG biWidth; //图片宽度LONG biHeight; //图片高度WORD biPlanes; //面数,置1WORD biBitCount; //每一位像素占的位数,DWORDbiCompression; //压缩,0比表示不压缩.BI_RGBDWORDbiSizeImage;//图片大小,对24位来说,biWidth * biHeight * 3LONG biXPelsPerMeter;//分辨率,每米多少个像素LONG biYPelsPerMeter;//分辨率,每米多少个像素

DWORDbiClrUsed; //用到的颜色数DWORDbiClrImportant; //重要的颜色} BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;

3.调色版

typedef struct tagRGBQUAD {BYTE rgbBlue;BYTE rgbGreen;BYTE rgbRed;BYTE rgbReserved; //保留,置0} RGBQUAD;typedef RGBQUAD FAR* LPRGBQUAD;

4.位图数据

不同位数的数据格式不同,对24位位图来说,没有调色版,位图信息依次存放是BGR...

***********************************************************************************

另外两个数据结构,

//实际上OS/2的调色版,(1,4,8位)typedef struct tagRGBTRIPLE // rgbt { BYTE rgbtBlue ; // blue level BYTE rgbtGreen ; // green level BYTE rgbtRed ; // red level } RGBTRIPLE ;

//位图信息,(位图信息头 + 调色版)

typedef struct tagBITMAPINFO // bmi { BITMAPINFOHEADER bmiHeader ;// info-header structure RGBQUAD bmiColors[1] ;// color table array } BITMAPINFO, * PBITMAPINFO ;

对于24位位图来说,没有色彩对照表(调色版),

其位图数据是

BG R

- - - - - - - - - - - - - - - - - - - - - - - -

也就是RGBTRIPLE结构

另外位图数据是自下而上.也就是说左下角为其第一个元素

关于字节对齐的问题,32位对齐也就是4个字节对节

对24位位图来说

由于存放数据时候时候,每像素3个节字,所以需要考虑对齐

//每行像素byte WIDTHBYTE(row) ((row * 3 + 3 ) / 4 ) * 4//更有效率一点 WIDTHBYTE(row) ((row * 24 + 31)>>5)<<2

测试例子

QQ截一幅图55.bmp

属性如下:

宽度 :847

高度 :596

水平分辨率 :96 DPI

垂直分辨率 :96 DPI

位深度 :24

帧数 :1

图片大小:1516278 字节

有了前面这些.

手动计算 考虑对齐的问题,宽度 BYTE : ((847*3+3)/4)*4 =2544 (byte)

总大小 = 宽度 * 高度 + 文件头(14 bytes) + 信息头(40 bytes)

= 2544 * 596 + 54 = 1516278 (bytes)

读图例子如下:

#include <afx.h>int main(){char *pbuf = NULL;BITMAPFILEHEADER bfh={0};BITMAPINFOHEADER bih={0};CFile file;file.Open("55.bmp",CFile::modeRead);int nLen = file.GetLength();pbuf = new char[nLen+1];file.ReadHuge(pbuf , nLen);file.Close();bfh = *(LPBITMAPFILEHEADER)pbuf;bih = *(LPBITMAPINFOHEADER)(pbuf + sizeof(BITMAPFILEHEADER));delete []pbuf;return 0;}//结果如下:

//文件头//BITMAPFILEHEADER bfh//bfType= 19778//'MB'//bfSize = 1516278//bfReserved1= 0//bfReserved2= 0//bfOffBits = 54

//信息头//BITMAPINFOHEADER bih//biWidth= 847//biHeight = 596//biPlanes = 1//biBitCount = 24//biCompression = 0 //BI_RGB//biSizeImage= 1516224 // bfSize - bfOffBits//biXPelsPerMeter = 3780//biYPelsPerMeter = 3780//biClrUsed = 0//biClrImportant = 0

////显示图片//最原始的用SetPixel来显示图片//例子//单文档工程中.CBmpView...//成员变量public:char * m_pBuf;//整个文件缓存char * m_pBits;//位图数据int m_nWidth;//宽度int m_nHeight;//高度int m_nRowBytes;//每行的节字数LPBITMAPFILEHEADER m_pbfh;//文件头指针LPBITMAPINFOHEADER m_pbih;//信息头指针//构造函数中CBmpView::CBmpView(){// TODO: add construction code herem_pBuf = NULL;m_pBits = NULL;m_pbfh = NULL;m_pbih = NULL;

//读数据CFile file;file.Open("55.bmp",CFile::modeRead);int nLen = file.GetLength();m_pBuf = new char[nLen+1];file.ReadHuge(m_pBuf,nLen);file.Close();

m_pbfh = LPBITMAPFILEHEADER(m_pBuf);//文件头int nOffBits = m_pbfh->bfOffBits;//真实位图数据位移大小m_pbih = LPBITMAPINFOHEADER(m_pBuf + sizeof(BITMAPFILEHEADER));//信息头

m_pBits = m_pBuf + nOffBits;//位图数据

m_nWidth = m_pbih->biWidth; //宽度m_nHeight = m_pbih->biHeight; //高度m_nRowBytes = ((m_nWidth*3+3)/4) * 4;//每行的节字大小}

//显示图片void CBmpView::OnDraw(CDC* pDC){CBmpDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);// TODO: add draw code for native data hereRGBTRIPLE *rgb = (RGBTRIPLE *)(m_pBits);char *pRow = (char *)rgb;int nXOff = 20;int nYoff = 20;

//从下往上显示for(int y = m_nHeight-1 ; y > 0 ; y--){for(int x = 0 ; x < m_nWidth ; x++){BYTE r = rgb[x].rgbtRed;BYTE g = rgb[x].rgbtGreen;BYTE b = rgb[x].rgbtBlue;COLORREF clr = RGB(r,g,b);//取颜色pDC->SetPixel( nXOff + x , nYoff + y ,clr);}pRow += m_nRowBytes;//指向下一行rgb = (RGBTRIPLE *)pRow;//指向下一行}}

//,常规方法.更为简便,速度的方法

int StretchDIBits(

HDC hdc,// handle to DC

int XDest, // x-coord of destination upper-left corner

int YDest, // y-coord of destination upper-left corner

int nDestWidth,// width of destination rectangle

int nDestHeight,// height of destination rectangle

int XSrc, // x-coord of source upper-left corner

int YSrc, // y-coord of source upper-left corner

int nSrcWidth,// width of source rectangle

int nSrcHeight, // height of source rectangle

CONST VOID *lpBits,// bitmap bits

CONST BITMAPINFO *lpBitsInfo, // bitmap data

UINT iUsage, // usage options

DWORD dwRop // raster operation code

);

StretchDIBits(pDC->GetSafeHdc(),nXOff,nYoff,m_nWidth,m_nHeight,0,0,m_nWidth,m_nHeight,m_pBits,(LPBITMAPINFO)m_pbih,DIB_RGB_COLORS,SRCCOPY);

int SetDIBitsToDevice(

HDC hdc, // handle to DC

int XDest, // x-coord of destination upper-left corner

int YDest, // y-coord of destination upper-left corner

DWORD dwWidth, // source rectangle width

DWORD dwHeight, // source rectangle height

int XSrc, // x-coord of source lower-left corner

int YSrc, // y-coord of source lower-left corner

UINT uStartScan, // first scan line in array

UINT cScanLines, // number of scan lines

CONST VOID *lpvBits, // array of DIB bits

CONST BITMAPINFO *lpbmi, // bitmap information

UINT fuColorUse // RGB or palette indexes

);

SetDIBitsToDevice(pDC->GetSafeHdc(),nXOff,nYoff,m_nWidth,m_nHeight,0,0,0,m_nHeight,m_pBits,(LPBITMAPINFO)m_pbih,DIB_RGB_COLORS);

-*******************************************

//文件的保存

(24位)文件的保存

void CBmpView::OnFullscreen() {// TODO: Add your command handler code hereHDC hdc,hmemDC;HBITMAP hBitmap,hOldBitmp;//屏幕DC,长度,宽度hdc = CreateDC("DISPLAY",NULL,NULL,NULL);int cx = GetDeviceCaps(hdc,HORZRES);int cy = GetDeviceCaps(hdc,VERTRES);//兼容DC,兼容位图hmemDC = CreateCompatibleDC(hdc);hBitmap = CreateCompatibleBitmap(hdc,cx,cy);hOldBitmp =(HBITMAP)SelectObject(hmemDC,hBitmap);BitBlt(hmemDC,0,0,cx,cy,hdc,0,0,SRCCOPY);hBitmap = (HBITMAP)SelectObject(hmemDC,hOldBitmp);DeleteDC(hdc);DeleteObject(hOldBitmp);//基本长度,宽度BITMAP bm;GetObject(hBitmap,sizeof(bm),&bm);int nWidth = bm.bmWidth;int nHeight = bm.bmHeight;//像素数据大小(byte)DWORD dwBmBitsSize = ((nWidth*24+31)/32)*4*nHeight;BITMAPFILEHEADER bfh={0};BITMAPINFOHEADER bih={0};//文件头信息bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);bfh.bfReserved1 = 0;bfh.bfReserved2 = 0;bfh.bfSize = bfh.bfOffBits + dwBmBitsSize;bfh.bfType = 'MB';//信息头信息bih.biBitCount= 24;bih.biCompression = BI_RGB;bih.biHeight = nHeight;bih.biWidth = nWidth;bih.biPlanes = 1;bih.biSize = sizeof(BITMAPINFOHEADER);bih.biSizeImage = dwBmBitsSize;bih.biClrImportant = 0;bih.biClrUsed= 0;bih.biXPelsPerMeter= 0;bih.biYPelsPerMeter= 0;//位图数据char *pBits = new char[dwBmBitsSize];memset(pBits , 0 , dwBmBitsSize);GetDIBits(hmemDC,hBitmap,0,nHeight,pBits,(LPBITMAPINFO)&bih,DIB_RGB_COLORS);DeleteDC(hmemDC);DeleteObject(hBitmap);//写文件CFile file;file.Open("1.bmp",CFile::modeCreate | CFile::modeWrite);file.Write(&bfh,14);file.Write(&bih,40);file.Write(pBits,dwBmBitsSize);file.Close();delete []pBits;}

如果觉得《位图(BMP)文件格式(一)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。