PPM图像详解和P3图像引起iOS 9崩溃闪退问题解决方案

一、iOS 9因图像格式不符导致闪退解决方案

iOS 9.3以下(9.1、9.2)对图像格式敏感。若是16位或P3的图像,会引发闪退。而且收集用户crash报告是一堆混乱的地方报错,并无法明确定位到出错的代码在哪里。出现大面积iOS 9.1、9.2系统用户闪退、崩溃的情况,请仔细回想一下此版本做的操作,大概率是加入了不符合规则要求的图片。

最常见也是最明显的犯错情况是加入了jpg、jpeg等类型的图片,而不是正紧的png切图。这样在加载UI的时候就会闪退了。

在 Xcode 8 中,当你资源文件中[含有16位图]或者[图片显示模式γ值为'P3']且iOS targets设定为iOS 9.3以下就会出现这个问题. 如果你的app需要支持广色域显示的话,那你必须得把target设置成iOS 9.3+,相反,如果你的app不需要支持广色域且你想兼容 iOS 9.3 之前的项目,你就得把所有的16位的或者显示模式为'P3'图片全都替换成8位模式的SRGB颜色的图片。

解决方案:

1、导出ipa包。(就用你之前发布时候打包的那个ipa包吧)

2、把该ipa文件修改后缀名.ipa 为 .zip. 这时候就变成了一个.zip的压缩包了。

3、解压该 .zip 文件. 解压后的目录里面会有一个包含着你的 app bundle 文件的 Payload 文件夹

4、 对Payload 文件夹下你的APP,右键,选择在终端中打开。(新建终端窗口。如果没有的话请自行百度如何把一个文件在终端中打开。)

5、输入:find . -name 'Assets.car'  (注意空格,不懂格式请直接复制。)

6、使用 assetutil 命令找到任何包含着 16-bit or P3 的资源文件, 对每个 Assets.car 之行以下命令 :

sudo xcrun --sdk iphoneos assetutil --info ./Assets.car> /tmp/Assets.json

扫描二维码关注公众号,回复: 1473850 查看本文章

注意这里的:./Assets.car是上一个步骤的输出结果,就是你的Assets.car的路径。

7、打开上一步生成的 /tmp/Assets.json 。输入:open  /tmp/Assets.json

然后就会弹出一个记事本,查看里面的内容。找包含“DisplayGamut": “P3”的图片或者BitsPerComponent值为16的图片,根据名字找到它,把它替换掉,可以找UI小姐姐重新设计个。如下图这个P3图片,是我从网上随便找的,所以。。唉。。坑到了。做切图还是请专业UI设计师吧。


把不符合规则的图片都替换掉之后就没问题了。做个检查,再打包一遍,重复上述步骤检查一下。

二、PPM图片格式详解

那么上述所说的P3,是什么意思呢?网络上并查不到直接的解释,不过可以从PPM图像格式说起。

PPM图像格式是由Jef Poskanzer 在1991年所创造的。PPM(Portable Pixmap Format)还有两位兄长,大哥名叫「PBM」,二哥人称「PGM」,他们三兄弟各有所长,下面为你们一一介绍:

PBM 是位图(bitmap),仅有黑与白,没有灰;
PGM 是灰度图(grayscale),即从黑到白是有程度之分的;
PPM 是通过RGB三种颜色显现的图像(pixmaps);

每个图像文件的开头都通过2个字节「magic number」来表明文件格式的类型(PBM, PGM, PPM),以及编码方式(ASCII 或 Binary),magic number分别为P1、P2、P3、P4、P5、P6。

也就是说,彩色图是P3或者P6,编码方式不同。ASCII格式适合人类阅读理解,可以用文本编辑器打开,读取对应图像的数据(比如PPM格式的RGB值)。 Binary格式适合机器阅读,按照二进制形式,顺序存储图像信息,不用空格分隔,所以图像处理起来更有效率,占用空间容量更少(由于缺少空格)。

下面着重讲解PPM格式:
PPM图像格式分为两部分,分别为头部分和图像数据部分。
头部分:由3部分组成,通过换行或空格进行分割,一般PPM的标准是空格。
第1部分:P3或P6,指明PPM的编码格式,
第2部分:图像的宽度和高度,通过ASCII表示,
第3部分:最大像素值,0-255字节表示。

图像数据部分:
ASCII格式:按RGB的顺序排列,RGB中间用空格隔开,图片每一行用回车隔开。
Binary格式:PPM用24bits代表每一个像素,红绿蓝分别占用8bits。

ppm是一种很简单的协议,下面我们使用文本编辑器和windows画图对其进行解释。


对比分析PPM文件
ppm支持注释 plain.ppm plain-注释.ppm
ppm支持ASCII和BINARY两种格式 plain.ppm binary.ppm
ppm支持两种格式分别使用魔术P3和P6 plain.ppm binary.ppm
该ppm文件为4*4的图片,最多支持16*16*16种颜色 plain.ppm bmp.bmp
记事本中比较ppm和bmp文件,发现图片格式都有不同的魔数 plain.ppm binary.bmp

下面我们通过另一张图确认二进制ppm内容究竟是什么样子的。


通过UE查看二进制文件,同样的我们发现,前三行为ppm文件的头部分”信息,然后第四行开始为二进制数据。

从“头部分”可以看出来文件teapot.ppm为P6格式(即二进制的ppm文件类型)的文件,256*256的图像大小,RGB的每个色彩值范围为0-255,也就是数8个byte表示一个R或者G或者B的颜色,8*3个byte(即3Byte)表示一个RGB颜色,UE查看器中矩形内的3Byte就是该文件的一个像素点,该值为135CC0。通过Photoshop可以查看该值颜色就是我们图片中显示的颜色。



参考文献:

https://stackoverflow.com/questions/42050549/app-downloaded-from-appstore-crash-in-9-3-lower-version-devices

PPM部分转载参考自:

https://blog.csdn.net/kinghzkingkkk/article/details/70226214

http://paulbourke.net/dataformats/ppm/

猜你喜欢

转载自blog.csdn.net/lyxleft/article/details/79788019