iOS Swift处理点9图片
一、什么是点9图?
点9图是Android开发中用到的一种特殊格式的图片,后缀名是“.9.png”的图片。左上两条线控制可拉伸区域(未画线表示不可拉伸),右下两条线控制内容显示区(无文字内容不画)。
二、点9图的作用是什么?
简单来说,点9图的作用就是可以保证图片在不模糊变形的前提下做到自适应。
什么意思呢?我们来举个简单的例子说明吧。下图是我们常见的按钮背景,切图的时候如果没有用点9切图,开发想改变按钮的高度的时候,会直接整体拉伸,得到的结果就是圆角就变形了,如下图:
那么用点9图之后,会通过左、上两条横线定义图片可以拉伸的部分,问题就得到了解决啦,如下图:
三 iOS中如何处理图片局部拉伸
iOS中处理进行图片局部拉伸,相关API如下:
1 2 3 4 5 | @ available ( iOS 5.0 , *) open func resizableImage ( withCapInsets capInsets : UIEdgeInsets ) - > UIImage @ available ( iOS 6.0 , *) open func resizableImage ( withCapInsets capInsets : UIEdgeInsets , resizingMode : UIImage . ResizingMode ) - > UIImage |
capInsets定义图片的不拉伸范围(这个范围是相对于源图片大小而言),resizingMode定义了图片以拉伸/平铺的方式变换。
四 iOS中如何处理点9图片
iOS和安卓为了可以统一用一套UI,iOS需要显示点九图片,具体思路是获取到图片中上、左两条直线的像素颜色值,取得黑线距离两边的距离即为不可拉伸区域,得到上下左右不可拉伸区域之后,用iOS局部拉伸API处理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | func ninePatchImage ( _ scale : Int = 3 ) - > UIImage { guard let imageRef = self . cgImage else { return self } guard let rgbaImage :[[ CGFloat ]] = getRGBA () else { return self } let scale : CGFloat = CGFloat ( scale ) //最上边一行的各像素点数组 var topBarRgba :[[ CGFloat ]] = [] for i in 1 .. < imageRef . width - 1 { topBarRgba . append ( rgbaImage [ i ]) } //最左边一排像素点数组 var leftBarRgba = [[ CGFloat ]]() for i in 0 .. < rgbaImage . count { if i % imageRef . width == 0 { leftBarRgba . append ( rgbaImage [ i ]) } } leftBarRgba . removeFirst () leftBarRgba . removeLast () guard let edge = stretchEdge ( topBarRgba : topBarRgba , leftBarRgba : leftBarRgba ) else { return self } if let cgImage = self . cgImage ?. cropping ( to : CGRect ( x : 1 , y : 1 , width : self . size . width - 2 , height : self . size . height - 2 )){ var cropImage = UIImage . init ( cgImage : cgImage , scale : CGFloat ( scale ), orientation : . up ) cropImage = cropImage . resizableImage ( withCapInsets : UIEdgeInsets ( top : edge . top / scale , left : edge . left / scale , bottom : edge . bottom / scale , right : edge . right / scale ), resizingMode : . stretch ) return cropImage } return self } |
获取黑线距离各边的具体长度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | private func stretchEdge ( topBarRgba :[[ CGFloat ]], leftBarRgba :[[ CGFloat ]]) - > UIEdgeInsets ?{ var left = - 1 for i in 0 .. < topBarRgba . count { if topBarRgba [ i ][ 3 ] == 1 { left = i break } } if left == - 1 { return nil } var right = - 1 for i in ( 0 .. < topBarRgba . count ). reversed () { if topBarRgba [ i ][ 3 ] == 1 { right = i break } } if right == - 1 { return nil } var top = - 1 for i in ( 0 .. < leftBarRgba . count ) { if leftBarRgba [ i ][ 3 ] == 1 { top = i break } } if top == - 1 { return nil } var bottom = - 1 for i in ( 0 .. < leftBarRgba . count ). reversed () { if leftBarRgba [ i ][ 3 ] == 1 { bottom = i break } } if bottom == - 1 { return nil } bottom = leftBarRgba . count - 1 - bottom right = topBarRgba . count - 1 - right return UIEdgeInsets ( top : CGFloat ( top ), left : CGFloat ( left ), bottom : CGFloat ( bottom ), right : CGFloat ( right )) } |
文字显示区域也可以获取到,但是iOS中没有相关处理,让UI最好上和下,左和右黑线长度相同
地址: https://github.com/duzhaoquan/DQTool
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署