图片拉伸详解

导语:

有时候对一个图片进行常规的缩放达不到我们想要的效果,比如聊天气泡的大小、带边框的按钮背景。通常我们会设置某个偏移值对图片进行拉伸来实现我们想要的效果。iOS6以后有两条相似的API可以解决这一问题,下文简称带模式的缩放和不带模式的缩放。

- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets;
- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets resizingMode:(UIImageResizingMode)resizingMode;

下面是官方文档对API的解释:

Each inset defines the potion of the image that does not stretch in the given dimension. The regions inside an image’s top and bottom insets maintain a fixed height, and the areas inside the left and right insets maintain a fixed width. Figure 2 shows how each part of a nine-part image stretches as the image itself is stretched to fill the available space. The corners of the image do not change size because they are inside both a horizontal and vertical inset.

也就是说会传入一个UIEdgeInsets类型的结构体将UIImage分为9个(也有可能是2个)部分,并对其中间部分和四个边进行缩放,但是四个角会保持不变。

图1

下面分别介绍这两条API。

不带模式的缩放

缩放模式有两种,分别是UIImageResizingModeTile平铺和UIImageResizingModeStretch拉伸。如果不指定缩放模式,则会根据传入UIEdgeInsets类型的结构体的不同而进行不同的缩放。
原文是这么说的:

iOS uses different rendering techniques, with different performance characteristics, depending on the size of each resizable area in the image:

If resizable areas have a width or height of 1 pixel—that is, a horizontally resizable area is 1 pixel wide, a vertically resizable area is 1 pixel tall, or the center region of the image is 1 x 1 pixel—iOS draws the image by stretching the 1-pixel region. This mode provides the fastest performance (for nonzero cap insets).

If resizable areas have a width or height greater than 1 pixel, iOS draws the image by tiling the region. This mode provides reduced performance, but can be useful for images with textured (rather than solid-color) content in their resizable areas.

If the entire image is resizable—that is, the capInsets parameter is UIEdgeInsetsZero—and its size is greater than 1 x 1 pixel, iOS draws the image by tiling the entire image. This mode is faster than the tiling mode for nonzero cap insets.

也就是说,

  • 如果中间部分边长都小于或等于1,这种情况下可变部分从上往下、从左至右按一个像素偏移值按照拉伸模式来放大。若中间部分有一边大于1,则大于1的那边按平铺模式缩放,小于1的那边以一个像素的默认偏移值按拉伸模式缩放。
  • 如果中间部分边长大于1x1;在这种情况下可变部分按照平铺模式来放大。
  • 如果中间部分大小等于图片的大小,并且图片大小大于1x1,也就是说传入的参数为UIEdgeInsetsZero,在这种情况下可变部分按照平铺模式来放大。

下面用一张对称的图片来测试,图片大小是90x90,imageView大小为180x180,上面是测试图下面是原图。

中间部分大小为0的情况,传入的参数为:UIEdgeInsetsMake(image.size.height*0.5, image.size.width*0.5, image.size.height*0.5, image.size.width*0.5)

图2

中间部分叠加(小于0)的情况,传入的参数为:UIEdgeInsetsMake(image.size.height*0.5, image.size.width*0.5, image.size.height*0.5+20, image.size.width*0.5+20)

图3

中间部分边长均小于1的情况,传入的参数为:UIEdgeInsetsMake(image.size.height*0.5, image.size.width*0.5, image.size.height*0.5-0.5, image.size.width*0.5-0.5)

图4

中间部分边长均大于1的情况,传入的参数为:UIEdgeInsetsMake(image.size.height*0.3, image.size.width*0.3, image.size.height*0.3, image.size.width*0.3)

图5

中间部分等于图片大小的情况,传入的参数为:UIEdgeInsetsZero

图6

带模式的缩放

这种缩放方式出现在iOS6+,官方说明如下:

This method is exactly the same as its counterpart resizableImageWithCapInsets: except that the resizing mode of the new image object can be explicitly declared. You should only call this method in place of its counterpart if you specifically want your image to be resized with the UIImageResizingModeStretch resizing mode.

意思就是这种缩放方式和前面的差不多,除非你一定要用拉伸的方式来放大图片,否则还是建议你使用不带模式的方式来处理你的图片。

拉伸模式,传入的参数为:UIEdgeInsetsMake(image.size.height*0.3, image.size.width*0.3, image.size.height*0.3, image.size.width*0.3)

图7

平铺模式,传入的参数为:UIEdgeInsetsMake(image.size.height*0.3, image.size.width*0.3, image.size.height*0.3, image.size.width*0.3)

图8

这两种方法都不会改变原图,而是返回一张新的图片。其实在像素为1的情况下也看不出是平铺模式还是拉伸模式(性能上拉伸模式好得多),如果是纯色背景两种模式区别也不大。anyway,知道总比不知道要强。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容

  • 教程一:视频截图(Tutorial 01: Making Screencaps) 首先我们需要了解视频文件的一些基...
    90后的思维阅读 4,652评论 0 3
  • 每年中考总会有很多同学在不经意间丢掉了本不该丢的分,而这本来是完全可以避免的。相信大家都不想这样的事情发生在自己身...
    gaosijiaoyu阅读 203评论 0 0