关于怎么用C++读取bmp图片
#include"fstream.h"//24bitbitmapboolCBitmapWindow::LoadFile(char*bmpFile){FILE*fp;if(...
#include "fstream.h"//24bit bitmap
bool CBitmapWindow::LoadFile (char *bmpFile)
{
FILE *fp;
if((fp=fopen(bmpFile,"rb"))==NULL)
return false;
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
BITMAPINFOHEADER bih;
fread(&bfType,sizeof(WORD),1,fp);
if(bfType!=0x4d42)
return false;
fread(&bfSize,sizeof(DWORD),1,fp);
fread(&bfReserved1,sizeof(WORD),1,fp);
fread(&bfReserved2,sizeof(WORD),1,fp);
fread(&bfOffBits,sizeof(DWORD),1,fp);
fread(&bih,sizeof(BITMAPINFOHEADER1),1,fp);
nWidth=bih.biWidth ;
nHeight=bih.biHeight;
if(nWidth % 4 !=0)
nWidth=nWidth+ (4-nWidth % 4); //修正位图宽度值
DWORD size=nWidth*bih.biBitCount/8*nHeight;
arrayColor=new ZafLogicalColor[nWidth*nHeight];
// LPSTR pData=new char[size];
unsigned char* pData=new unsigned char[size];
fread(pData,size,1,fp);
int bmWidthBytes=nWidth*bih.biBitCount /8;
int bmBitsPixel=bih.biBitCount ;
int nBit=bmBitsPixel/8;
colorTableBitmap* clrTableBmp;
clrTableBmp=new colorTableBitmap[nWidth*nHeight];
char cBit[40];
int z;
for (int y=0;y<nHeight;y++)
{
for (int x=0;x<nWidth;x++)
{
z=nHeight-y-1;
clrTableBmp[y*nWidth+x].nIndex =y*nWidth+x;
clrTableBmp[y*nWidth+x].iBlue =pData[x*nBit+z*bmWidthBytes];
clrTableBmp[y*nWidth+x].iGreen =pData[x*nBit+1+z*bmWidthBytes];
clrTableBmp[y*nWidth+x].iRed=pData[x*nBit+2+z*bmWidthBytes];
sprintf(cBit,",%d:%d:%d:%d",y*nWidth+x,pData[x*nBit+z*bmWidthBytes],
pData[x*nBit+1+z*bmWidthBytes],
pData[x*nBit+2+z*bmWidthBytes]);
}
}
delete []clrTableBmp;
delete []pData;
fclose(fp);
return true;
网上代码是这样的。。可是我不明白,不知道怎么关联我的本地已有的图片,希望您能搞教诲下。。谢谢,不甚感激 展开
bool CBitmapWindow::LoadFile (char *bmpFile)
{
FILE *fp;
if((fp=fopen(bmpFile,"rb"))==NULL)
return false;
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
BITMAPINFOHEADER bih;
fread(&bfType,sizeof(WORD),1,fp);
if(bfType!=0x4d42)
return false;
fread(&bfSize,sizeof(DWORD),1,fp);
fread(&bfReserved1,sizeof(WORD),1,fp);
fread(&bfReserved2,sizeof(WORD),1,fp);
fread(&bfOffBits,sizeof(DWORD),1,fp);
fread(&bih,sizeof(BITMAPINFOHEADER1),1,fp);
nWidth=bih.biWidth ;
nHeight=bih.biHeight;
if(nWidth % 4 !=0)
nWidth=nWidth+ (4-nWidth % 4); //修正位图宽度值
DWORD size=nWidth*bih.biBitCount/8*nHeight;
arrayColor=new ZafLogicalColor[nWidth*nHeight];
// LPSTR pData=new char[size];
unsigned char* pData=new unsigned char[size];
fread(pData,size,1,fp);
int bmWidthBytes=nWidth*bih.biBitCount /8;
int bmBitsPixel=bih.biBitCount ;
int nBit=bmBitsPixel/8;
colorTableBitmap* clrTableBmp;
clrTableBmp=new colorTableBitmap[nWidth*nHeight];
char cBit[40];
int z;
for (int y=0;y<nHeight;y++)
{
for (int x=0;x<nWidth;x++)
{
z=nHeight-y-1;
clrTableBmp[y*nWidth+x].nIndex =y*nWidth+x;
clrTableBmp[y*nWidth+x].iBlue =pData[x*nBit+z*bmWidthBytes];
clrTableBmp[y*nWidth+x].iGreen =pData[x*nBit+1+z*bmWidthBytes];
clrTableBmp[y*nWidth+x].iRed=pData[x*nBit+2+z*bmWidthBytes];
sprintf(cBit,",%d:%d:%d:%d",y*nWidth+x,pData[x*nBit+z*bmWidthBytes],
pData[x*nBit+1+z*bmWidthBytes],
pData[x*nBit+2+z*bmWidthBytes]);
}
}
delete []clrTableBmp;
delete []pData;
fclose(fp);
return true;
网上代码是这样的。。可是我不明白,不知道怎么关联我的本地已有的图片,希望您能搞教诲下。。谢谢,不甚感激 展开
3个回答
展开全部
可以看下如下的操作:
1、图片文件是有固定格式的,像BMP图片是文件头+位图的颜色数据。
文件头一般在读取的时候是使用下面的代码:
BITMAPFILEHEADER fileheader={0};
fread(&fileheader,sizeof(fileheader),1,fp);
if(fileheader.bfType!=0x4D42) // 判断是否为BMP图片
{
fclose(fp);
return ;
}
BITMAPINFOHEADER head;
fread(&head,sizeof(BITMAPINFOHEADER),1,fp);
long bmpWidth = head.biWidth; //获取图片的宽
long bmpHeight = head.biHeight; //获取图片的宽
WORD biBitCount = head.biBitCount;
if(biBitCount != 24) // 是否为24位位图
{
::AfxMessageBox(_T("请选择24位位图!"));
fclose(fp);
return ;
}
2、文件读到这里了就要读到位图的颜色数据了,那么在读取前,需要知道数据的大小,这样才能把分配具体大学的缓冲区,之后把数据完整的读取到缓冲区内。
那么计算位图数据的大小一般用下面的代码去做。
int totalSize = (bmpWidth *biBitCount/8+3)/4*4*bmpHeight;
BYTE *pBmpBuf = new BYTE[totalSize];
3、在这些工作做完之后,就使用fread命令直接读取文件内容即可,直到读到文件结束。
整个具体的代码实现如下:
FILE *fp=NULL;
int ret = fopen_s(&fp,"D:\\11.bmp","rb");
if(fp==0)
{
return ;
}
BITMAPFILEHEADER fileheader={0};
fread(&fileheader,sizeof(fileheader),1,fp);
if(fileheader.bfType!=0x4D42)
{
fclose(fp);
return ;
}
BITMAPINFOHEADER head;
fread(&head,sizeof(BITMAPINFOHEADER),1,fp);
long bmpWidth = head.biWidth;
long bmpHeight = head.biHeight;
WORD biBitCount = head.biBitCount;
if(biBitCount != 24)
{
::AfxMessageBox(_T("请选择24位位图!"));
fclose(fp);
return ;
}
int totalSize = (bmpWidth *biBitCount/8+3)/4*4*bmpHeight;
BYTE *pBmpBuf = new BYTE[totalSize];
size_t size = 0;
while(true)
{
int iret = fread(&pBmpBuf[size],1,1,fp);
if(iret == 0)
break;
size = size + iret;
}
fclose(fp);
int i,j;
CClientDC dc(this);
int pitch=bmpWidth%4;
for(i=0;i<bmpHeight;i++)
{
int realPitch=i*pitch;
for(j=0;j<bmpWidth;j++)
{
dc.SetPixel(j,i,RGB(
pBmpBuf[(i*bmpWidth+j)*3+2+realPitch],
pBmpBuf[(i*bmpWidth+j)*3+1+realPitch],
pBmpBuf[(i*bmpWidth+j)*3+realPitch]));
}
}
delete [] pBmpBuf; pBmpBuf = NULL;
return ;
展开全部
你好,我把问题补充一下,希望对你有帮助。如果还是不行,你再问我。
在你如下的程序段中:
//读取头文件
fseek( rfile , sizeof(short) ,SEEK_SET );
fread( pointfh ,sizeof(BITMAPFILEHEADER) , 1 , rfile );
//读取信息头文件
fseek( rfile , sizeof(BITMAPFILEHEADER)+sizeof(short) ,SEEK_SET );
fread( pointih ,sizeof(BITMAPINFOHEADER),1, rfile );
//读位图信息
pointimage=(char*)calloc(ih.biSizeImage*3, sizeof(char));
fseek(rfile,fh.bfOffBits,SEEK_SET);//头指针移动到位图区
fread(pointimage,sizeof(char),ih.biSizeImage*3,rfile);
第一句中,我觉得不要加sizeof(short),而是将其改为0。因为文件的前sizeof(BITMAPFILEHEADER)个字节就是 文件信息头,紧接其后的sizeof(BITMAPINFOHEADER)个字节是位图信息头,所以在你的第三条语句中,也应去掉sizeof(short)。另外,biSizeImage就是位图像素信息实际占用的存储空间长度,不需要乘以3,所以在上面第5和第7句中应将“*3”去掉。这时你在运行一下试试。
还有,24位位图每个像素用3个字节表示。你的256像素*256像素的图像的实际占用的字节数应是256*256*3 = 196608,这正是biSizeImage的值!
bmp文件分为四个部分:
文件信息头、位图信息头、调色板、位图信息数据。
你在读信息头文件后,应该读调色板数据。对于真彩色图像,因为没有调色板,所以不用读;但对于其他的图像就需要读了。这是你的代码存在的问题之一。解决办法是根据biBitCount的值判断调色板的大小:若biBitCount为1,调色板大小为2*sizeof(RGBQUAD)字节;若为4,调色板16*sizeof(RGBQUAD);若为8,调色板256*sizeof(RGBQUAD);若为24,调色板为0。
另外,位图信息数据每行存储的字节数一定是4字节的整数倍,不足的时候补0。比如你的图像每行只有一个像素,一个像素用三个字节存储,那么在实际存储该图像时需要在每行多补充一个字节,以使其达到4字节的整数倍。biSizeImage的值就是图像信息数据实际存储的字节数,读的时候直接读这么多字节的数据就行了,不需要乘以3。你的代码在读信图信息时并没考虑这一点,这是存在的问题之二。图像每行存储的实际字节数:nBytesPerLine = biSizeImage / biHeight,这个值在后续的处理中可能会用到。
你说读取的分辨率是3780,是指每米有3780个像素,单位是像素/米。而那个96的单位可能不是像素/米。
希望对你有帮助。
在你如下的程序段中:
//读取头文件
fseek( rfile , sizeof(short) ,SEEK_SET );
fread( pointfh ,sizeof(BITMAPFILEHEADER) , 1 , rfile );
//读取信息头文件
fseek( rfile , sizeof(BITMAPFILEHEADER)+sizeof(short) ,SEEK_SET );
fread( pointih ,sizeof(BITMAPINFOHEADER),1, rfile );
//读位图信息
pointimage=(char*)calloc(ih.biSizeImage*3, sizeof(char));
fseek(rfile,fh.bfOffBits,SEEK_SET);//头指针移动到位图区
fread(pointimage,sizeof(char),ih.biSizeImage*3,rfile);
第一句中,我觉得不要加sizeof(short),而是将其改为0。因为文件的前sizeof(BITMAPFILEHEADER)个字节就是 文件信息头,紧接其后的sizeof(BITMAPINFOHEADER)个字节是位图信息头,所以在你的第三条语句中,也应去掉sizeof(short)。另外,biSizeImage就是位图像素信息实际占用的存储空间长度,不需要乘以3,所以在上面第5和第7句中应将“*3”去掉。这时你在运行一下试试。
还有,24位位图每个像素用3个字节表示。你的256像素*256像素的图像的实际占用的字节数应是256*256*3 = 196608,这正是biSizeImage的值!
bmp文件分为四个部分:
文件信息头、位图信息头、调色板、位图信息数据。
你在读信息头文件后,应该读调色板数据。对于真彩色图像,因为没有调色板,所以不用读;但对于其他的图像就需要读了。这是你的代码存在的问题之一。解决办法是根据biBitCount的值判断调色板的大小:若biBitCount为1,调色板大小为2*sizeof(RGBQUAD)字节;若为4,调色板16*sizeof(RGBQUAD);若为8,调色板256*sizeof(RGBQUAD);若为24,调色板为0。
另外,位图信息数据每行存储的字节数一定是4字节的整数倍,不足的时候补0。比如你的图像每行只有一个像素,一个像素用三个字节存储,那么在实际存储该图像时需要在每行多补充一个字节,以使其达到4字节的整数倍。biSizeImage的值就是图像信息数据实际存储的字节数,读的时候直接读这么多字节的数据就行了,不需要乘以3。你的代码在读信图信息时并没考虑这一点,这是存在的问题之二。图像每行存储的实际字节数:nBytesPerLine = biSizeImage / biHeight,这个值在后续的处理中可能会用到。
你说读取的分辨率是3780,是指每米有3780个像素,单位是像素/米。而那个96的单位可能不是像素/米。
希望对你有帮助。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
呃,我写这类程序的时候用的是GetBitmapBits函数……
这个的话,用LoadFile(本地图片文件名)就行了吧?
这个的话,用LoadFile(本地图片文件名)就行了吧?
来自:求助得到的回答
本回答被提问者采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询