MFC中显示图像的放大、缩小、移动功能
BOOL StretchBlt(HDC hdcDest, int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest, HDC hdcSrc, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc, DWORD dwRop);
一种是CDC的成员函数是这样的:
BOOL StretchBlt( int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, DWORD dwRop );
在实现时有两点要注意
- 显示模式,使用SetStretchBltMode来控制像素在拉伸,缩小时的像素运算。在拉伸位图时一般不需要修改,在压缩位图显示时,默认值会出现颜色失真,这时可以使用HALFTONE模式。
- 在StrectchBlt中xSrc,ySrc为拷贝设备的逻辑坐标,在拷贝位图后在边缘是有一个逻辑单位的空白的,这点在放大图片对xSrc,ySrc进行设置容易被忽略。
目的描述
- 显示位图,鼠标点击图片,以所点击图片的位置为中心按照一定比例系数对图片显示进行放大缩小操作。
- 移动位图显示窗口,按下鼠标右键可以拖动位图的显示位置,对位图的显示区进行移动操作。
思路
通过WM_LBUTTONDOWN或WM_LBUTTONCLICK来获取鼠标的动作的坐标,通常是CClientDC的逻辑坐标,如果是采用文档模式则一般CClientDC和显示窗口是一致的。如果采用PictureControl在窗口应用程序当中显示时,可以先获得PictureControl区域的屏幕坐标再转换成CClientDC的坐标。经过PicturenControl左上角坐标的计算,就可以得到鼠标点击位置在PictureControl区域中的逻辑坐标。再通过该坐标计算出在原设备区中的逻辑坐标,通过该逻辑坐标就可以计算出鼠标所在点在位图上的坐标。知道该位图上坐标后,就可以对原设备区进行拉伸,缩小,移动的操作了。
实现
放大,缩小
CStatic m_sPreview;//PictureControl 控件
CPoint m_CurClientPoint;//当前鼠标位置所在客户区的逻辑坐标
int m_iMultiple;//图像缩放显示倍数
enum PreviewType{enlarge,narrow,restore,move};
PreviewType m_nPrevewType;//命令模式
CPoint m_OriginSrcPoint;//显示图像右上角坐标
unsigned int iWidth,iHeight;//iWidth与iHeight是图片的横纵像素的数目
...
ClientToPictureControl(&m_sPreview,&m_CurClientPoint);
PictureControlToBmp(m_nWidthDest,m_nHeightDest,m_nWidthSrc,m_nHeightSrc,&m_OriginSrcPoint,&m_CurClientPoint);
m_nWidthSrc=iWidth/m_iMultiple;
m_nHeightSrc=iHeight/m_iMultiple;
Mutiply(m_nPreviewType,&m_OriginSrcPoint,&m_CurClientPoint,m_nWidthSrc,m_nHeightSrc);
m_nYOriginSrc=m_OriginSrcPoint.y;//
m_nXOriginSrc=m_OriginSrcPoint.x;//
函数ClientToPictureControl功能为得到该点再控件坐标系的。
void ClientToPictureControl(CStatic *picControl,CPoint *point)//得到picControl在客户区的逻辑位置
{
CWnd *pWnd;
pWnd=picControl;
CRect tmp;
pWnd->GetWindowRect(&tmp);//控件窗口位置
ScreenToClient(&tmp);
*point = *point - tmp.TopLeft();
}
函数PictureControlToBmp功能是为得到鼠标位置在图像坐标系下的像素坐标
void PictureControlToBmp(int nWidthDest,int nHeightDest,int nWidthSrc,int nHeightSrc,
CPoint *Origin,CPoint *point)
{
point->x = point->x * nWidthSrc / nWidthDest+ Origin->x;
point->y= point->y * nHeightSrc / nHeightDest+ Origin->y;
}
函数Mutiply//是调整显示右上角坐标的。
void Mutiply(PreviewType type,CPoint *Origin,CPoint *point, int width,int height)
{
switch (type)
{
case CAlphaDlg::enlarge:
if(point->x-width/>)
{
if(m_pMyDevice->m_sFrInfo.iWidth > point->x+width/){
Origin->x=point->x-width/;}
else{
Origin->x=m_pMyDevice->m_sFrInfo.iWidth-width;
}
}
else
{
Origin->x=;
}
if(point->y-height/>)
{
if(m_pMyDevice->m_sFrInfo.iHeight> point->y+height/){
Origin->y=point->y-height/;}
else{
Origin->y=m_pMyDevice->m_sFrInfo.iHeight-height;
}
}
else
{
Origin->y=;
}
break;
case CAlphaDlg::narrow:
if(point->x-width/>)
{
if(m_pMyDevice->m_sFrInfo.iWidth > point->x+width/){
Origin->x=point->x-width/;}
else{
Origin->x=m_pMyDevice->m_sFrInfo.iWidth-width;
}
}
else
{
Origin->x=;
}
if(point->y-height/>)
{
if(m_pMyDevice->m_sFrInfo.iHeight> point->y+height/){
Origin->y=point->y-height/;}
else{
Origin->y=m_pMyDevice->m_sFrInfo.iHeight-height;
}
}
else
{
Origin->y=;
}
break;
case CAlphaDlg::restore:
Origin->x=;
Origin->y=;
break;
case CAlphaDlg::move:
break;
default:
break;
}
}
以上,是图像放大缩小的步骤。
如果移动图像和上面类似,直接响应WM_MOUSEMOVE消息
void OnMouseMove(UINT nFlags, CPoint point)
{
if(m_bTool==TRUE&&m_nPreviewType==move)
{SetCursor(LoadCursor(NULL,IDC_SIZEALL));
CRect rect;
switch (nFlags)
{
case MK_LBUTTON:
if(m_CurClientPoint!=point)
{
if(m_nXOriginSrc+(-point.x+m_CurClientPoint.x)/m_iMultiple>)
{
if(m_nXOriginSrc+(-point.x+m_CurClientPoint.x)/m_iMultiple + m_nWidthSrc< m_pMyDevice->m_sFrInfo.iWidth)
m_nXOriginSrc=m_nXOriginSrc+(-point.x+m_CurClientPoint.x)/m_iMultiple;
}
else
{
m_nXOriginSrc=;
}
if(m_nYOriginSrc+(-point.y+m_CurClientPoint.y)/m_iMultiple>)
{
if(m_nYOriginSrc+(-point.y+m_CurClientPoint.y)/m_iMultiple + m_nHeightSrc< m_pMyDevice->m_sFrInfo.iHeight)
m_nYOriginSrc=m_nYOriginSrc+(-point.y+m_CurClientPoint.y)/m_iMultiple;
}
else
{
m_nYOriginSrc=;
}
m_CurClientPoint = point ;
}
m_sPreview.GetClientRect(&rect);
InvalidateRect(rect,);
break;
default:
break;
}
}
MFC中显示图像的放大、缩小、移动功能的更多相关文章
- JS中图片的放大缩小没反应
这段代码无反应: 代码如下: <script type="text/javascript"> onload = function () { document.getEl ...
- 不使用CvvImage类来在MFC中显示图像
/* * ===================================================================================== * * Filen ...
- canvas上画出坐标集合,并标记新坐标,背景支持放大缩小拖动功能
写在前面:项目需求,用户上传一个区位的平面图片,用户可以在图片上添加新的相机位置,并且展示之前已绑定的相机坐标位置,图片支持放大缩小&拖动的功能.新增坐标,页面展示相对canvas定位,保存时 ...
- html5在微信中不允许放大缩小页面
在头部添加 <meta name="viewport" content="width=device-width, initial-scale=1, maximum- ...
- MFC中实现定时执行与提醒功能(自编代码)
具体实现代码如下:添加一个计时器:SetTimer(1,1000,NULL); 下面仅列举核心代码,详细步聚不作说明,效果如下所示: void CShowTimer::OnTimer(UINT_PTR ...
- h5在微信中不允许放大缩小页面
在头部添加 <meta name="viewport" content="width=device-width, initial-scale=1, maximum- ...
- 鼠标滚轮图片放大缩小功能,使用layer弹框后不起作用
今天在项目中遇到的一个问题:点击按钮使用layer弹框弹出一张图片,需要加一个鼠标滚轮放大缩小,图片也跟着放大缩小的功能.于是在网上找了一个demo. DEMO: <!DOCTYPE html ...
- Android多点触控技术,实现对图片的放大缩小平移,惯性滑动等功能
首先推荐一下鸿洋大大的打造个性的图片预览与多点触控视频教程,这套教程教我们一步一步实现了多点触控实现对图片的平移和缩放的功能.这篇文章我将在鸿洋大大的基础之上做了一些扩展功能: 1.图片的惯性滑动 2 ...
- 自定义mousewheel事件,实现图片放大缩小功能实现
本文是承接 上一篇的<自定义鼠标滚动事件> 的基础上实现的,建议大家先看一下上一篇的mousewheel的实现,再浏览下文: 上篇中我们介绍到: $element.mousewheel( ...
随机推荐
- java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES) 解决办法
一.背景 在Spark中,将DStream写入到MySQL出现错误:java.sql.SQLException: Access denied for user 'root'@'localhost' ( ...
- CodeForces 805B 3-palindrome
构造. $bbaabbaabbaa......$输出前$n$个即可,这样不需要用到$c$,而且任意相邻三个都不会是回文. #include <cstdio> #include <cm ...
- 洛谷P2507 [SCOI2008]配对 [DP,贪心]
题目传送门 配对 题目描述 你有 n 个整数Ai和n 个整数Bi.你需要把它们配对,即每个Ai恰好对应一个Bp[i].要求所有配对的整数差的绝对值之和尽量小,但不允许两个相同的数配对.例如A={5,6 ...
- Python之路【第五篇】: 函数、闭包、装饰器、迭代器、生成器
目录 函数补充进阶 函数对象 函数的嵌套 名称空间与作用域 闭包函数 函数之装饰器 函数之可迭代对象 函数之迭代器 函数之生成器 面向过程的程序设计思想 一.函数进阶之函数对象 1. 函数对象 秉承着 ...
- 【模式匹配】更快的Boyer
1. 引言 前一篇中介绍了字符串KMP算法,其利用失配时已匹配的字符信息,以确定下一次匹配时模式串的起始位置.本文所要介绍的Boyer-Moore算法是一种比KMP更快的字符串匹配算法,它到底是怎么快 ...
- 欧拉路小结 JZYZOJ1210 骑马修栅栏
现在写到欧拉路,理解起来并不算特别困难...吧... 但是非常恶心的是每次都要调试半天,做不到一遍两遍就能ac 每次写程序都对于程序的整体构架没有清晰的思路,想到哪里写到哪里真的是个非常差的习惯[尽管 ...
- [Codeforces 1060F] Shrinking Tree
Link: 传送门 Solution: 原来CF的官方题解也能鸽啊…… 详细题解 该题思路: 1.对于每个点删边方案数为$fac[n-1]$,总贡献为每种方案下满足的概率的和,接下来直接求贡献 2.每 ...
- CodeForces - 1009D Relatively Prime Graph
题面在这里! 直接暴力找点对就行了,可以证明gcd=1是比较密集的,所以复杂度略大于 O(N log N) #include<bits/stdc++.h> #define ll long ...
- spring aop 理解
aop简介 aop是spring 的两大特性之一,还有IOC.主要提供面向切面的编程思想,区分于面向对象编程. aop原理(动态代理+反射) 在一个方法体中,可能会存在很多其他的方法调用,我们可以把每 ...
- 微信小程序缓存滑动距离,当页面浏览到一定位置,滑动其他页面后返回该页面记录之前的滑动距离
15.微信小程序缓存滑动距离 我们在浏览页面的时候,然后左滑或者右滑到新的页面,等返回此页面,我们希望可以记录上次滑动的距离 虽然这个实现起来并不难,但是会遇到一些坑,因为scroll-view的组件 ...