CImage实现多张图像的查看以及图像自由缩放,拖动

CImage提供了增强的位图支持,包括加载和保存 JPEG、 GIF、 BMP 和可移植网络图形 (PNG) 格式的图像的能力。为加载图像提供了更方便,更多样的选择,本文以CImage为核心实现多张图像的查看以及图像缩放,拖动。

1.载入图像

void XXXDlg::OnDropFiles(HDROP hDropInfo)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	int  nFileCount = ::DragQueryFile(hDropInfo, 0xFFFFFFFF, NULL, 256);   //获取拖入的文件数量
	char * pFilePath = new char[256];
	int startnumber=0;
	if (nFileCount!=0)
	    startnumber=m_arFile.GetCount();
	
	for (int i=startnumber; i<startnumber+nFileCount; i++)
	{
		UINT nChars = ::DragQueryFile(hDropInfo, i-startnumber, pFilePath,256);   // 获取拖入的第i个文件的文件名
		CString m_FilePath(pFilePath, nChars); 
		m_arFile.Add(m_FilePath);
	}

	if (m_arFile.GetCount()>0)
	{
		for (int i=startnumber;i<m_arFile.GetCount();i++)
		{
			m_jpegFile.Add(loadraw(m_arFile.GetAt(i)));//解码CR2数据
			CString imginfo;
			imginfo.Format("Image:%s  Maker:%s  Model:%s  Iso:%.2f Tv:%.2f  Av :%.2f  Date:%s",
				LinsnData.imgdata.filename,
				LinsnData.imgdata.make,
				LinsnData.imgdata.model,
				LinsnData.imgdata.iso_speed,
				LinsnData.imgdata.shutter,
				LinsnData.imgdata.aperture,
				LinsnData.imgdata.timestamp);
			m_imageinfo.Add(imginfo);
		}
		LinsnData.imgdata.imgnumber=startnumber;
		CString img_name=m_jpegFile.GetAt(LinsnData.imgdata.imgnumber);
		Showjpeg(img_name);
		SetWindowText(m_imageinfo.GetAt(LinsnData.imgdata.imgnumber));
	}
	delete[] pFilePath;

	::DragFinish (hDropInfo);

	CDialog::OnDropFiles(hDropInfo);
}

2.显示图像

void XXXDlg::Showjpeg()
{
	if (image.IsNull())return;
	int cx, cy;  
	cx  = image.GetWidth();  
	cy  = image.GetHeight();  
	CWnd *pWnd = NULL;  
	pWnd= GetDlgItem(IDC_STATIC_IMG);//获取图像控件句柄
	pWnd->GetClientRect(&imgrect);

	if (zoom<1.0)zoom=1.0;
	if(zoom>(double)cy/(double)imgrect.Height())
		zoom=(double)cy/(double)imgrect.Height();

	//理论显示图像大小
	double img_width=(double)cx/zoom;
	double img_height=(double)cy/zoom;

	//计算显示该图片不失真(及长宽比不变)需要的界面尺寸
	double scal_image=double(img_width)/double(img_height);
	int width_rect=int(scal_image*double(imgrect.Height()));
	int height_rect=int(double(imgrect.Width())/scal_image);

	if (width_rect<imgrect.Width())
	{
		int leave=(imgrect.Width()-width_rect)/2;
		imgrect.left+=leave;
		imgrect.right-=leave;
	}
	if (height_rect<imgrect.Height())
	{
		int leave=(imgrect.Height()-height_rect)/2;
		imgrect.top+=leave;
		imgrect.bottom-=leave;
	}

	//计算该界面下能显示的图像正确尺寸
	double scal_rect=double(imgrect.Width())/double(imgrect.Height());
	int width_img=int(scal_rect*img_height);
	int height_img=int(img_width/scal_rect);
	if (img_height>height_img)
	{
		img_height=height_img;
	} 
	if(img_width>width_img)
	{
		img_width=width_img;
	}

	//计算缩放后全图像大小 
	double imgawidth=(double)imgrect.Width()*zoom;
	double imgaheight=(double)imgrect.Height()*zoom;
	//计算图像变化比例
	img_change=((double)cx/imgawidth);

	//将鼠标移动距离转换为图像移动距离
	pointmove.x=double(pointmove.x)*img_change;
	pointmove.y=double(pointmove.y)*img_change;

	if (pointcur.x-pointmove.x<0)pointcur.x=pointmove.x=0;
	if (pointcur.y-pointmove.y<0)pointcur.y=pointmove.y=0;
	if (pointcur.y-pointmove.y+img_height>(int)cy)pointmove.y=(pointcur.y+img_height)-cy;
	if (pointcur.x-pointmove.x+img_width>(int)cx)pointmove.x=(pointcur.x+img_width)-cx;

	//计算图像的左上角坐标
	imgcurpos.x=(double)(pointcur.x-pointmove.x);
	imgcurpos.y=(double)(pointcur.y-pointmove.y);

	if(wheelflag) //缩放标志位
	{
		CPoint afterchange;
		afterchange.x=curpos.x-double(mousepos.x)*img_change;//计算缩放后图像左上角的变化
		afterchange.y=curpos.y-double(mousepos.y)*img_change;

		//计算图像的左上角坐标
		imgcurpos.x+=afterchange.x;
		imgcurpos.y+=afterchange.y;
		if (imgcurpos.x<0)imgcurpos.x=0;
		if (imgcurpos.y<0)imgcurpos.y=0;
		if (imgcurpos.x+img_width>(int)cx)  imgcurpos.x=(pointcur.x+img_width)-cx;
		if (imgcurpos.y+img_height>(int)cy) imgcurpos.y=(pointcur.y+img_height)-cy;
	}

	//
	CDC *pDc = NULL;  
	pDc = pWnd->GetDC();//获取picture control的DC 

	int ModeOld=SetStretchBltMode(pDc->m_hDC,STRETCH_HALFTONE); 
	//从源矩形中复制一个位图到目标矩形,按目标设备设置的模式进行图像的拉伸或压缩
	image.StretchBlt(pDc->m_hDC,
		imgrect.left,imgrect.top,imgrect.Width(),imgrect.Height(),//界面显示区域
		imgcurpos.x,imgcurpos.y,int(img_width),(int)img_height,//图像显示的区域
		SRCCOPY);
	SetStretchBltMode(pDc->m_hDC,ModeOld); 
	ReleaseDC(pDc); 
}

3.图像缩放

BOOL XXXDlg::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
	ScreenToClient(&pt);
	if (imgrect.PtInRect(pt)&&m_arFile.GetCount()>0)
	{	
		mousepos.x=pt.x-imgrect.left;//计算鼠标在图像显示区域的坐标
		mousepos.y=pt.y-imgrect.top;
		curpos.x=double(mousepos.x)*img_change;//计算鼠标在图像坐标系下的坐标
		curpos.y=double(mousepos.y)*img_change;
		if (nFlags==MK_CONTROL)
		{
			if (zDelta>0)zoom+=0.1;
			else  zoom-=0.1;
			wheelflag=TRUE;
			Showjpeg();
			wheelflag=FALSE;
			pointcur.x=imgcurpos.x;//记录当前图像左上角坐标
			pointcur.y=imgcurpos.y;
		}
	}
	
	return CDialog::OnMouseWheel(nFlags, zDelta, pt);
}

4.拖动显示

void XXXDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
	if (imgrect.PtInRect(point)&&m_arFile.GetCount()>0)
	{
		pointbefor=point;//记录鼠标点击的坐标
		HCURSOR hCur = LoadCursor( NULL , IDC_HAND ) ;
		::SetCursor(hCur);
	}
	CDialog::OnLButtonDown(nFlags, point);
}
void XXXDlg::OnMouseMove(UINT nFlags, CPoint point)
{
	if (nFlags==MK_LBUTTON&&m_arFile.GetCount()>0)
	{
		if (imgrect.PtInRect(point))
		{		
			HCURSOR hCur = LoadCursor( NULL , IDC_HAND) ;
			::SetCursor(hCur);
            //计算鼠标移动的距离
			pointmove.x=point.x-pointbefor.x;
			pointmove.y=point.y-pointbefor.y;
			Showjpeg();
		}
	}
	CDialog::OnMouseMove(nFlags, point);
}
void XXXDlg::OnLButtonUp(UINT nFlags, CPoint point) 
{
	HCURSOR hCur = LoadCursor( NULL , IDC_ARROW  ) ;
	::SetCursor(hCur);
    //记录图像所在位置
	pointcur.x=imgcurpos.x;
	pointcur.y=imgcurpos.y;
    //移动距离清零
	pointmove.x=0;
    pointmove.y=0;
	CDialog::OnLButtonUp(nFlags, point);
}

5.多张图像的切换

void XXDlg::OnBnClickedButtonLast()
{
	if (m_jpegFile.GetCount()!=0)
	{
		if(LinsnData.imgdata.imgnumber>0)
		{
			LinsnData.imgdata.imgnumber--;
			CString img_name=m_jpegFile.GetAt(LinsnData.imgdata.imgnumber);
			Showjpg(img_name);
			SetWindowText(m_imageinfo.GetAt(LinsnData.imgdata.imgnumber));
		}
		else if(LinsnData.imgdata.imgnumber==0)
		{
			MessageBoxTimeoutA(NULL,"This is the first image!","Image",MB_OK,LANG_ENGLISH,800);
		}
		else
		{
			MessageBoxTimeoutA(NULL,"Error!","Image",MB_OK,LANG_ENGLISH,800);
		}
	}
	else
	{
		MessageBoxTimeoutA(NULL,"No image loading!","Image",MB_OK,LANG_ENGLISH,800);
	}
}
void XXXDlg::OnBnClickedButtonNext()
{
	if (m_jpegFile.GetCount()!=0)
	{
		if(LinsnData.imgdata.imgnumber<m_arFile.GetCount()-1)
		{
			LinsnData.imgdata.imgnumber++;
			CString img_name=m_jpegFile.GetAt(LinsnData.imgdata.imgnumber);
			Showjpg(img_name);
			SetWindowText(m_imageinfo.GetAt(LinsnData.imgdata.imgnumber));
		}	
		else if(LinsnData.imgdata.imgnumber==m_jpegFile.GetCount()-1)
		{
			MessageBoxTimeoutA(NULL,"This is the last image!","Image",MB_OK,LANG_ENGLISH,800);
		}
		else
		{
			MessageBoxTimeoutA(NULL,"Error!","Image",MB_OK,LANG_ENGLISH,800);
		}
	}
	else
	{
		MessageBoxTimeoutA(NULL,"No image loading!","Image",MB_OK,LANG_ENGLISH,800);
	}
}
//注意使用MessageBoxTimeout要添加如下代码
extern "C"
{
	int WINAPI MessageBoxTimeoutA(IN HWND hWnd, IN LPCSTR lpText, IN LPCSTR lpCaption, IN UINT uType, IN WORD wLanguageId, IN DWORD dwMilliseconds);
	int WINAPI MessageBoxTimeoutW(IN HWND hWnd, IN LPCWSTR lpText, IN LPCWSTR lpCaption, IN UINT uType, IN WORD wLanguageId, IN DWORD dwMilliseconds);
};
#ifdef UNICODE
#define MessageBoxTimeout MessageBoxTimeoutW
#else
#define MessageBoxTimeout MessageBoxTimeoutA
#endif

6.图像另存为的实现

void XXXDlg::OnBnClickedBtnSave()
{
	if (m_jpegFile.GetCount()>0)
	{
		CFileDialog fileDlg(false,".jpg","*.jpg",OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,
			"Image files(*.bmp;*.gif;*.jpg;*.png)|*.bmp;*.gif;*.jpg;*.png|\
			Bitmap files(*.bmp)|*.bmp|\
			Graphics Interchange Format Files(*.gif)|*.gif|\
			Joint Photographic Experts Group[JPEG]Files(*.jpg)|*.jpg|\
			Portable Network Graphics Files(*.png)|*.png|\
			All Flies(*.*)|*.*||");
		if(fileDlg.DoModal()==IDOK)
		{
			CString strpath=fileDlg.GetPathName();
			HRESULT hResult=image.Save(strpath);
			if(FAILED(hResult))
			{
				MessageBox(_T("Saving image failed!"));
			}
		}
	}
	else
	{
		MessageBoxTimeoutA(NULL,"No image loading!","Image",MB_OK,LANG_ENGLISH,800);
	}
}

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
MFC (Microsoft Foundation Class) 是一组用于开发 Windows 应用程序的 C++ 类库。CImage是MFC中用于处理图像的类之一。要实现图像缩放功能,可以使用CImage类的Resize方法。 首先,我们需要加载一个图像文件到CImage对象中。可以使用CImage类的Load方法来完成这一步骤。例如,可以使用下面的代码加载一个名为"image.bmp"的图像文件: CImage image; image.Load(_T("image.bmp")); 接下来,我们需要创建一个新的CImage对象,用来存储缩放后的图像。可以使用CImage类的Create方法来创建一个指定大小的图像对象。例如,可以使用下面的代码创建一个大小为200x200像素的新图像对象: CImage newImage; newImage.Create(200, 200, image.GetBPP()); 然后,我们可以使用CImage类的Resize方法将原始图像缩放到指定大小。可以将原始图像对象和新图像对象作为参数传递给Resize方法。例如,可以使用下面的代码将原始图像缩放为200x200像素的尺寸: image.Resize(newImage.GetDC(), 0, 0, 200, 200, SRCCOPY); 最后,我们需要保存缩放后的图像。可以使用CImage类的Save方法将新图像保存为文件。例如,可以使用下面的代码将新图像保存为"resized_image.bmp": newImage.Save(_T("resized_image.bmp")); 综上所述,要使用MFC CImage实现图像缩放功能,我们需要加载图像文件,创建新的图像对象,调用Resize方法进行缩放,最后保存缩放后的图像
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值