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; i0)
	{
		for (int i=startnumber;i

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_rectheight_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

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);
	}
}

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

你可能感兴趣的:(C++)