背景

.9图来源于Android。为了设计出一套图,兼容Android和iOS,使用.9图的方式来对图片进行拉伸以适应不同的屏幕。在iOS中没有.9图的概念,只能先了解Android的.9图再进行模拟Android的方法。

什么是.9图片

即图片后缀名前有.9的图片,如pic.9.png、pic1.9.jgp,诸如此类的图片就称为.9图片。且在原始图片四周添加了一个像素,在这一个像素上用黑线标识出相关的区域。

.9图片的作用

.9图片的作用是在图片拉伸的时候特定的区域不会发生图片失真,特定的区域就是由.9图边缘一圈像素中的left和top的黑线所决定。

Android中的.9图介绍

.9图其实是在原始图片的四周添加了一个像素,通俗点说就是图片比原始图片扩大了一圈,多出来的那一圈是透明像素。我们需要绘制黑线的地方正是在那一圈透明像素上进行绘制。

如上图所示,在原始图的四周添加了一个圈的透明像素。其中:四周分别命名为L、T、R、B。

绘制在L的区域:用于拉伸的纵向区域。

绘制在T的区域:用于拉伸的横向区域。

绘制在R的区域:用于显示前景的纵向范围。

绘制在B的区域:用于显示前景的横向范围。

举例说明一下,如下图 :

该图的四周添加了相应的黑线。

拉伸区域,如下图:

红色框区域:表示纵向拉伸的区域,也就是说,当图片需要纵向拉伸的时候它会只指定拉伸红色区域,其他区域在纵向是不会拉伸的。

绿色框区域:表示横向拉伸的区域,也就是说,当图片需要横向拉伸的时候它会只指定拉伸绿色区域,其他区域在横向是不会拉伸的。

显然红色和绿色相交的部分是既会进行横向拉伸也会进行纵向拉伸的。

前景的显示区域,如下图:

蓝色区域:表示前景能显示的纵向范围。即前景的最上面可以显示到什么地方,最下面可以显示的什么地方。

黄色区域:表示前景能显示的横向范围。即前景的最左边可以显示到什么地方,最右边可以显示的什么地方。

蓝色和黄色相交部分:表示整个前景能显示的区域。一个区域是矩形的,蓝色规定了上下边界,黄色规定了左右边界,两者共同当然也就规定了一个矩形区域。

在iOS中图片拉伸:

1.在iOS5之前,使用- (UIImage *)stretchableImageWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight;这个方法进行图片的拉伸。

2.在iOS5之后,使用- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets;

或- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets resizingMode:(UIImageResizingMode)resizingMode;这个方法进行图片的拉伸或平铺。

iOS中有个叫端盖(end cap)的概念,用来指定图片中的哪一部分不用拉伸。比如下图中,黑色代表需要被拉伸的矩形区域,上下左右不需要被拉伸的边缘就称为端盖。

如上所述,在iOS中想要拉伸图片,就得确定要被拉伸的区域,而这个区域是由top、left、bottom、right四个方向的值所决定的区域,这部分的概念与Android中的.9图是不太一样的,但拉伸的区域概念差不太多。

了解了以上概念,我们就可以在iOS中模拟Android处理.9图的拉伸模式。

我们使用了一个第三方库:LVNinePatchImage进行.9图的处理。因为原始图片四周添加了一像素的透明。而只有黑线的alpha值是为1的,其余部分都是透明的则alpha值为0。通过这种逻辑关系就能找到对应的左边和上边的黑线区域位置。然后通过iOS系统提供的拉伸方法进行图片的拉伸操作。

该库主要主要做的事有:

1.通过类方法+ (unsigned char*)getRGBAsFromImage:(UIImage*)image count:(NSInteger)count;来获取图片的所有像素点的RGB值包括Alpha值。

2.通过方法 inline static CGFloat getImageAphaAtPoint(const unsigned char* rawData, NSInteger width, NSInteger height , NSInteger pointX, NSInteger pointY);去找出pointX到pointY之间像素点的Alpha值。

如当pointY始终为0,pointX从1到图片的宽度,就能找出图片顶部一像素的所有alpha值。当pointX始终为0,pointY从1到图片的高度,就能找出图片左边一像素的所有alpha值。

3.然后遍历找到的顶部和左边的alpha数组值,当alpha为1的连续区域就是黑线的所在位置。

4.然后调用方法+ (UIImage*)crop:(CGRect)r image0:(UIImage*)image0;裁剪掉图片四周的一像素区域,只保留中间正确(最原始)的图片。

5.最后再根据黑线的所在位置,算出top、left、bottom、right端盖的值,调用- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets;方法进行图片的拉伸或平铺。

参考链接

http://blog.csdn.net/shimiso/article/details/41079847

http://www.cnblogs.com/mjios/archive/2013/02/26/2934280.html

iOS 中使用.9图的更多相关文章

  1. iOS中 轮播图放哪最合适? 技术分享

    我们知道,轮播图放在cell或collectionViewCell上会影响用户层级交互事件,并且实现起来比较麻烦,现在推出一个技术点:答题思路是:将UIScrollView放在UIView或UICol ...

  2. iOS中 动态启动图GIF的简单设置 韩俊强的博客

    // 设定位置和大小 CGRect frame = CGRectMake(50,340,[UIScreen mainScreen].bounds.size.width / 2,[UIScreen ma ...

  3. 解决iOS中 tabBarItem设置图片(image+title切图在一起)时造成的图片向上偏移

    解决iOS中 tabBarItem设置图片(image+title切图在一起)时造成的图片向上偏移 解决办法1:设置tabBarItem的imageInsets属性 代码示例: childContro ...

  4. iOS中数据库应用基础

    iOS 数据库入门 一.数据库简介 1.什么是数据库? 数据库(Database) 是按照数据结构来组织,存储和管理数据的仓库 数据库可以分为2大种类 关系型数据库(主流) PC端 Oracle My ...

  5. iOS开发——高级篇——iOS中常见的设计模式(MVC/单例/委托/观察者)

    关于设计模式这个问题,在网上也找过一些资料,下面是我自己总结的,分享给大家 如果你刚接触设计模式,我们有好消息告诉你!首先,多亏了Cocoa的构建方式,你已经使用了许多的设计模式以及被鼓励的最佳实践. ...

  6. iOS 图片轮播图(自动滚动)

    iOS 图片轮播图(自动滚动) #import "DDViewController.h" #define DDImageCount 5 @interface DDViewContr ...

  7. (转)如何处理iOS中照片的方向

    如何处理iOS中照片的方向 31 May 2015 • 7 min. read • Comments 使用过iPhone或者iPad的朋友在拍照时不知是否遇到过这样的问题,将设备中的照片导出到Wind ...

  8. iOS中的存储方式

    1.Plist 1.1 了解沙盒 每个iOS应用都有自己的应用沙盒(应用沙盒就是文件系统目录),与其它文件系统隔离.应用必须呆在自己的沙盒里.其它应用不能访问该沙盒. 一个程序中所有的非代码文件都可以 ...

  9. 浅谈iOS中的userAgent

    浅谈iOS中的userAgent   User-Agent(用户代理)字符串是Web浏览器用于声明自身型号版本并随HTTP请求发送给Web服务器的字符串,在Web服务器上可以获取到该字符串. 在公司产 ...

随机推荐

  1. 《深入Java虚拟机学习笔记》- 第19章 方法的调用与返回

    <深入Java虚拟机学习笔记>- 第19章 方法的调用与返回

  2. HDU 1043 Eight BFS

    题意:就是恢复成1,2,3,4,5,6,7,8,0; 分析:暴力BFS预处理,所有路径,用康拓展开判重,O(1)打印 93ms 还是很快的 #include <iostream> #inc ...

  3. longblogV1.0——我的静态博客发布系统

    longblogV1.0——我的静态博客发布系统 环境依赖: python3-markdown 作者:IT小小龙个人主页:http://long_python.gitcafe.com/电子邮箱:lon ...

  4. 自动脚本工具新版 v2.0

    自动脚本工具 下载 下载工具后,解压,直接双击 "execute.bat" 文件后(前提已配置好 jdk 1.7 的环境),会生成文件夹 "output",该文 ...

  5. 类内const static(static const)成员变量初始化问题

    在查找const相关资料的过程中,又遇到了另外一个问题,就是C++类中const static(或者static const)成员变量应当如何初始化的问题. 查阅了许多资料,发现VC环境下,只允许co ...

  6. 设计原则 Design Principle

    Design Principle设计原则 最近由于碰到要参与设计一个音频处理系统,有人提议用一个大的全局变量结构体来做状态信息交流的地方,引起了我对设计一个系统的思考,于是找到了如下资料,当然,关于这 ...

  7. MapReduce 支持的部分数据挖掘算法

    MapReduce 支持的部分数据挖掘算法 MapReduce 能够解决的问题有一个共同特点:任务可以被分解为多个子问题,且这些子问题相对独立,彼此之间不会有牵制,待并行处理完这些子问题后,任务便被解 ...

  8. HW7.5

    import java.util.Scanner; public class Solution { public static void main(String[] args) { Scanner i ...

  9. HW6.13

    import java.util.Scanner; public class Solution { public static void main(String[] args) { Scanner i ...

  10. 我用的Linux命令

    从今天起,会在这里记一些我使用过的linux命令 =======I'm 分割线======= 11.查看某个端口号被哪个应用占用 netstat -apn|grep 端口号,lsof -i:端口号,n ...