正文

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

 

阅读(10391) | 评论(0)


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

评论

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