BMP 全解

本文总结了BMP格式的相关知识,包括DDB和DIB的区别,以及解码过程中遇到的问题:如信息头结构体对齐、宽度4字节对齐、像素起点位置、颜色格式转换等。此外,详细介绍了1bit到32bit不同位深BMP的解码方法,包括调色板索引、颜色格式转换等,并提到4bit和8bit的RLE压缩情况。
摘要由CSDN通过智能技术生成

好久没写东西咯,最近一种忙图片效果,这两天吧BMP做了,总想记录下东西下来吧,所以总结了下。本想把之前的TGA,PNG,GIF的都再一起重新总结一下,可惜时间不多,那就暂时先把BMP总结咯,位图的资料网上有很多,我只总结下自己在解码过程中遇到的几个问题。

BMP格式

   BMP格式是常见的格式,早期windows3.0以前,底层图片基本上都使用BMP,所以叫DDB(device depande BMP),windows3.0以后开始脱离BMP,叫DIB(device indepande BMP).

解码过程中遇到的几个问题:

1. 信息头54个字节,在定义信息头结构体的时候要注意所在的平台,注意int是4个字节还是2个字节,往往会因为结构体自动对齐的问题使得头信息结构体算出长度为56,此时就需要将结构体声明为2字节对齐,方法是使用#pragma pack(2

void CExample10View::OnSave555BiBitfields() { // TODO: Add your command handler code here if(lpBmpDataBuf==NULL) { MessageBox("当前没有打开的位图"); return; } BYTE r,g,b; LPBYTE lpDest,lpSrc; int i,j; int nheapSize; CFileDialog filesavebox(FALSE,"bmp","BI_BITFIELDS.bmp",OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,"files(*.bmp)|*.bmp|",NULL); CFile file; CString strPathname; if(m_bmi.biBitCount!=24) { MessageBox("当前打开的位图不是24位位图"); return; } memcpy(&m_newbmf,&m_bmf,sizeof(BITMAPFILEHEADER)); memcpy(&m_newbmi,&m_bmi,sizeof(BITMAPINFOHEADER)); m_newbmi.biBitCount=16; m_newbmi.biCompression=BI_BITFIELDS;//即3 m_newbmi.biSizeImage=WIDTHBYTES(m_newbmi.biWidth,m_newbmi.biBitCount)*m_newbmi.biHeight; m_newbmf.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(DWORD)*3 +WIDTHBYTES(m_newbmi.biWidth,m_newbmi.biBitCount)*m_newbmi.biHeight; m_newbmf.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(DWORD)*3; nheapSize=sizeof(BITMAPINFOHEADER)+sizeof(DWORD)*3 +WIDTHBYTES(m_newbmi.biWidth,m_newbmi.biBitCount)*m_newbmi.biHeight; if(lpnewBmpDataBuf!=NULL) { delete []lpnewBmpDataBuf; lpnewBmpDataBuf=NULL; } lpnewBmpDataBuf=new BYTE[nheapSize]; memcpy(lpnewBmpDataBuf,&m_newbmi,sizeof(BITMAPINFOHEADER)); DWORD* lp=(DWORD*)(lpnewBmpDataBuf+sizeof(BITMAPINFOHEADER)); *lp++=0x00007c00; *lp++=0x000003e0; *lp =0x0000001f; for(i=0;i<m_newbmi.biHeight;i++) { for(j=0;j<m_newbmi.biWidth;j++) { lpSrc=lpBmpDataBuf+sizeof(BITMAPINFOHEADER) +WIDTHBYTES(m_bmi.biWidth,m_bmi.biBitCount)*(m_bmi.biHeight-1-i) +j*3; lpDest=lpnewBmpDataBuf+sizeof(BITMAPINFOHEADER)+sizeof(DWORD)*3 +WIDTHBYTES(m_newbmi.biWidth,m_newbmi.biBitCount)*(m_newbmi.biHeight-1-i) +j*2; b=*lpSrc++; b&=0xf8; g=*lpSrc++; g&=0xf8; r=*lpSrc++; r&=0xf8; WORD* lp=(WORD*)lpDest; *lp=0; *lp=r<<7; *lp+=(g<>3); } } if(filesavebox.DoModal()!=IDOK) return; strPath
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值