原文出处: martin_wjl(@martin_wjl) git
对于图片拉伸是移动开发中很常见的需求,在前一阵子作项目中须要作一个相似于QQ
聊天气泡,这个气泡会根据文字的多少而变化,当时有了三种方案:github
重写drawRect
方法,使用贝赛尔曲线画一个气泡编程
用一个大图做为背景,管它怎么拉伸,确定不会变形json
使用图片,同时使用系统提供的API
对图片进行局部拉伸架构
来分析一下这三种作法利弊:性能
第一种:劳民伤财,drawRect
的使用带来离屏渲染,若是滑动聊天界面将使内存急剧增长,同时我也不会使用贝赛尔曲线,呜呜!测试
第二种:大图的话,显然所占空间会比较大,这样致使最后的安装包较大,尺寸不合适的图片加载也会对性能有所影响网站
第三种:显然这是一种划算的作法,对于怎么进行局部拉伸也是这篇博客的重点ui
至于 iOS 5 之类的方法,这里就再也不谈了。在 iOS 6 的时候,系统为咱们提供了这样一个方法spa
1 |
public func resizableImageWithCapInsets(capInsets: UIEdgeInsets, resizingMode: UIImageResizingMode) -> UIImage |
对于拉伸的方式,有如下两种:
IUIImageResizingModeStretch
:拉伸模式,经过拉伸UIEdgeInsets
指定的矩形区域是咱们要保护的区域,也就是不被拉伸的区域
UIImageResizingModeTile
:平铺模式,经过重复显示UIEdgeInsets
指定的矩形区域是要保护的区域,也就是不被重复显示的区域
来作四个测试,假如咱们的原始图像尺寸为60*128
当咱们设置capInsets
为如下四种值的时候有什么样子的效果:
1:capInsets
参数为UIEdgeInsetsMake(0, 0, 0, 0)
2:capInsets
参数为UIEdgeInsetsMake(42, 0, 0, 0)
3:capInsets
参数为UIEdgeInsetsMake(0, 20, 0, 0)
4:capInsets
参数为UIEdgeInsetsMake(42, 20, 42, 20)
在一个180*384
的窗口进行测试图像,对于实践的结果,能够在这个地址中看到。
四种测试结果是:
1: 原始图像拉伸,比例放大
2: 咱们对图片上面的区域进行了保护,其余区域进行了拉伸,保护区域在Y轴保持了原比例,可是X轴方向进行了拉伸
3: 咱们对图片的左侧区域进行了保护,其余区域进行了拉伸,保护区域在X轴保持了原比例,可是在Y轴方向进行了拉伸
4: 咱们对除了中心区域的位置进行了保护,中心区域进行了拉伸,四个角进行了双层保护,其他被保护区域在X、Y轴的拉伸与第二、3种状况下相同,效果图以下:
效果图4
与上面的场景相同,只不过再也不拉伸,改成平铺的方式,来尝试如下四种状况:
1:capInsets
参数为UIEdgeInsetsMake(0, 0, 0, 0)
2:capInsets
参数为UIEdgeInsetsMake(42, 0, 0, 0)
3:capInsets
参数为UIEdgeInsetsMake(0, 20, 0, 0)
4:capInsets
参数为UIEdgeInsetsMake(42, 20, 42, 20)
在一个180*384
的窗口进行测试图像,对于实践的结果,能够在这个地址中看到。
结论就是:
1: 按比例平铺
2: 咱们对图片上面的区域进行了保护,其余区域按比例平铺,保护区域在Y轴保持了原比例,可是X轴方向进行了平铺填充
3: 咱们对图片的左侧区域进行了保护,其余区域按比例平铺,保护区域在X轴保持了原比例,可是在Y轴方向进行了平铺填充
4: 咱们对除了中心区域的位置进行了保护,中心区域按比例平铺,四个角进行了双层保护,其他被保护区域在X、Y轴的平铺与第二、3种状况下相同,效果图以下:
效果5
注: 以上的代码测试来自SketchK七爷
何为Image Slicing
呢?,其实就至关于一个可视化的resizableImageWithCapInsets
,能够用于指定在图片缩放时用来填充的像素。咱们能够在Xcode
的Assets.xcassets
目录中选择要slicing
的图片,点击图片界面右下方的Show Slicing
按钮,在想要设定切片的图片上点击Start Slicing
,将出现左中右(或者上中下)三条能够拖动的指示线,经过拖动它们来设定实际的缩放范围。
图
咱们刚才说,他就是可视化的resizableImageWithCapInsets
,那么它的capInsets
在哪里呢?打开图片对应的.json
文件,代码以下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
{ "images" : [ { "resizing" : { "mode" : "9-part", "center" : { "mode" : "tile", "width" : 42, "height" : 92 }, "cap-insets" : { "bottom" : 0, "top" : 95, "right" : 41, "left" : 0 } }, |
从文件能够看出来top
、left
、bottom
、right
对应的就是上左下右的指示线,看到mode
为tile
,就知道Image Slicing
默认为平铺缩放,对于width
与Height
是作什么的呢?Width
表明的是左侧线(或者上方线)和中间线之间的区域,Height
表明的是上侧线和中间线之间的区域。
看一下刚才图片运行起来的效果
测试结果
很神奇呀!灰色区域都会被隐藏,咱们发现灰色区域位于右侧线与中间线或者下方线与中间线之间。来分析一下各个数字的平铺:
3位与右侧线的右侧,不会发生变化
1位与左侧线与中间线之间,Y轴保持比例不变,X轴平铺
6位与右侧线的右侧,可是也位与上方线与中间线之间,因此会保持X轴不变,Y轴平铺
4位与左侧线与中间线之间,同时也位与上方线与中间线之间,会填充其余全部的空余区域。
好绕啊!仍是可视化比较简单,只要手动调试一下,就能够比较直观的看到效果,但愿能够帮到你,Demo能够进行下载。
问啊-定制化IT教育平台,牛人一对一服务,有问必答,开发编程社交头条 官方网站:www.wenaaa.com
QQ群290551701 汇集不少互联网精英,技术总监,架构师,项目经理!开源技术研究,欢迎业内人士,大牛及新手有志于从事IT行业人员进入!