下面要实现的程序是:从磁盘上读取一个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

评论