正文

VC中导入图像(BMP,JPG,GIF)并显示的方法2007-01-16 13:24:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/yuqiexing/22173.html

分享到:

下面要实现的程序是:从磁盘上读取一个jpg,bmp,或者gif图像,然后在程序中用鼠标画出一个矩形,表示图像的显示范围 //打开文件对话框,记下路径名 void CMyView::OnFile() { // TODO: Add your command handler code here CFileDialog dlg(TRUE); dlg.m_ofn.lpstrFilter="All Files(*.*)\0*.*\0textfiles(*.txt)\0*.txt\0\0"; if(dlg.DoModal()==IDOK) {   bmpname=dlg.GetPathName();  Isput=TRUE;  }} //左键单击处理 void CMyView::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default   CClientDC dc(this);   if(Isput==TRUE){     if(pushnumb==0)    {      oldpoint=point;      oripoint=point;      pushnumb=1;      SetCapture();   }  else  {         ReleaseCapture();       float x1=min(oripoint.x,point.x);       float y1=min(oripoint.y,point.y);       float  x2=max(oripoint.x,point.x);       float y2=max(oripoint.y,point.y); //绘制图像       this->DrawJpg(&dc,x1,y1,x2-x1,y2-y1);      //this->DrawBmp1(&dc,x1,y1,             // x2-x1,y2-y1,bmpname,1);      pushnumb=0;   } }  CView::OnLButtonDown(nFlags, point);} //鼠标移动消息处理 void CMyView::OnMouseMove(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default if(Isput==TRUE&&pushnumb==1) {  CClientDC dc(this);  dc.SelectStockObject(NULL_BRUSH); //绘制橡皮线矩形  dc.SetROP2(R2_NOT);  dc.Rectangle(oripoint.x,oripoint.y,oldpoint.x,oldpoint.y);  dc.Rectangle(oripoint.x,oripoint.y,point.x,point.y);  oldpoint=point; } CView::OnMouseMove(nFlags, point);} //绘制图像的过程   void CMyView::DrawJpg(CDC *pDC,int x,int y,int width,int high){ IPicture *pDic; IStream *pStm; CFileStatus fstatus; CFile file; LONG cb;  BOOL bSuccess = TRUE; // 打开文件并获得文件的真实大小 if(file.Open(bmpname,CFile::modeRead) && file.GetStatus(bmpname,fstatus)  && ((cb=fstatus.m_size)!=-1)) {  // 从堆中分配指定数量字节的一整块,这时系统无法提供零零碎碎的局部或全局的堆  HGLOBAL hglobal=::GlobalAlloc(GMEM_MOVEABLE,cb);  LPVOID pvData=NULL;  if(hglobal != NULL)  {   // 锁定全局内存对象并返回它的首地址   if((pvData=::GlobalLock(hglobal))!=NULL)   {    // 把文件内容读进全局内存对象的地址空间中        file.ReadHuge(pvData,cb);     // GlobalUnlock函数把以GMEM_MOVEABLE方式分配的内存对象的锁定计数器减1    ::GlobalUnlock(hglobal);     // 从全局内存中创建stream对象,第二个参数指定当stream释放时是否自动释放全局内存    ::CreateStreamOnHGlobal(hglobal,TRUE,&pStm);     //  创建一个新的picture对象并用stream对象中的内容初始化    if(SUCCEEDED(::OleLoadPicture(pStm,fstatus.m_size,     TRUE,IID_IPicture,(LPVOID*)&pDic)))    {     // 释放不要的stream对象并清空stream指针(千万不能省略,否则有内存没释放掉)     pStm->Release();     pStm = NULL;          OLE_XSIZE_HIMETRIC hmWidth;     OLE_YSIZE_HIMETRIC hmHeight;     pDic->get_Width(&hmWidth);     pDic->get_Height(&hmHeight);      int nImageWidth = MulDiv(hmWidth, ::GetDeviceCaps(pDC->m_hDC, LOGPIXELSX), 2540);     int nImageHeight = MulDiv(hmHeight,::GetDeviceCaps(pDC->m_hDC, LOGPIXELSY), 2540);      // 注意倒数几个参数的选择,可能出现翻转     if(FAILED(pDic->Render(pDC->m_hDC,x,y,nImageWidth ,nImageHeight ,0,hmHeight,      hmWidth,-hmHeight,NULL)))       AfxMessageBox("Failed!");     pDic->Release();    }    else     AfxMessageBox("Error Loading Picture from stream");   }  }  } else  AfxMessageBox("cann't open image file!");} 更新: 如果要获得象素大小,而不是上面的OLE_YSIZE_HIMETRIC ,可以用下面的方法转换:       int width = MulDiv(hmWidth, ::GetDeviceCaps(pDC->m_hDC, LOGPIXELSX), 2540);      int hight = MulDiv(hmHeight,::GetDeviceCaps(pDC->m_hDC, LOGPIXELSY), 2540);   当然如果只是导入bmp格式的不用那么麻烦,编写下面这个函数就可以了 void CMyView::DrawBmp1(CDC *pDC, int x, int y, int width, int high, CString fName, int DrawMode){ CDC dc; dc.CreateCompatibleDC(pDC); //从外部文件导入 HBITMAP b=(HBITMAP)::LoadImage(NULL,fName,IMAGE_BITMAP,0,0,LR_DEFAULTSIZE|LR_LOADFROMFILE); CBitmap bitmap; bitmap.Attach(b); BITMAP bm; bitmap.GetBitmap(&bm); dc.SelectObject(&bitmap); //显示图像 pDC->StretchBlt(x,y,width,high,&dc,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY); bitmap.Detach(); } 其他理论文章导读: http://www.diybl.com/course/3_program/vc/vc_js/2008831/138954.html  

阅读(12489) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册