纯c++读取与显示BMP图片

来源:互联网 发布:sqlserver distinct 编辑:程序博客网 时间:2024/05/17 01:53

这是个控制台程序,无论是在VC6.0还是在vs上都能够直接用,这就涉及到纯C++语言的图像处理编程

#include<iostream>#include<Windows.h>#include<malloc.h>#include<stdlib.h>#include<stdio.h>#include<string.h>using namespace std;void main (){char fileName[30];                        //定义打开图像名字char *buf;                                //定义文件读取缓冲区char *p;int r,g,b,pix;HWND wnd;                                 //窗口句柄HDC dc;                                   //绘图设备环境句柄FILE *fp;                                 //定义文件指针FILE *fpw;                                //定义保存文件指针    DWORD w,h;                                //定义读取图像的长和宽    DWORD bitCorlorUsed;                      //定义    DWORD bitSize;                            //定义图像的大小    BITMAPFILEHEADER bf;                      //图像文件头    BITMAPINFOHEADER bi;                      //图像文件头信息cout<<"请输入要打开文件的名字:(如:e:\\1.bmp)";cin>>fileName;if((fp=fopen(fileName,"rb"))==NULL){   cout<<"文件未找到!";   exit(0);}    fread(&bf,sizeof(BITMAPFILEHEADER),1,fp);//读取BMP文件头文件    fread(&bi,sizeof(BITMAPINFOHEADER),1,fp);//读取BMP文件头文件信息w=bi.biWidth;                            //获取图像的宽h=bi.biHeight;                           //获取图像的高bitSize=bi.biSizeImage;                  //获取图像的sizebuf=(char*)malloc(w*h*3);                //分配缓冲区大小fseek(fp,long(sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)),0);//定位到像素起始位置fread(buf,1,w*h*3,fp);                   //开始读取数据wnd=GetForegroundWindow();               //获取窗口句柄dc=GetDC(wnd);                           //获取绘图设备int x=40;int y=40;p=buf;for(int j=0;j<h;j++){for(int i=0;i<w;i++){b=*p++;g=*p++;r=*p++;pix=RGB(r,g,b);SetPixel(dc,x+i,y+h-j,pix);}}fpw=fopen("LenaSaved.bmp","wb");fwrite(&bf,sizeof(BITMAPFILEHEADER),1,fpw);  //写入文件头fwrite(&bi,sizeof(BITMAPINFOHEADER),1,fpw);  //写入文件头信息p=buf;for( j=0;j<h;j++){for(int i=0;i<w*3;i++){fwrite(p++,1,1,fpw);}}fclose(fpw);fclose(fp);//return fp;}

第二次编辑内容:从控制台转向MFC编程,下面的代码可用于单文档和多文档,打开和保存BMP图像

void CMyDIPView::OnOK() { //CFileDialog为VC中打开文件对话框类   BITMAPFILEHEADER bmpHeader;//文件头  BITMAPINFOHEADER bmpInfo;//信息头  CFileDialog dlg(TRUE, "*.BMP", NULL, NULL,"位图文件(*.BMP)|*.bmp;*.BMP|",this);  CFile bmpFile;//记录打开文件      CString strFileName;//记录选择文件路径  if (!dlg.DoModal() == IDOK) return;  strFileName = dlg.GetPathName();   //以只读的方式打开文件  if(!bmpFile.Open(strFileName, CFile::modeRead|CFile::typeBinary)) return;  if (bmpFile.Read(&bmpHeader,sizeof(BITMAPFILEHEADER)) != sizeof(BITMAPFILEHEADER))  {   AfxMessageBox("read bmp header failed!");   return;  }  if (bmpHeader.bfType != 0x4d42)  {   AfxMessageBox("invalid file type!");   return;  }  if (bmpFile.Read(&bmpInfo,sizeof(BITMAPINFOHEADER)) != sizeof(BITMAPINFOHEADER))  {   AfxMessageBox("read bmp infor header failed!");   return;  }  if (bmpInfo.biBitCount != 24)   {  AfxMessageBox("File is not 24 bit.Application doesn't support this kind of file!");   return; }   pBmpInfo = (BITMAPINFO *)new char[sizeof(BITMAPINFOHEADER)];   if (!pBmpInfo)   {    AfxMessageBox("memory error!");    return;   }       //为图像数据申请空间   memcpy(pBmpInfo,&bmpInfo,sizeof(BITMAPINFOHEADER));   DWORD dataBytes = bmpHeader.bfSize - bmpHeader.bfOffBits;   pBmpData = (BYTE*)new char[dataBytes];   if (!pBmpData)   {   AfxMessageBox("memory error!");    delete pBmpData;   return;   }  if (bmpFile.Read(pBmpData,dataBytes) != dataBytes)   {   AfxMessageBox("Read bmp data failed!");    delete pBmpInfo;    delete pBmpData;   return;   }   bmpFile.Close();    CWnd *pWnd=GetDlgItem(IDC_PICTURE);//获得pictrue控件窗口的句柄   CRect rect;   pWnd->GetClientRect(&rect);//获得pictrue控件所在的矩形区域   CDC *pDC=pWnd->GetDC();//获得pictrue控件的DC      //显示图片   pDC->SetStretchBltMode(COLORONCOLOR);    StretchDIBits(pDC->GetSafeHdc(),0,0,rect.Width(),rect.Height(),0,0,bmpInfo.biWidth,bmpInfo.biHeight,pBmpData,pBmpInfo,DIB_RGB_COLORS,SRCCOPY);    iBmpWidth=bmpInfo.biWidth;                        iBmpHeight=bmpInfo.biHeight; // TODO: Add extra validation here}void CMyDIPView::OnSave() { BITMAPFILEHEADER bmpf;//文件头   BITMAPINFOHEADER bmpi;//信息头   int Widthbytes;    CFile bmpFile;   CString strFileName;    CFileDialog dlg(FALSE, "*.BMP", NULL, NULL,"位图文件(*.BMP)|*.bmp;*.BMP|");   if (!dlg.DoModal()==IDC_SAVE) return;    strFileName = dlg.GetPathName();   if (bmpFile.Open(strFileName, CFile::modeCreate | CFile::modeReadWrite) == 0)return; Widthbytes = (iBmpWidth*3+3)/4*4;//位图对齐,确保为4的倍数    /* BITMAPFILEHEADER结构填写 */   bmpf.bfType = 0x4d42;   bmpf.bfOffBits =sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);   bmpf.bfSize = bmpf.bfOffBits + Widthbytes *iBmpHeight;   bmpf.bfReserved1 = 0;   bmpf.bfReserved2 = 0;   /* BITMAPINFOHEADER结构填写 */    bmpi.biSize = sizeof(BITMAPINFOHEADER);  bmpi.biWidth = iBmpWidth;   bmpi.biHeight =iBmpHeight;   bmpi.biPlanes = 1;    bmpi.biBitCount = 24;//24位   bmpi.biCompression = BI_RGB;   bmpi.biSizeImage =0;    bmpi.biXPelsPerMeter = 0;   bmpi.biYPelsPerMeter = 0;   bmpi.biClrUsed = 0;   bmpi.biClrImportant = 0;      bmpFile.Write(&bmpf,sizeof(bmpf));//写文件头;   bmpFile.Write(&bmpi,sizeof(bmpi));//写信息头;    bmpFile.Write(pBmpData,Widthbytes*iBmpHeight);//写图像数据信息;    bmpFile.Close(); // TODO: Add your control notification handler code here}



原创粉丝点击