我写的BMP位图打开读取数据与保存函数 为什么最后得到的BMP图片绘图失败? 再UP UP UP 一下!!!! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 你是要把读到的图片数据保存在别的地方吗??我给你一个简单的例子吧:int read_and_write_bmp(char* infilename, char* outfilename){ FILE* infd; FILE* outfd; unsigned char byte; if((infd=fopen(infilename,"rb"))==NULL) { printf("can't open file\n"); return -1; } if((outfd=fopen(outfilename,"wb"))==NULL) { printf("can't open output file\n"); return -1; } while(fread(&byte,sizeof(char),1,infd)!= NULL) { fwrite(&byte,sizeof(char),1,outfd); } fclose(infd); fclose(outfd); return 0;}int main(){ read_and_write_bmp("F:\\1.bmp","F:\\2.bmp"); return 0;}这样就把1.bmp读到2.bmp中了。 to s_rlzheng:我是要读入一个BMP位图的数据然后对他进行旋转等处理后,然后再保存成BMP 位图 分为三个函数写 一个负责打开读取位图数据。一个负责旋转数据,一个负责存储 那为什么我写的那段代码就不能保存数据呢 保存的图片用图片阅读器打开提示绘图失败 但是没有报任何错误 to kittyhuaner:必须考虑吗? 在读入的时候也要把数据写成四字节对齐的格式吗? 处理后也要写成四字节对齐的格式? 我直接读进来,然后旋转一下 我在直接写进文件里不就行了吗? 为什么必须保证四字节对齐呢 这个程序你是每次打开图片就去获取一个Data,然后再对这个Data进行变换,然后再进行保存是吗?如果是这样你就得每次都检查一下你这两行函数:fseek( pFile,offset,SEEK_SET);//指针指到位图像素值起始位置fread(&DataBuf,sizeof(BYTE),BufSize, pFile);是否每次都指对位置,就是你读了第一个数据后,第二次读的时候指针得往后挪,否则每次读到的数据可能会是一样的。另外,最好就不要读一个数据就开关图片一次,效率太低了,整个程序开关一次就够了。 to :s_rlzheng:{【这个程序你是每次打开图片就去获取一个Data,然后再对这个Data进行变换,然后再进行保存是吗?】} 是的我不是读一个数据就打开一次啊 我是利用读数据这个函数把整个图片的像素值直接读到Buffer中 然后进行处理 接着在利用save函数保存 啊 可是你这里不是只调用了一次fread(&DataBuf,sizeof(BYTE),BufSize, pFile); 去读么?不是只读了一个byte的数据就结束了么??我看不到你在哪里读完整个图片数据啊!!! TO s_rlzheng:那您觉得该怎么写这一段呢 我也在愁苦这个问题呢 while(fread(&byte,sizeof(char),1,fd)!= NULL)让它读到末尾才结束啊。不过你的程序恐怕要改改了,最好是边读就边进行转换然后接着保存。转换过程可以写成一个函数,但是读与写就要要写成一个函数了。 如果你自己保存的bmp文件用acdsee或者画笔打开时显示“绘图失败”那么就是你在写入文件时,就没有正确的写入位图文件头和信息头,主要原因就在这,以前我做时就经常遇到。 必须考虑四字节对齐,要不然出来的画面肯定是错的,除非你的图片width*height*colordepth正好是4的倍数 给你个链接看看,希望对你有帮助:http://hi.baidu.com/s%5Frlzheng/blog/item/7b10e910189e3806203f2e23.htmlhttp://hi.baidu.com/s%5Frlzheng/blog/item/1c1cc96ea8bd50dd80cb4a2d.html 就是这个问题,微软规定,位图的每一行的字节数都是4的倍数(这是规定),我本来是想给你找原文,但是找不到了,有个很巧妙的方法,是我们老师教的:void CSDI_BMPView::SaveBmp(CString strPath){ if(strPath.IsEmpty()) return; UINT PicWidth = m_rcSel.Width(); UINT PicHeight= m_rcSel.Height(); //m_rcSel是所选图片区域矩形的大小 UINT PicWidth4; PicWidth4 = (PicWidth*3+3)/4*4; //注意这句 UINT PicSize = PicWidth4 * PicHeight; BITMAPFILEHEADER bmpFileHeader; bmpFileHeader.bfType = ((WORD)(('M'<<8)|'B')); bmpFileHeader.bfSize = 54 + PicSize; bmpFileHeader.bfReserved1 = 0; bmpFileHeader.bfReserved2 = 0; bmpFileHeader.bfOffBits = 54; BITMAPINFOHEADER bmpInfoHeader; bmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER); bmpInfoHeader.biWidth = PicWidth; bmpInfoHeader.biHeight = PicHeight; bmpInfoHeader.biPlanes = 1; bmpInfoHeader.biBitCount = 24; bmpInfoHeader.biCompression = 0; bmpInfoHeader.biSizeImage = PicSize; bmpInfoHeader.biXPelsPerMeter = 0; bmpInfoHeader.biYPelsPerMeter = 0; bmpInfoHeader.biClrUsed = 0; bmpInfoHeader.biClrImportant = 0; BYTE *lpData; lpData = new BYTE[PicSize]; UINT i, j, k, index=0; for(i=0; i<PicHeight; i++) { for(j=0; j<PicWidth; j++) { COLORREF crl = m_dcBK.GetPixel(m_rcSel.left+j, m_rcSel.top+PicHeight-i); lpData[index++] = GetBValue(crl); lpData[index++] = GetGValue(crl); lpData[index++] = GetRValue(crl); } for(k=0; k<PicWidth4 - PicWidth*3; k++) { lpData[index++] = 0; } } CFile ofile(strPath,CFile::modeCreate|CFile::modeWrite); ofile.Write(&bmpFileHeader,sizeof(BITMAPFILEHEADER)); ofile.Write(&bmpInfoHeader,sizeof(BITMAPINFOHEADER)); ofile.Write(lpData,PicSize); ofile.Close(); delete [] lpData;} OPENGL中调用auxDIBImageLoad函数产生的相关问题 为什么用PostMessage 程序就死掉? 如何在组件中添加一个ACTIVE控件? 线程中打开数据库的问题? 句柄和指针有什么异&同? 对话框类中定义了CPoint的两个变量,然后。。。。。。。。。。????? 请教CString/format的用法! 关于虚拟摄像头的问题 用vc++怎么做一个建立ftp服务器端? 如何弹出资源管理器? “std”: 具有该名称的命名空间不存在 如何模拟双击SysListView32里的某一行?
我给你一个简单的例子吧:
int read_and_write_bmp(char* infilename, char* outfilename)
{
FILE* infd;
FILE* outfd;
unsigned char byte;
if((infd=fopen(infilename,"rb"))==NULL)
{
printf("can't open file\n");
return -1;
}
if((outfd=fopen(outfilename,"wb"))==NULL)
{
printf("can't open output file\n");
return -1;
}
while(fread(&byte,sizeof(char),1,infd)!= NULL)
{
fwrite(&byte,sizeof(char),1,outfd);
}
fclose(infd);
fclose(outfd);
return 0;
}int main()
{
read_and_write_bmp("F:\\1.bmp","F:\\2.bmp");
return 0;
}
这样就把1.bmp读到2.bmp中了。
我是要读入一个BMP位图的数据然后对他进行旋转等处理后,然后再保存成BMP 位图 分为三个函数写 一个负责打开读取位图数据。一个负责旋转数据,一个负责存储 那为什么我写的那段代码就不能保存数据呢 保存的图片用图片阅读器打开提示绘图失败 但是没有报任何错误
必须考虑吗? 在读入的时候也要把数据写成四字节对齐的格式吗?
处理后也要写成四字节对齐的格式? 我直接读进来,然后旋转一下 我在直接写进文件里不就行了吗? 为什么必须保证四字节对齐呢
如果是这样你就得每次都检查一下你这两行函数:
fseek( pFile,offset,SEEK_SET);//指针指到位图像素值起始位置
fread(&DataBuf,sizeof(BYTE),BufSize, pFile);
是否每次都指对位置,就是你读了第一个数据后,第二次读的时候指针得往后挪,否则每次读到的数据可能会是一样的。
另外,最好就不要读一个数据就开关图片一次,效率太低了,整个程序开关一次就够了。
{【这个程序你是每次打开图片就去获取一个Data,然后再对这个Data进行变换,然后再进行保存是吗?】} 是的我不是读一个数据就打开一次啊
我是利用读数据这个函数把整个图片的像素值直接读到Buffer中 然后进行处理 接着在利用save函数保存 啊
fread(&DataBuf,sizeof(BYTE),BufSize, pFile);
去读么?不是只读了一个byte的数据就结束了么??
我看不到你在哪里读完整个图片数据啊!!!
那您觉得该怎么写这一段呢 我也在愁苦这个问题呢
让它读到末尾才结束啊。
不过你的程序恐怕要改改了,最好是边读就边进行转换然后接着保存。转换过程可以写成一个函数,但是读与写就要要写成一个函数了。
http://hi.baidu.com/s%5Frlzheng/blog/item/1c1cc96ea8bd50dd80cb4a2d.html
就是这个问题,微软规定,位图的每一行的字节数都是4的倍数(这是规定),我本来是想给你找原文,但是找不到了,有个很巧妙的方法,是我们老师教的:
void CSDI_BMPView::SaveBmp(CString strPath)
{
if(strPath.IsEmpty())
return; UINT PicWidth = m_rcSel.Width();
UINT PicHeight= m_rcSel.Height(); //m_rcSel是所选图片区域矩形的大小
UINT PicWidth4; PicWidth4 = (PicWidth*3+3)/4*4; //注意这句 UINT PicSize = PicWidth4 * PicHeight;
BITMAPFILEHEADER bmpFileHeader;
bmpFileHeader.bfType = ((WORD)(('M'<<8)|'B'));
bmpFileHeader.bfSize = 54 + PicSize;
bmpFileHeader.bfReserved1 = 0;
bmpFileHeader.bfReserved2 = 0;
bmpFileHeader.bfOffBits = 54; BITMAPINFOHEADER bmpInfoHeader; bmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfoHeader.biWidth = PicWidth;
bmpInfoHeader.biHeight = PicHeight;
bmpInfoHeader.biPlanes = 1;
bmpInfoHeader.biBitCount = 24;
bmpInfoHeader.biCompression = 0;
bmpInfoHeader.biSizeImage = PicSize;
bmpInfoHeader.biXPelsPerMeter = 0;
bmpInfoHeader.biYPelsPerMeter = 0;
bmpInfoHeader.biClrUsed = 0;
bmpInfoHeader.biClrImportant = 0; BYTE *lpData;
lpData = new BYTE[PicSize]; UINT i, j, k, index=0;
for(i=0; i<PicHeight; i++)
{
for(j=0; j<PicWidth; j++)
{
COLORREF crl = m_dcBK.GetPixel(m_rcSel.left+j, m_rcSel.top+PicHeight-i);
lpData[index++] = GetBValue(crl);
lpData[index++] = GetGValue(crl);
lpData[index++] = GetRValue(crl);
}
for(k=0; k<PicWidth4 - PicWidth*3; k++)
{
lpData[index++] = 0;
}
}
CFile ofile(strPath,CFile::modeCreate|CFile::modeWrite);
ofile.Write(&bmpFileHeader,sizeof(BITMAPFILEHEADER));
ofile.Write(&bmpInfoHeader,sizeof(BITMAPINFOHEADER));
ofile.Write(lpData,PicSize);
ofile.Close(); delete [] lpData;
}