PNG (Portable Network Graphics)

Refer to the W3C[7] definition of PNG, an extensible file format for lossless, portable, and well-compressed raster image storage.

Compress PNG Files

As we mentioned in the iOS package reduction exercise, iOS image resources need to be compressed and added to our project.

When it comes to image compression, there is a Compress PNG Files option in the Build Setting of Xcode, and most articles have mentioned that compressed images may become huge after Compress PNG Files.

Compress PNG Files Compress PNG Files

Apple will handle PNGs

PNG images for iPhone and iPad apps may have been optimized for performance using Apple’s modified PNGCrush tool, a process called Compress PNG Files.

Pngcrush Caught libpng error was raised during compilation when the image suffix was changed from JPG to PNG.

So what did Apple do with PNG images? Referring to pNGdefry [8] ‘s analysis against W3C[7]’ s definition, Apple generally does the following:

  • A private but critical data block named CgBI will be inserted.
  • Place in the image itselfIHDRBlock before
  • Stored in theIDATCompressed image data missing in blockzlibCompression head andAdler-32The checksum
  • 8-bit true-color images are stored in BGR/BGRA order instead ofIHDRThe RGB and RGBA order indicated in the block.
  • Image pixels use predetermined Alpha values
  • The modified file uses the file name extension.pngAnd internal file structures defined for valid images, but conforming to standardsPNGViewing and editing software can no longer handle them.

So, you can’t use PNG images from built IPA packages. You can use PngDefry [8] to view PNG images for iOS and pngCheck [9] to view normal PNG images.

When you get a PNG image from a built IPA package, you can decode it using the decode command and it’s ready to use.

validationCompress PNG FilesEffect on image size

We found the optimization command in Xcode, In the/Applications/Xcode. App/Contents/Developer/Platforms/iPhoneOS platform/Developer/usr/bin/iPhoneOS – optimize Obtain the corresponding compilation process optimization method – intercept the optimizePNGs part, which corresponds to the implementation of Compress PNG Files.

sub optimizePNGs { my $name = $File::Find::name; if ( -f $name && $name =~ /^(.*).png$/i) { my $crushedname = "$1-pngcrush.png"; my @args = ( $PNGCRUSH, "-q", "-iphone", "-f", "0" ); if ( $stripPNGText ) { push ( @args, "-rem", "text" ); } push ( @args, $name, $crushedname ); if (system(@args) ! = 0) { print STDERR "$SCRIPT_NAME: Unable to convert $name to an optimized png! \n"; return; } unlink $name or die "Unable to delete original file: $name"; rename($crushedname, $name) or die "Unable to rename $crushedname to $name"; print "$SCRIPT_NAME: Optimized PNG: $name\n"; }}Copy the code

Xcode gets the PNG image Apple needs by executing the Apple Modify PngCrush tool from all the.png image files in the file list.

Let’s use the header diagram from the previous article as the test case we need


xcrun -sdk iphoneos pngcrush -q -iphone -f 0 image.png image1.png
Copy the code

Remove the -q argument and you can see some information about this process:

Xcrun - SDK iphoneos pngcrush - iphone - f 0 image. The PNG image1. PNG | pngcrush 1.6.4 | Copyright (C) 1998-2002200-6 Glenn Randers-Pehrson | Copyright (C) 2005 Greg Roelofs | This is a free, open-source program. Permission is irrevocably | granted to everyone to use this version of pngcrush without | payment Of any fee. | the Executable name is pngcrush | It was built with libpng version 1.2.7, And is | running with libpng version 1.2.7 - September 12, 2004 (header) | Copyright (C) 1998-2004200-6 Glenn Randers - Pehrson, | Copyright (C) 1996, 1997 Andreas Dilger, | Copyright (C) 1995, Guy Eric Schalnat, Group Inc., 42, | and zlib version 1.2.11, Copyright (C) 1998-2002 (or later), | Jean - loup Gailly and Mark Adler. | It was compiled with LLVM Apple LLVM 12.0.5 (clang - 1205.0.19.59.6) [+ internal OS, ptrauth-isa=deployment-target-based] and modified by Apple as indicated in the sources. Recompressing image.png Total length of data found in IDAT chunks = 144033 IDAT length with method 120 (fm 0 zl 9 zs 1) = 215970 Best pngcrush method PNG (49.94% IDAT increase) (49.76% filesize increase) CPU time used = 0.064 seconds (Decoding 0.008, Encoding 0.042, other 0.013 seconds)Copy the code

The size of Compress PNG Files increased from 144033 to 215970. The essence of Compress PNG Files is that Apple uses PngCrush to process the required PNG images during compilation so that iOS platforms can use the images more quickly.

You can add the files to the project directory instead of Assets Catalogs and then build an IPA package to analyze the images using PngDefry [8] and PngCheck [9].

pngcrushextended

Apple modified the PngCrush tool in two main ways:

Code command: xcrun – SDK iphoneOS pngcrush – iPhone

Xcrun – SDK iphoneOS pngcrush -revert- iPhone – Optimizations

Image compression

In the iOS Package reduction Tip, we learned that resource issues are a major factor affecting package size, and image resources are the most common during development. Using the right image compression tool can effectively reduce the packet.

Lossy compression and lossless compression

Common compression tools include Tinypng, PngQuant, ImageAlpha, ImageOptim, PngCrush, OpTIPng, PNGOut, PNGNQ, ADVPNG, etc. According to their compression methods, they are divided into two camps: lossy compression and lossless compression

According to the data, Tinypng, PNGQuant, ImageAlpha and PNGNQ are lossy compression, basically using quantization algorithm, converting 24-bit PNG images into 8-bit PNG images to reduce the number of colors. Pngcrush, OpTIPng, PNGOut and ADVPNG are lossless compression, using DEFLATE algorithm based on LZ/Huffman to reduce data in IDAT chunk area of image. Generally, the compression rate of lossy compression is much higher than lossless compression.

Compression tools

The following two tools are recommended for background images, placeholders, and large label images that are common in projects

  • TinyPNG4Mac: Using the API provided by Tinify, the current free version of Tinify is compressed to no more than 20 pieces at a time and no larger than 5 megabytes. For the average iOS application, enough for daily development use
  • ImageOptim-CLI: automatically perform the higher compression rate for ImageAlpha lossy compression and ImageOptim lossless compression.

You can compare TinyPng with ImageOptim-CLI by viewing this table.

For small images, such as our common icon icon, we can compress the image by changing its encoding mode to RGB with Palette. You can use ImageOptim to change the encoding of the image to RGB with Palette.

imageoptim -Q --no-imageoptim --imagealpha --number-of-colors 16 --quality 40-80 ./1.png
Copy the code

Xcode Negative optimization

Take a closer look at the Palette algorithm from the Palette Images.

We generally use Assets Catalogs to manage the image resources. There will be corresponding optimization methods

During the build process, Xcode reprocesses the image with its own compression algorithm. In the process of building Assest. Car, Xcode will use AcTool to decode the PNG image of Assets Catalogs and obtain Bitmap data. And then use actool’s coding compression algorithm for coding compression processing. So lossless compression methods that don’t change the encoding may not make a difference in terms of the final package size.

For the same image, Xcode adopts different compression algorithms on different devices and iOS systems, which also leads to different sizes of images on different devices when downloading.

Assest. Car was analyzed with the Assetutil tool to obtain its specific compression method

sudo xcrun --sdk iphoneos assetutil --info ***.app/Assets.car > ***.json
Copy the code

Focus on the following fields: Compression, Encoding, SizeOnDisk.

  • Compression methods are different for different devices and iOS systems
  • Encoding Encoding mode
  • SizeOnDisk Specifies the exact size of the image
{
   "AssetType" : "Image",
   "BitsPerComponent" : 8,
   "ColorModel" : "RGB",
   "Colorspace" : "srgb",
   "Compression" : "deepmap2",
   "Encoding" : "ARGB",
   "Name" : "image",
   "NameIdentifier" : 51357,
   "Opaque" : false,
   "PixelHeight" : 300,
   "PixelWidth" : 705,
   "RenditionName" : "image.png",
   "Scale" : 1,
   "SHA1Digest" : "294FEE01362591334E3C3B4ECE54AF0EA8491781",
   "SizeOnDisk" : 113789,
   "Template Mode" : "automatic"
}
Copy the code

If APP Stochastic can be enabled to generate IPA packages for different devices, and then perform a single decompression for each IPA package, retrieving assets. car to export the corresponding Assets. json, You can also use the Assetutil method mentioned in JD’s APP Slimming practice to export the Assets.car file of a specific device from the assets. car file of the general package

Sudo xcrun -- SDK iphoneOS assetutil -- Idiom phone -- Subtype 570 -- Scale 3 --display-gamut SRGB -- GraphicsClass MTL2,2 -- Graphicsclassfallbacks MTL1,2:GLES2,0 -- Memory 1 -- Hostedidioms car,watch XXX /Assets. Car -o XXX /thinning_assets. CarCopy the code

For thin packages, the size of the image added to the project does not really reflect the impact it has on the build package. Keep in mind that the true size of the image is its ipA size — including images added to Asset Catalogs that are eventually converted to.car files, and the rest are images in packages and files in various bundles.

Compression of theharm

Don’t blindly pursue the maximum compression ratio, consider both the quality of the compressed image and the actual size of the file after Xcode.

Compressed completed picture as far as possible in the high resolution of the device to see if there will be any problems, let the UI take a good look, will not appear noise, burrs and other phenomena.

If an image has been compressed so lossy that its SizeOnDisk in Assets.car becomes large, but its performance across devices is acceptable, you can try adding it to the bundle and changing its image format to Data. So Xcode doesn’t compress it. But don’t forget to change the calling method to imageWithContentOfFile:.

View picture compression here[10]More theoretical basis.

JPG to PNG

JPG files added in Assets Catalogs will be converted to PNG format in the final.car file

When we ask the UI for an image, if the UI throws you a.jpg or a JPEG image, you professionally say, better give me a PNG image, or the system will convert to a PNG image.

On the home page, the JPG images we added to the project directory are built without any compression and their format in the package is unchanged.

For JPG images added to Assets Catalogs, we need to unpack them.carFile, let’s test the following JPG image as an example, its material name and file name areUntitledlogo.usingassetutilThe tool gets the corresponding JSON portion:

{
   "AssetType" : "Image",
   "BitsPerComponent" : 8,
   "ColorModel" : "RGB",
   "Encoding" : "JPEG",
   "Name" : "Untitledlogo",
   "NameIdentifier" : 16638,
   "Opaque" : true,
   "PixelHeight" : 300,
   "PixelWidth" : 705,
   "RenditionName" : "Untitledlogo.jpg",
   "Scale" : 1,
   "SHA1Digest" : "8AD0802190689DEC7778A28EEFFBE972F4121B5B",
   "SizeOnDisk" : 68122,
   "Template Mode" : "automatic"
}
Copy the code

Most tools for reverse-engineering.car files use Apple’s proprietary coreui. framework library to simulate Apple’s access to images and then use PngCrush to decode and restore PNG images. The essence is to extract its content using CUICatalog in CoreUI. Framework.

The author used the Asset Catalog Tinkerer and selected Assets. Car for our test

Then use its export function to export the image:

The result is two PNG images, yes, two decoded PNG images

For more tools, see Analysing Assets. Car file in iOS[11]As well as visualizations for QuickLook.carFile plugin[12], many tools are open source code, you can view the specific view.

conclusion

When using PNG or other image resources in a project, you need to consider the impact on the overall package size. For PNG resources added into the project, APP will process them for faster reading.

PNG images added to the Asset Catalog, lossless compression of PNG images may have no effect in their final construction, but lossy compression may conflict with Apple’s own compression method, resulting in negative optimization.

In general, active compression is not required for Asset Catalog PNG image resources.

The resources

CgBI_file_format: iphonedev. Wiki/index. PHP/C…

Douyin quality construction – iOS installation package size optimization practice: juejin.cn/post/691631…

Today’s headline iOS installation package size optimization – the new stage, new practices: mp.weixin.qq.com/s/oyqAa8wKd…

PNG image compression contrastive analysis: mp.weixin.qq.com/s/0ajYgnP3m…

TinyPNG4Mac:github.com/kyleduo/Tin…

ImageOptim-CLI:github.com/JamieMason/…

Portable Network Graphics (PNG) Specification (Second Edition) : www.w3.org/TR/PNG/

Pngdefry – Repairing – iPhone Fried PNGs:www.jongware.com/pngdefry.ht…

Pngcheck:www.libpng.org/pub/png/app…

Chapter 9. Compression will and Filtering:www.libpng.org/pub/png/boo…

Analysing Assets. The car file in iOS:stackoverflow.com/questions/2…

QuickLook visuals.car file plugin: blog.timac.org/2018/1112-q…

Asset Catalog Tinkerer: github.com/insidegui/A…