使用CPicture类绘制放大镜看图

本文介绍了如何使用CPicture类解决CImage类在显示放大镜时出现的问题。通过CPicture类加载和显示JPEG图像,并利用双缓冲技术实现放大镜效果,解决了图像失真和显示效率低下的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        在前面文章中阐述了用CImage类绘图,和绘制放大镜,如果设置HALFTONE此模式,图像才不会失真,但是放大镜上面显示的图像会出现白色斑点,在window sever操作系统中运行,白色斑点不会出现,目前测试在window 7操作系统中发现任然有此问题,而且使用HALFTONE模式显示jpg图像,虽然不失真,但是显示效率明显很慢,放大镜移动起来,视觉效果很差。

       针对前面的显示问题,使用网上流传的CPicture类来实现jpg图像的显示以及放大镜功能,可以很好的解决此问题。

      CPicture类如下:

    

#ifndef PICTURE_H
#ifndef picture_h

#define PICTURE_H
#define picture_h


#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000


class CPicture
{
public:
 CPicture();
 virtual ~CPicture();

public:
 BOOL LoadPicture(UINT nResource, LPCTSTR lpszResType)
 {return LoadPicture(MAKEINTRESOURCE(nResource), lpszResType);}
 BOOL LoadPictureFromFile(LPCTSTR lpszFileName);
 BOOL LoadPicture(LPCTSTR lpszResource,LPCTSTR lpszResType);
 BOOL IsValid(){ return m_pPic!=NULL;}
 CSize GetSize(){return m_size;}
 void Draw(CDC* pDC, LPCRECT lprcDest, LPCRECT lprcSrc);
 void Draw(CDC* pDC, int xDest,int yDest, int cxDest, int cyDest ,
  int xSrc ,int ySrc ,int cxSrc ,int cySrc);

 void Release();

protected:
 IPicture*   m_pPic;

 OLE_XSIZE_HIMETRIC   _w_him;
 OLE_YSIZE_HIMETRIC   _h_him;

 CSize     m_size;

protected:
 void CalcSize();
};


#endif // define picture_h
#endif // define PICTURE_H

 

#include "stdafx.h"
#include "Picture.h"


#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif


//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CPicture::CPicture()
:m_pPic(NULL), _h_him(0), _w_him(0), m_size(0,0)
{
}

CPicture::~CPicture()
{
 Release();
}

void CPicture::Release()
{
 if(m_pPic != NULL)
 {
  m_pPic->Release();
  m_pPic = NULL;
  _h_him = _w_him = 0;
  m_size.cx = m_size.cy = 0;
 }
}

BOOL CPicture::LoadPicture(LPCTSTR lpszResource, LPCTSTR lpszResType)
{
 Release();

 HINSTANCE  hInst = AfxFindResourceHandle(lpszResource, lpszResType);
 HRSRC hRsrc = ::FindResource(hInst, lpszResource, lpszResType);
 if(hRsrc == NULL) return FALSE;
 HGLOBAL hGlobal = LoadResource(hInst, hRsrc);

 if(hGlobal == NULL) return FALSE;


 DWORD dwSize = SizeofResource(hInst, hRsrc);

 HGLOBAL hMem = ::GlobalAlloc(GMEM_MOVEABLE, dwSize);
 if(hMem == NULL) return  FALSE;

 LPVOID  pSrc = ::LockResource(hGlobal);
 if(pSrc == NULL) {
  ::GlobalFree(hMem);
  return FALSE;
 }

 LPVOID pDes = ::GlobalLock(hMem);
 if(pDes == NULL){
  //::GlobalUnlock(hGlobal);
  ::GlobalFree(hMem);
  return FALSE;
 }

 memcpy(pDes, pSrc, dwSize);

 //GlobalUnlock(hGlobal);
 GlobalUnlock(hMem);

 ::FreeResource(hGlobal);

 IStream* pStm = NULL;
 CreateStreamOnHGlobal(hMem, TRUE, &pStm);

 if(!SUCCEEDED(OleLoadPicture(pStm,dwSize,TRUE,IID_IPicture,(LPVOID*)&m_pPic)))
 {
  pStm -> Release();
  ::GlobalFree(hMem);
  pStm = NULL;
  return FALSE;
 }

 pStm->Release();
 ::GlobalFree(hMem);

 CalcSize();
 return TRUE;

}

BOOL CPicture::LoadPictureFromFile(LPCTSTR lpszFileName)
{
 Release();

 CFile   file;
 if(!file.Open(lpszFileName, CFile::modeRead))
  return FALSE;

 DWORD dwSize = file.GetLength();

 HGLOBAL hMem = ::GlobalAlloc(GMEM_MOVEABLE, dwSize);
 if(hMem == NULL) return  FALSE;

 LPVOID pDes = ::GlobalLock(hMem);
 if(pDes == NULL){
  ::GlobalFree(hMem);
  return FALSE;
 }

 //file.ReadHuge(pDes, dwSize);
 file.Read(pDes,dwSize);
 file.Close();

 GlobalUnlock(hMem);

 IStream* pStm = NULL;
 CreateStreamOnHGlobal(hMem, TRUE, &pStm);

 if(!SUCCEEDED(OleLoadPicture(pStm,dwSize,TRUE,IID_IPicture,(LPVOID*)&m_pPic)))
 {
  pStm -> Release();
  ::GlobalFree(hMem);
  pStm = NULL;
  return FALSE;
 }

 pStm->Release();
 ::GlobalFree(hMem);

 CalcSize();
 return TRUE;

}

如何用此类实现放大镜功能呢?如下利用双缓冲技术,实现放大镜


 CDC * pDC=GetDlgItem(IDC_DISIMAGE_STATIC)->GetDC();
 //创建内存DC
 CDC dcMem;
 dcMem.CreateCompatibleDC(pDC);               //依附窗口DC创建兼容内存DC
 CBitmap bmp;                                                 //内存中承载临时图象的位图
 bmp.CreateCompatibleBitmap(pDC,1224,1024);//创建兼容位图
 dcMem.SelectObject(&bmp);  

m_Image.Draw(&dcMem,CRect(0,0,816,682),CRect(0,0,2448,2048));//绘制原始图像

m_Image.Draw(&dcMem,ndRect.left,ndRect.top,ndRect.Width(),ndRect.Height(),nsRect.left*3,nsRect.top*3,nsRect.Width()*3,nsRect.Height()*3);//绘制放大镜

  pDC->BitBlt(0,0,816,682,&dcMem,0,0,SRCCOPY);//将内存DC上的图象拷贝到前台

  dcMem.DeleteDC();                                       //删除DC
  bmp.DeleteObject();                                        //删除位图

ReleaseDC(pDC);

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值