IOS下,利用捏合手势实现图像缩放和显示
图像的缩放查看,在移动终端上早已不是问题,任何一个人都能够熟练的操作图像的缩放。本文所讲述的重点并不是应用层面上的,而是从编码的角度去自己实现一个图像的缩放应用。作者(就是我自己)最近在做一款APP,其中有一个功能就是抓取PC桌面的图像发送到手机上显示。虽说现在的手机屏幕在慢慢的变大,已经可以达到5.5英寸,但是相比PC显示器的20+英寸,还是显得很小,可以展现的内容也很有限。如果整个PC屏幕显示在手机屏幕上,可以自行脑补一下,你能够看清上面的文字和图片么?那么问题来了,整个功能就需要实现对抓取PC桌面的放大和缩小显示。下面我将比较详细接用代码写出使用捏合手势来实现的缩放功能。
首先我们需要两个参数来保存重要的信息:
CGFloat m_fScale; // 缩放倍数
CGPoint m_ptStart; // 显示图像块的起始点
m_fScale这个参数很容易理解,你缩放图像,一定得有个缩放倍数,那么就是它了;至于m_ptStart这个参数,我想我可能需要稍微啰嗦两句,来解释一下:当你放大图像时,由于显示区域时固定的,那么你就不可能把整个放大的图像都显示出来,你只能显示某一个块图像,那么这一块图像需要有一个起始点。
好吧,我承认,以上的解释是废话,我们还是来举个例子来说明一下吧。
比如,你的图像是1920 x 1080的分辨率,你放大了2倍,那么整个图像的分辨率就会变成3840 x 2160;如果你把3840 x 2160的图像直接显示出来,那你看到的结果是非但没有放大的效果,还缩小了。因为可显示区域大小是固定的,分辨率越大,显示内容越小。那么如何才能显示放大的图像呢?这时m_ptStart这个参数的作用就显现出来了。假设这个参数的值为(0,0),那么就是说从图像的标准坐标原点开始显示,显示的长度宽度也是固定的(假设是1920 x 1080),那么针对于3840 x 2160这个放大的图像,从(0,0)点开始显示长宽为1920 x 1080的图像块,这样显示的图像就是放大了(因为原本在固定可显示区域要显示1920 x 1080的图像,现在只要显示960 x 540的图像块就可以了)。
这样的例子,不知道是不是所有人都能够理解,还不理解,我也表示无能为力了。
其次,我们需要给一个UIView添加捏合手势识别,假设这个UIView就是我们要在上面显示图像的View,这段代码的作用是,将一个捏合手势添加的View上,并且关联了捏合手势的处理函数gesturePinch。
// m_pTouchView已经关联到了UIView空间上
m_pTouchView.multipleTouchEnabled = YES; // 允许UIView多点触控
UIPinchGestureRecognizer *recongnizerPinch = [[UIPinchGestureRecognizer alloc]init];
[recongnizerPinch addTarget:self action:@select(gesturePinch:)];
[m_pTouchView addGestureRecognizer:recognizerPinch];
这是捏合手势的处理函数,对缩放倍数进行边界检查,并且设置缩放倍数。
-(void)gestruePinch:(id)sender {UIPinchGestureRecognizer *gesture = (UIPinchGestureRecognizer*)sender;if (gesture.state == UIGestureRecognizerStateBegan){// 记录捏合手势开始时的缩放系数m_fStartScale = m_fScale;}// 捏合手势默认的系数是1.0// 当识别为放大手势时,系数会从1.0开始递加; 当识别为缩小手势时,系数会从1.0开始递减,直到为0.0CGFloat scale = gesture.scale + m_fStartScale - 1.0;// 锁定缩放倍数,缩放倍数只能在1.0~3.0之间if (scale - 1.0 < 0.000001){scale = 1.0;}else if (scale - 3.0 > 0.000001){scale = 3.0;}m_fScale = scale;
}
好了,到此为止,所有准备工作都做完了,下面该最关键的部分登场了——抠图并放大。
-(void)captureImage:(UIImage*)org scale:(CGFloat)scale startPoint:(CGPoint)startPoint {// 如果缩放倍数为1.0的话,表示不需要进行缩放处理if (scale - 1.0 <= 0.000001){return org;}// 根据缩放倍数计算需要显示的图像的宽度和高度int nW = org.size.width / scale;int nH = org.size.height / scale;// 根据startPoint和新的宽度高度,调整新的显示起始点。int nX = (org.size.width - startPoint.x) >= nW ? startPoint.x : (org.size.width - nW);int nY = (org.size.height - startPoint.y) >= nH ? startPoint.y : (org.size.height - nH);// 提取指定rect的图像块CGImage subImageRef = CGImageCreateWidthImageInRect(org.CGImage, CGRectMake(nX, nY, nW, nH);UIImage *capImg = [UIImage imageWidthCGImage:subImageRef];CGImageRelease(subImageRef);// 针对提取出来的图像块,将它还原到可现实区域大小,以实现放大的效果UIGraphicsBeginImageContext(org.size);[capImg drawInRect:CGRectMake(0, 0, org.size.width, org.size.height)];UIImage *retImage = UIGraphicsGetImageFromCurrentImageContext();UIGraphicsEndImageContext();return retImage;
}
图像处理完毕了,剩下的就是将图像画到UIView上就行了。
-(void)drawImage:(UIImage*)img {if (img == nil){return ;}m_pTouchView.layer.contents = (id)[self captureImage:img scale:m_fScale startPoint:m_ptStart].CGImage;
}
你发现了什么?有问题?有参数没介绍?
对,你答对了,m_pStart这个显示起始坐标还没有设置,我们一直假设的是原始坐标(0,0);
至于这个坐标,你可以再touchesBegan,touchesMoved和touchesEnded这些函数中处理一下,就可以得到坐标了,这里就不写出具体代码了,留给细心的读者作为课后作业吧。
IOS下,利用捏合手势实现图像缩放和显示相关推荐
- IOS下利用OpenCV框架去除视频水印
想做个去水印的APP,第一个想到的就是CV里的inpaint图像修复技术.就想着把CV框架放在IOS中用,由于第一次接触IOS的开发,就看了两本实习时候导师大神推荐的书,很多东西都不太了解,虽然CV官 ...
- 基于FPGA 的图像缩放算法设计
介绍双线性插值算法来实现图像缩放,FPGA 硬件实现方法,包括图像数据缓冲单元.插值系数生成单元以及插值计算单元等. 图像是人类感知世界的视觉基础,是人类获取信息.表达信息的重要手段.现在研究较多的是 ...
- iOS XCode中的手机模拟器 利用键盘鼠标模拟各种手势 解决捏合手势中心不动的问题
大家都知道,iOS开发和安卓开发在模拟器上有一点明显的不同,就是iOS的编程工具XCode中内置的模拟器是可以模拟手势的.但是之前一直没有对手势的使用方法总结过,只知道option+鼠标左键可以实现捏 ...
- IOS OpenGL ES GPUImage 图像缩放 GPUImageTransformFilter
目录 一.简介 二.效果演示 三.源码下载 四.猜你喜欢 零基础 OpenGL (ES) 学习路线推荐 : OpenGL (ES) 学习目录 >> OpenGL ES 基础 零基础 Ope ...
- iOS多点触摸与手势
转自: http://book.51cto.com/art/201110/297453.htm 4.2.2 iOS多点触摸与手势 iOS赋予用户至少3.5英寸的宽广视野,在当时可谓令人眼前一亮.在这不 ...
- Opencv实现纵横比保持的图像缩放
之前实现过C实现纵横比保持的RGB图像缩放,其实计算效率是不高的. opencv的好多实现都是自带mmx, sse加速的.所以就来研究一下如何用opencv来实现纵横比保持的图像缩放. 查看了一下op ...
- OpenCV图像缩放插值之BiCubic双三次插值
图像缩放算法简介 在图像的仿射变换中,很多地方需要用到插值运算,常见的插值运算包括最邻近插值,双线性插值,双三次插值(立体插值),兰索思插值等方法,OpenCV提供了很多方法,其中,双线性插值由于折中 ...
- 滤波、漫水填充、图像金字塔、图像缩放、阈值化
imgpro 组件是 Image 和 Process 这两个单词的缩写组合,即图像处理模块,这个模块包含了如下内容: 文章目录 1.线性滤波:方框滤波.均值滤波.高斯滤波 1.1 平滑处理 1.2 ...
- 图形图像处理-之-高质量的快速的图像缩放 中篇 二次线性插值和三次卷积插值
from:http://blog.csdn.net/housisong/article/details/1452249 图形图像处理-之-高质量的快速的图像缩放 中篇 二次线性插值和三次卷积插值 ...
- 图像缩放算法_技术专栏|基于无人机LK光流算法的适用性及其优化方法探究
点击上方蓝字关注我们 问题描述 ◆ ◆ ◆ 一般的LK光流算法存在一个比较明显的局限性.我们知道,一般的LK光流算法必须包含三个假设: (1)亮度恒定: (2)时间连续或者运动是小运动: (3)空间一 ...
最新文章
- PTA 03-树1 树的同构 (25分)
- Android之集成友盟推送功能
- JFreeChart(四)之线型图
- Ajax_ASP.NET 添加 Ajax 和客户端功能_01
- 【推荐】“水果”公司的复兴 (乔布斯和苹果公司)---Google黑板报
- 国家集训队2011 happiness
- Android JNI入门第六篇——C调用Java
- “新基建”提速,数字化硬核人才,你们准备好了吗?
- “宇宙最强”GPU —— NVIDIA Tesla V100 面向开发者开放试用!
- 批量将txt转换成Excel格式
- 初学Python选什么版本?
- 实用的手机app商城购物网站模板源码
- Mac OS X的入门文档
- linux双系统无u盘安装教程视频教程,window 与Linux Mint 双系统U盘安装方法
- 数据库综合查询与视图操作
- 2022-2027年中国肺炎疫苗行业市场运行现状及投资战略研究报告
- leetcode(力扣) 718. 最长重复子数组 1143. 最长公共子序列 1035. 不相交的线 (动态规划)
- centos6.8安装db2expc11.1
- 文正机械电子工程专业课_机械电子工程有些什么课程
- 密码学安全性证明中的挑战者和攻击者
热门文章
- latex中表格怎么加标题_LaTeX中表格怎么加标题
- opencv学习十三:图像金字塔和图像梯度
- Java int 最大值溢出
- 内存超频时序怎么调_憋了很久的问题:内存时序有什么用?超频时怎么调?
- java 打印对象_java中直接打印对象
- Google BBR是什么?以及在 CentOS 7 上如何部署
- anaconda安装完怎么打开_录像机怎么样安装在机柜上,看完就明白
- html 表格单元格点击事件,bootstrap table onClickCell点击单元格事件
- 怎么用计算机算lnx,ln计算(log计算器在线)
- 大数据和云计算有什么关系?