Nine Patch Pic

.9图作为Android端图片控制的一个利器,使用的时候很简单,只需要在一个图片的四边预留1px的空白像素,然后按照规则,分别在left top right bottom控制这些1px像素就好了。

  • left: Vertical拉伸控制像素,可以为一个像素,也可以是一个区域
  • top: Horizontal拉伸控制像素,可以为一个像素,也可以是一个区域
  • right: Vertical内容区域,设置该.9后,控件的内容只能在这部分空间内显示
  • bottom: Horizontal内容区域,设置区域后,控件的内容只能在这部分空间内显示

这上面就是一个开发者对NinePatch最基本的认知,但是实际上NinePatch虽然用着简单,但是踩坑点实际还是存在的。Android NinePatch官方说明

在AndroidStudio提供的.9图生成器,实际上是一个熟悉的.bat文件,在以前很久之前.9图就是这样生成的。工具基于SDK目录下的draw9patch.bat做了封装整合到AndroidStudio中。同时说明下如下的这些功能

  1. Show Lock (显示当前.9图不可编辑的部分,一般都是非透明像素部分,即图片left top right bottom 留下的1px空白像素)
  2. Show Content (显示当前.9图内容区域,由right和bottom控制的内容区域)
  3. Show Patches (显示当前.9图拉伸区域,由top和left控制的拉伸区域)
  4. Show Bad Patches (显示当前.9图不规范的拉伸区域,由一套逻辑控制,等下详细说明)

NinePatch 在不同分辨率遇到的问题

Nine Patch遇到了问题?

需求描述:在使用NinePatch的一个场景中,UI给了一张背景图,我和UI都意在拉伸这张图片的空白区域,以实现内容的控制,同时可以保持头部的红色区域部分不变化。

切图的心路历程:

  1. 因为历史需求是需要这张图片作为背景图的,所以UI就针对这张背景图做了一个.9的处理
  2. 第一次切图,直接在原图上面的边距上面加了一个px的黑色像素,但是发现这样有问题,所以就有踩坑记录一了。
  3. UI小哥修改之后,直接Copy到项目,发现还是出现问题,他把多余的透明像素都换成了黑色像素,所以有踩坑记录二。
  4. 最后发现这个图片拉伸失效,虽然图片确实设置了.9拉伸了,但是又因为设置的vertical content区域是全部,所以红色的头部也会被拉伸
  5. 之后叫UI再次缩小空白区域,然后vertical content设置到红色区域下方

踩坑记录一:边缘留白透明像素,导致拉伸失效问题

踩坑描述:copy UI小哥的图片之后,发现整个背景图被拉伸了,而且观察效果发现图片左侧有两条黑边,和没有设置.9图一样。后来仔细观察.9图发现,发现.9图的左右侧的黑色

踩坑记录二:com.android.builder.internal.aapt.v2.Aapt2Exception: AAPT2 error: check logs for details

踩坑描述:在使用.9图之后,尝试通过gradle去Sync Project后,会提示这个错误。发现项目在clean、rebuild、Invalid Cache and Restart操作后均无效,还是会报同样的错误。思考后发现,当前操作只是Copy了UI提供的.9图,于是查看.9图是否存在猫腻。

果真,.9图原本预留的一个1px,UI切图后发现,right留白的像素不为1,而是2个黑色像素

踩坑一和二犯了一个最大的错误,违反了官方文档NinePatch的操作定义

看到官网指导的第四点,明确指定操作的px只有一个px,所以额外指定多px的话,可能会出现我上面描述的这些问题

踩坑记录三:缩小verticalContent还是遇到手机兼容的问题

经过上面的两个踩坑点,UI小哥乖了很多。切图只是切1px的内容了,也按照要求把verticalContent设置到了红白区域之间。切图从No1切到了No2

要求切的两张图


这时候按照平时的.9来说,已经满足UI的需求了,但是当项目跑起来的时候,实锤打脸。屏幕dpi较低的机型,头部的红色区域块还是会拉伸。

最后才有一个觉悟:即使图片控制了拉伸区域,但是他的其他部分都是不可拉伸的。所以白色区域的确是拉伸了,但是在高dpi上面加载低dpi的图片,那么图片肯定会被拉伸的。

最后需要UI小哥再根据主流的分辨率做了分别的切图,才真正的解决了这个问题

参考链接:不同dpi下的.9图


Bad Patch背后的逻辑

刚刚上面说了左上控制拉伸,右下控制内容填充。

按照官方的文档说明(简直不要太简单):在.9工具使用的时候,选中show bad patches按钮,图片会显示红色的区域块,红色区域块标识这块内容为"脏区域",而且"脏区域"仅仅会作用于拉伸区域(即左上区域)。 那这个"脏区域"会引起什么问题呢?

官网解释是这样:Visual coherence of your stretched image will be maintained if you eliminate all bad patches.
当所有的bad patches都消除之后,才能保持图片拉伸区域的一致性,所以换句话说=> 不消除"脏区域"可能会导致填充区域不能响应拉伸区域,所以图片就会不一致;但是假若图片在.9拉伸预览的时候,显示正确就没多大问题了,也不需要过多担心

虽然Stack Overflow 的这个NinePatch Bad Patches Pose说到不影响渲染,但是既然出现了这个问题,还是消除好一点。
,后面Google找到关于bad patches的产生与影响的点,这边贴下bad patches的pose
NinePatch Bad Patches 思考

Bad Patches是如何产生的?

例如有这样一张图,bad patches的产生只是发生在拉伸区域,所以我们需要关注的是left和top区域

假若我们将left和top的拉伸区域,先放到一个简单的维度查看(只看top或者只看left),然后将这块区域切片再重叠,那将得到类似这样的一张图片,left和top拆分后,会分成若干个区域

最后可以划分出8个区域,A,B,C,D,E,F,G

然后再将这八个区域进行1px的像素值进行划分,top区域进行水平划分,left区域进行垂直划分


切片之后,Android Studio会先从top区域横向对比当前区域的所有像素值,检查是否一致。然后再从left区域纵向对比当前区域的所有像素值,检查是否一致。
假若不一致的情况下它就是bad patches。那么他要检查得多细致呢?一个颜色值的差别都算,虽然肉眼看出来颜色很相似,但是差别一个颜色值也是差别.

那么他是怎么实现对比呢?,那垂直方向为例,垂直方向的切片会在这A B C E H这几个区域里面横向检查,去检查每一块切片的像素是否完全一致。假若组内像素值不一致,那么这个组就是一个 bad patches

同样滴,水平方向也是如此,会在C D E F这四个区域里面垂直检查每个切片的像素是否完全一致。假若组内像素值不一致,那么这个组就是一个 bad patches

那么至于交叉的部分C E,则需要检查两次,即垂直方向要检查一次,水平方向也需要检查一遍,假若组内像素值不一致,那么这个组就是一个 bad patches

例子验证

上面的pose主进行了一次测验,测验如下:

创建了十张不同的.9图,每张.9图在不同的区域里面均有像素值的差别。那bad patches就在这些区域上面展示出来了

但是也存在一个特殊的例子,例如一张这样的图片,也是一张很常见的图片,带阴影的.9图。按照上面所说的:AndroidStudio会检查组里面的全部像素值是否一致,但是阴影一般都是多个不同色值的像素组成的,所以尽量拉伸值


遇到.9图 bad patches需要怎么处理?

Pose主和Stack Overflow的回答都是比较直接:Google对bad patches的解释太隐晦了,只是简单解释会引起图片拉伸和内容区域不一致。但是Pose主都认为,假若在预览情况下面发现bad patches的话,先看看右侧的预览是否正确,假若预览正确的情况下那可以直接忽略bad patches了。

但是这里有一个更好的办法:

假若图片拉伸区域简单,那么请把left和top的拉伸像素值设置成1px,都可以直接避免bad patches的产生。
解释:按照上面bad patches产生的原因,因为垂直方向和水平方向的像素值只有1,所以group也只有一个,不能作为横纵向对比。那么他们只剩下一个交叉区域的对比了,但是交叉区域又是1个px的,所以也没有对比可言,所以就不会产生bad patches了。

关于.9图失效以及.9图不可以错过的细节点相关推荐

  1. 图机器学习——5.9 图神经网络:图的增广

    由于在实际的训练中,原始的图结构往往不是训练的最优图结构.下面我们考虑如何对图进行增强(graph augmentation),这个类似于数据扩增,提升训练效率,模型的泛化能力及测试集的准确率. 这种 ...

  2. 【ECharts】环形图、饼状图

    目录 color设置的颜色 环形渐变色 圆环中间显示文字 悬浮显示中间文字 悬浮显示中间文字,默认显示第一个 循环高亮饼图块 label文字过长重叠 label和饼图一致 label展示位置 内容为0 ...

  3. 灰度图,法线贴图,置换贴图和位移贴图

    查看全文 http://www.taodudu.cc/news/show-5684567.html 相关文章: OC置换可以混合.相乘.相加吗?多个置换贴图叠加 unity-shader-曲面细分与置 ...

  4. Typora gitee图床迁移github图床教程(图文详细)

    目录 一.GitHub配置 二.Picgo的配置 三.将gitee仓库导入到GitHub中 四.批量修改图片路径 就在前几天,gitee宣布将开源仓库全部人工审核,在审核到图床仓库时,显示 因此为了保 ...

  5. 实验报告C语言实现图的深度遍历,图的深度优先遍历的C语言实现.pdf

    图的深度优先遍历的C语言实现.pdf 维普资讯 九 江 职 业 技 术 学 院 学 报 JournalofJiujiangVocational&TechnicalCollege 2004.2 ...

  6. 计算机及网络应用基础思维导图_思维导图在生物教学中的应用

    思维导图又叫心智图,是由一个中心向周围有层次的发散的图形,由词汇.图形.线条.编号等构成,应用不同颜色的笔画出各级分支,既是一种思维工具又是一种学习方法.生物学科中含有大量的概念.生物分类.生物特征等 ...

  7. Scrum 工件: 速度图和燃尽图

    速度图 Velocity用于衡量scrum团队持续提供业务价值的速度,可以采用历史估算的方法,衡量一个又一个sprint的速度.团队通过跟踪完成达到自己团队完成标准的故事点的数量,就可以基于相对点值对 ...

  8. 使用Leangoo共享脑图/思维导图做多级需求管理

    上篇介绍了如何使用Leangoo思维导图实现影响地图.本文,将介绍如何用Leangoo脑图来做多级需求管理. 什么是Epic? Epic是史诗故事,通常需要花费多个Sprint来开发和测试,才能完成最 ...

  9. 在线作图|如何画韦恩图(包含upset图)

    韦恩图(包含upset图) 韦恩图(Venn diagram)用于展示在不同的事物群组(集合)之间的联系.R 语言中的维恩图绘制有很多包,Vennerable(最多9维),VennDigram(最多5 ...

最新文章

  1. PowerShell收发TCP消息包
  2. python爬虫框架排行榜-常用python爬虫框架整理
  3. 360企业安全2019暑期实习算法岗笔试
  4. Ubuntu Linux 8.04系统JAVA配置方法
  5. Python稳基修炼的经典案例12(计算机二级、初学者必会的字符文件处理)
  6. Windows2003操作系统SQL Server 2008安装图解(详细)
  7. 游戏设计的100个原理(6-10)
  8. 关于Windows勒索病毒以及445端口防护
  9. Python爬虫生成二维码应用,突显个性味道
  10. Qt与flash交互实现(播放Flash动画)
  11. 青云mysql_青云分布式数据库RadonDB 深度兼容MySQL
  12. 关于多径效应,平坦衰落,频率选择性衰落以及瑞利衰落的理解
  13. C20_OC10-内存管理
  14. No provider available from registry localhost:9090 for service
  15. 求不规则四边形的面积
  16. 市场刚需亚马逊测评还能不能做?如何评论、提升排名、打造爆款
  17. 请问 e^π 和 π^e 哪个大?
  18. Dockerfile最佳实践【原创、很多实践经验】
  19. java彩虹雨_彩虹雨源码
  20. elm FatFs文件系统移植总结

热门文章

  1. 人工神经网络有哪些应用,人工神经网络包括哪些
  2. 使用python监控NTP系统(时钟服务器)
  3. MOV AX,DATA MOV DS,AX
  4. [回忆]2007年的GDNT研发广东北电辞职信.
  5. MyBatis 多表关联查询
  6. Swin Transformer 不重叠窗口
  7. 微信电脑版聊天记录转移
  8. Linux中如何新建用户
  9. uboot2021.10-nandflash-3.initr_nand
  10. Texmaker+Miktex配置