BMP文件的读写与显示,用VC怎么完成啊

conquerorren 2008-03-19 09:16:23
遇到一个问题,不知道怎么着手解决,就是常见得BMP文件怎么显示问题。
希望高手来指点主要过程,谢谢!!
...全文
589 25 打赏 收藏 举报
写回复
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
UltraBejing 2008-04-30
  • 打赏
  • 举报
回复
我也想知道,正在找這方面的資料~~~~~
疯魔症 2008-04-01
  • 打赏
  • 举报
回复
老师让我们做图像压缩,我刚实现,BMP文件读入内存,显示保存,封装了一个CDIB的类,对存取,操作位图像素,不知道离压缩还有多远.
rover___ 2008-03-31
  • 打赏
  • 举报
回复
从位图文件格式入手开始会很复杂,可以简单研究一种类型(肯定是DIB啦),比如print screen后用画图程序保存下的位图文件。格式是固定的24位,无压缩,没有颜色表,从左下到右上存储象素RGB,文件头取出图象尺寸后就可以直接跳过,直接去取象素值。但要注意行扫描有补零。以后慢慢深入研究其他复杂格式位图文件。这样做能更准确把握和随意操作位图。但效率低下。
不想深入研究位图,就使用API。效率很高。
疯魔症 2008-03-31
  • 打赏
  • 举报
回复
楼上的说的都很多了。
因为我也是刚做完bmp文件的显示保存,提一点个人的建议,首先,你要明白windows编程的一些概念,消息映射,文档,视图,windows下变量的定义方式,匈牙利命名法。
第二,熟悉,bmp文件的结构,如下的数据结构BITMAPFILEHEADER,BITMAPINFO,BITMAPINFOHEADER,RGBQUAD。
第三,是磁盘文件操作。我的感觉就是,以字节为单位操作内存。
q82074740 2008-03-29
  • 打赏
  • 举报
回复
void CDynSplitView2::OnDraw(CDC* pDC)
{
CDSplitDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if(!pDoc ->statedoc&&state2==1)
{
int m_scale=1;
BYTE* pBitmapData = CDibNew1->GetData();
LPBITMAPINFO pBitmapInfo = CDibNew1->GetInfo();
int bitmapHeight = CDibNew1->GetHeight();
int bitmapWidth = CDibNew1->GetWidth();
int scaledWidth = (int)(bitmapWidth * m_scale);
int scaledHeight = (int)(bitmapHeight * m_scale);
if (CDibNew1->GetRGB()) // Has a color table
{
CPalette * hPalette=CreateBitmapPalette(CDibNew1);
CPalette * hOldPalette =
pDC->SelectPalette(hPalette, true);
pDC->RealizePalette();
::StretchDIBits(pDC->GetSafeHdc(),0, 0, bitmapWidth, bitmapHeight,
0, 0, bitmapWidth, bitmapHeight,
pBitmapData, pBitmapInfo,
DIB_RGB_COLORS, SRCCOPY);
pDC->SelectPalette(hOldPalette, true);
::DeleteObject(hPalette);
}
else
{
StretchDIBits(pDC->GetSafeHdc(),
0, 0, scaledWidth, scaledHeight,
0, 0, bitmapWidth, bitmapHeight,
pBitmapData, pBitmapInfo,
DIB_RGB_COLORS, SRCCOPY);
}
}
}
yyunffu 2008-03-29
  • 打赏
  • 举报
回复
用GDI+很方便,各种图形显示都做了封装。
night_elf_1020 2008-03-28
  • 打赏
  • 举报
回复
http://58.251.57.67/down?cid=AD8E903C153527DA8E7AF19A5FEBEED3211E5FB2&t=3&fmt=-
迅雷!
paerxiushi 2008-03-28
  • 打赏
  • 举报
回复
(1).一个DIB位图文件的结构为:
BITMAPFILEHEADER
BITMAPINFOHEADER
RGBQUAD数组
像素数据数组
(2).对于位深度大于8的设备无关位图来说,不存在调色板数据.对于位深度等于或小于8的设备无关位图来说,调色板条目数量可以使用以下公式计算出来:
int nNumPaletteEntries=
1<<BitmapInfoHeader.biBitCount;
(3).设备无关位图可以包含少于可允许的最大值的调色板条目.BITMAPINFOHEADER成员biClrUsed可以用于确定设备无关位图是否已经保存数量明确的调色板条目.如果biClrUsed是0,则设备无关位图文件中包含该设备无关位图色深的最大数量调色板条目.如果它是一个非零值,则设备无关位图文件中的biClrUsed就是调色板的颜色表数量.
(4).在大多数程序中,设备无关位图各行中的字节数等于像素宽乘以每像素的字节数.由于各设备无关位图行的字节数必须是4的偶数倍,因此得不到精确结果.以下代码计算设备无关位图的字节宽度:
int nWidthBytes=BitmapInfoHeader.biWidth;
if(BitmapInfoHeader.biBitCount==16)
nWidthBytes*=2;
else if(BitmapInfoHeader.biBitCount==24)
nWidthBytes*=4;
while((nWidthBytes & 3)!=0)
nWidthBytes++;

在读BMP文件的时候,判断文件中结构BITMAPFILEHEADER中成员bfType是不是“MB”,因为bfType是倒序排列的,所以看上去是“MB”,而且要检查结构尺寸是否合理。
默认情况下,BMP文件中的数据每行按倒序排列,最下行显示最上行数据。
wrhwww 2008-03-25
  • 打赏
  • 举报
回复
首先你要明白BMP文件的结构,然后根据结构一部分一部分的去读

先读BITMAPFILEHEADER ,然后读BITMAPINFOHAEDER,然后读调色板,最后读BMP的数据区OK

在保存文件时也按这个结构去存OK,

显示时在OnDraw中调用StrethBlt函数即可
i_mandy 2008-03-24
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 paerxiushi 的回复:]
cpp文件实现体为:
CDIB::CDIB()
{
m_pDib=NULL;
}

CDIB::~CDIB()
{
if(m_pDib!=NULL)
delete[] m_pDib;
}


// CDIB 成员函数

BOOL CDIB::LoadDIB(const char *lpszFileName)
{
CFile file;
if(!file.Open(CString(lpszFileName),CFile::modeRead))
return FALSE;

BITMAPFILEHEADER BFH;
DWORD dwSize=(DWORD)(file.GetLength()-sizeof(BITMAPFILEHEADER));

unsigne…
[/Quote]我按照你的代码编译后遇到一个问题,打开文件后却无法显示出来,不知是什么问题,望指教
i_mandy 2008-03-24
  • 打赏
  • 举报
回复
向asdf请教,我按照你的程序编译了一下,(我自己修改了几处,我在view类中定义公共变量 LONG height,width;int BmpData并在此处BmpData=GlobalAllocPtr(GHND,ImgSize); 变为BmpData=(int)GlobalAllocPtr(GHND,ImgSize);通过编译后,我点打开文件时,无法在电脑里找到BMP格式文件,望指教.
如能将整个程序发给我更好,多谢.我的邮箱asacool2001@gmail.com
asdf2110 2008-03-20
  • 打赏
  • 举报
回复
举个简单的例子,以256色灰度图为例,可以使用setPixel()方法在OnDraw()里面完成
当然,对于24位真彩色,就要用到StretchDIBits()函数了。
新建一个菜单项,并添加命令响应函数,如下:
void CFractalCodeView::OnRead()
{
// TODO: Add your command handler code here
ReadFile();//此函数为自己添加的成员函数
IsFirstDraw=FALSE;//IsFirstDraw是View类的成员变量
Invalidate();//调用此函数使窗口无效,进行重绘
}
ReadFile()函数的实现如下:

void CFractalCodeView::ReadFile()
{
CString FileName;
CFile BmpFile,NewFile;
LONG i,j;
DWORD LineBytes,ImgSize;
unsigned char *lpBmpData;
CFileDialog FileOpenDlg(TRUE, ".bmp", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
"BMP Files(*.bmp)|*.bmp|All Files(*.*)|*.*||",NULL);

if(FileOpenDlg.DoModal()==IDOK)
{
FileName=FileOpenDlg.GetFileName();
GetDocument()->SetTitle(FileName);
//如果文件打开错误,给出出错信息
BmpFile.Open(FileName,CFile::typeBinary|CFile::modeRead);
BmpFile.Read((unsigned char *)&FileHeader,sizeof(FileHeader));//读入位图的文件标题
BmpFile.Read((unsigned char *)&InfoHeader,sizeof(InfoHeader));//读入位图的信息标题
height=InfoHeader.biHeight;
width=InfoHeader.biWidth;
LineBytes=((long)InfoHeader.biWidth*InfoHeader.biBitCount+31L)/32*4;//位图每行字节数
ImgSize=(DWORD)(LineBytes*InfoHeader.biHeight); //位图实际图像数据大小
BmpFile.Seek(256*sizeof(RGBQUAD),CFile::current);//指针指向位图实际数据
BmpData=GlobalAllocPtr(GHND,ImgSize);
if(BmpData==0)
return ;
BmpFile.Read((unsigned char*)BmpData,ImgSize); //读入位图实际图像数据
for(i=0;i<height;i++)
{//建立图像
lpBmpData=(unsigned char *)BmpData+i*LineBytes;
for(j=0;j<width;j++)
Image[i][j]=(BYTE)(*lpBmpData++);
}
BmpFile.Close();
}
}其中Image为View的成员变量,是二维数组,也可用动态分配的二维指针来表示,这里我们定义它为
BYTE Image[512][512];表示我们能打开的图象最大为512*512,当然也可设置为其他值
接下来就是在OnDraw()中显示了。函数如下:
void CFractalCodeView::OnDraw(CDC* pDC)
{
CFractalCodeDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if(!IsFirstDraw)
{
CDC *pDC;
pDC=GetDC();
for(int i=0;i<height;i++)
for(int j=0;j<width;j++)
pDC->SetPixel(i,j,RGB(Image[width-1-j][i],Image[width-1-j][i],
Image[width-1-j][i]));
}
}
运行时,由于我们点击OnRead()菜单,
(1)调用ReadFile()函数,将数据读入Image【】【】,
(2)IsFirstDraw=FALSE;使得OnDraw()里的if语句为真;
(3)Invalidate()使得当前窗口无效,需对窗口重绘,于是,我们的灰度图就被以画点的形式显示出来了













oakfire 2008-03-20
  • 打赏
  • 举报
回复
见《windows程序设计》第15章
ZiSheng 2008-03-20
  • 打赏
  • 举报
回复
位图文件分大概两部分,一个是位图头,一个是位图数据
Prodiva 2008-03-20
  • 打赏
  • 举报
回复
1.文件头
2.信息头
3调色板
4,数据
读就是了
aj3423 2008-03-20
  • 打赏
  • 举报
回复
用GDI+多方便

Bitmap bitmap;
bitmap = new Bitmap(L"myBmp.bmp");

HDC hdc = GetDC(NULL);
Graphics graphics(hdc);
graphics.DrawImage(bitmap, 0, 0);
ReleaseDC(NULL,hdc);
liu_min731 2008-03-20
  • 打赏
  • 举报
回复
楼上的说的对。
ahuisafe 2008-03-20
  • 打赏
  • 举报
回复
LoadImage,BitBlt msdn
菜牛 2008-03-20
  • 打赏
  • 举报
回复
简单点,LoadImage,BitBlt;这些问题一般Windows编程书上都有,最好先看看书。
conquerorren 2008-03-19
  • 打赏
  • 举报
回复
能给我具体讲下那个实现过程吗>
例如我想先从文件里打开一个文件载入到运行环境中怎么实现
然后怎么读取,能讲下为什么吗》谢谢!
加载更多回复(5)
发帖
图形处理/算法

1.9w+

社区成员

VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
帖子事件
创建了帖子
2008-03-19 09:16
社区公告
暂无公告