图像的缩放查看,在移动终端上早已不是问题,任何一个人都能够熟练的操作图像的缩放。本文所讲述的重点并不是应用层面上的,而是从编码的角度去自己实现一个图像的缩放应用。作者(就是我自己)最近在做一款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下,利用捏合手势实现图像缩放和显示相关推荐

  1. IOS下利用OpenCV框架去除视频水印

    想做个去水印的APP,第一个想到的就是CV里的inpaint图像修复技术.就想着把CV框架放在IOS中用,由于第一次接触IOS的开发,就看了两本实习时候导师大神推荐的书,很多东西都不太了解,虽然CV官 ...

  2. 基于FPGA 的图像缩放算法设计

    介绍双线性插值算法来实现图像缩放,FPGA 硬件实现方法,包括图像数据缓冲单元.插值系数生成单元以及插值计算单元等. 图像是人类感知世界的视觉基础,是人类获取信息.表达信息的重要手段.现在研究较多的是 ...

  3. iOS XCode中的手机模拟器 利用键盘鼠标模拟各种手势 解决捏合手势中心不动的问题

    大家都知道,iOS开发和安卓开发在模拟器上有一点明显的不同,就是iOS的编程工具XCode中内置的模拟器是可以模拟手势的.但是之前一直没有对手势的使用方法总结过,只知道option+鼠标左键可以实现捏 ...

  4. IOS OpenGL ES GPUImage 图像缩放 GPUImageTransformFilter

    目录 一.简介 二.效果演示 三.源码下载 四.猜你喜欢 零基础 OpenGL (ES) 学习路线推荐 : OpenGL (ES) 学习目录 >> OpenGL ES 基础 零基础 Ope ...

  5. iOS多点触摸与手势

    转自: http://book.51cto.com/art/201110/297453.htm 4.2.2 iOS多点触摸与手势 iOS赋予用户至少3.5英寸的宽广视野,在当时可谓令人眼前一亮.在这不 ...

  6. Opencv实现纵横比保持的图像缩放

    之前实现过C实现纵横比保持的RGB图像缩放,其实计算效率是不高的. opencv的好多实现都是自带mmx, sse加速的.所以就来研究一下如何用opencv来实现纵横比保持的图像缩放. 查看了一下op ...

  7. OpenCV图像缩放插值之BiCubic双三次插值

    图像缩放算法简介 在图像的仿射变换中,很多地方需要用到插值运算,常见的插值运算包括最邻近插值,双线性插值,双三次插值(立体插值),兰索思插值等方法,OpenCV提供了很多方法,其中,双线性插值由于折中 ...

  8. 滤波、漫水填充、图像金字塔、图像缩放、阈值化

      imgpro 组件是 Image 和 Process 这两个单词的缩写组合,即图像处理模块,这个模块包含了如下内容: 文章目录 1.线性滤波:方框滤波.均值滤波.高斯滤波 1.1 平滑处理 1.2 ...

  9. 图形图像处理-之-高质量的快速的图像缩放 中篇 二次线性插值和三次卷积插值

    from:http://blog.csdn.net/housisong/article/details/1452249 图形图像处理-之-高质量的快速的图像缩放 中篇 二次线性插值和三次卷积插值    ...

  10. 图像缩放算法_技术专栏|基于无人机LK光流算法的适用性及其优化方法探究

    点击上方蓝字关注我们 问题描述 ◆ ◆ ◆ 一般的LK光流算法存在一个比较明显的局限性.我们知道,一般的LK光流算法必须包含三个假设: (1)亮度恒定: (2)时间连续或者运动是小运动: (3)空间一 ...

最新文章

  1. PTA 03-树1 树的同构 (25分)
  2. Android之集成友盟推送功能
  3. JFreeChart(四)之线型图
  4. Ajax_ASP.NET 添加 Ajax 和客户端功能_01
  5. 【推荐】“水果”公司的复兴 (乔布斯和苹果公司)---Google黑板报
  6. 国家集训队2011 happiness
  7. Android JNI入门第六篇——C调用Java
  8. “新基建”提速,数字化硬核人才,你们准备好了吗?
  9. “宇宙最强”GPU —— NVIDIA Tesla V100 面向开发者开放试用!
  10. 批量将txt转换成Excel格式
  11. 初学Python选什么版本?
  12. 实用的手机app商城购物网站模板源码
  13. Mac OS X的入门文档
  14. linux双系统无u盘安装教程视频教程,window 与Linux Mint 双系统U盘安装方法
  15. 数据库综合查询与视图操作
  16. 2022-2027年中国肺炎疫苗行业市场运行现状及投资战略研究报告
  17. leetcode(力扣) 718. 最长重复子数组 1143. 最长公共子序列 1035. 不相交的线 (动态规划)
  18. centos6.8安装db2expc11.1
  19. 文正机械电子工程专业课_机械电子工程有些什么课程
  20. 密码学安全性证明中的挑战者和攻击者

热门文章

  1. latex中表格怎么加标题_LaTeX中表格怎么加标题
  2. opencv学习十三:图像金字塔和图像梯度
  3. Java int 最大值溢出
  4. 内存超频时序怎么调_憋了很久的问题:内存时序有什么用?超频时怎么调?
  5. java 打印对象_java中直接打印对象
  6. Google BBR是什么?以及在 CentOS 7 上如何部署
  7. anaconda安装完怎么打开_录像机怎么样安装在机柜上,看完就明白
  8. html 表格单元格点击事件,bootstrap table onClickCell点击单元格事件
  9. 怎么用计算机算lnx,ln计算(log计算器在线)
  10. 大数据和云计算有什么关系?