Which program or format to use for texture compression - ios

I have big image textures (4-12MB) and have resized them as much as I can without losing too much detail and would like to further compress them. Online compressors compress the 12.6MB image to 6MB without any problems, but Xcode doesn't support it (even though the compressed image is still .png), apparently because indexed color spaces are not supported for bitmap graphics contexts (according to CGBitmapContextCreate documentation and another post) and the compressed image uses them. If I try to use it I get an error:
CGBitmapContextCreate: unsupported color space.
I was looking through Apple documentation about compression and supported formats, but all I can find is information about how to compress images in code. I want to be able to apply an compressed (or otherwise reduced in size) image in the editor itself and not later in code. Is this possible?
If it is not possible to do this using a program, how should this be done via code in Swift? I found a lot of objective-C posts about this, but none that uses Swift.

Important: iOS does not support device-independent or generic color spaces. iOS applications must use device color spaces instead.
Use CGColorSpaceCreateDeviceRGB as the color space.

Related

Is there a way to compress a pdf made with pdfkit?

I’m using pdfkit to create multi-page documents with embedded images, and the files get really large quickly. I can compress them nicely afterwards using Preview on the Mac, and they still look great, so I’m wondering if there is perhaps a setting I’m missing in pdfkit that controls resolution or size, or if there is way to compress them after creating them.
No, there isn't a way of specifying the image compression using PDFKit. It's just putting the image data in a PDF wrapper.
I'd suggest that you probably don't want to reduce the size of the image; but just the compression level. However, if you do, you can use CGPDFDocument and scale the image to fit a particular-sized graphic context.
On macOS, it is possible to create a Quartz Filter programmatically, which can include options for compression, which you can then apply in the options when you write your PDF; but this isn't available in iOS.
(If you're using macOS's 'Reduce File Size' Quartz Filter when exporting from Preview, it's well-known to be not very good; many people have made better ones.)
However, you can set the JPEG compression level in a UIImage object, so you may be able to increase the compression in the image data before you convert it to PDF.
https://developer.apple.com/documentation/uikit/uiimage/1624115-jpegdata/

SVGKit performance and should it be preferred over PNG?

I have been looking at SVGKit and I am finding conflicting ideas. Some say it's slower than PNG and others saying it is fast.
I was hoping to get a recommendation and which route I should take. When I am exporting my vector graphics to PNG for display, would it not make sense to use an SVG instead ?
Of course this gives the added value that it remains a vector.
Or is it still recommended in exporting everything to a PNG ?
You might consider the middle-way introduced in Xcode 7. Here you add your assets to the project as vector images (PDF) and at build-time Xcode automatically generates the PNGs in all needed sizes (1x, 2x, 3x).
Personally, I only use SVGs when necessary, like if I need to be able to change the color of the (parts of the) image. I believe there can be a performance hit when resizing vector images at run-time, although Android uses vectors as default, so it might be insignificant.
SVG is most resource intensive and can be used if you need to display something that can be zoomed in and out while PNG should be preferred for most UI graphics (logos, icons, etc.), as it is crisp yet remains lightweight and fast to display so there is no way to compare SVG with PNG in term of Performance.
if you are going after a Crystal clear images you can use pdf based graphics, which are supported by Xcode Using Vector Images in Xcode
if you still need to implement SVGKit i always suggest using some tools (like SVGCleaner) to clean and simplify SVG in order to enhance performance.

iOS image quality improvement

Icons Are Pretty Right?
I'm working on an UI update in an iOS app, and trying to make things look a bit better with some new icons- but I seem to be incapable of determining how to save an image correctly so that it looks good in the interface!
As you can see from this image, if I include a white background with the image it looks great. If I take those same images and use an alpha background they look terrible! It appears that either the images aren't using the #2x correctly, or something else is going horribly wrong.
These images are either saved with GIMP as a png with alpha, or exported from inkscape, the originals are vector graphics. We get the same results from both avenues. I am using both a base imageName.png and imageName#2x.png for scaling.
Somehow, magically, I changed the a single image to greyscale in gimp, and changed the base size to 25px and it showed up with alpha correctly blended. Stock images from apple are also functioning correctly, so it absolutely seems to be something that I'm doing incorrectly when I'm saving the images.
The Setup in XCode
Basic Questions
Is there a certain bit depth, argb vs rgba format, or some other quirk that I need to know to get these images to show up correctly? Is there any way to verify that the program is loading the correct imageName#2x vs imageName? Is there some document that talks about integrated graphics (the iconography documentation isn't very helpful on technical details)
Actual Images
With Background:
Without Background:
I think you will find success if you just save the image at 4x the size you actually want and specify the size manually.

Xcode built-in png compression effects

I have a question about png-8 vs png-24 usage vs Xcode's built in "image compressor".
Some images converted to png-8 are just fine saved like that, because difference between png-24 version can't be noticed easily. But some images have to be stored as png-24 so that quality remains at high level... Same image is about 3 times smaller when saved like png-8, so I guess there would be some benefits in memory consumption when using png-8 vs png-24. But what I am not sure is:
Does iOS "likes" more png-24 ?
Are there any problems with using png-8 instead of png-24 in iOS and what is a preferred choice ?
What are benefits to optimize image in PS (or some program like TexturePacker) when COMPRESS_PNG_FILES in Xcode is set to YES because I suppose Xcode in some way overwrites our optimization done in PS?
What actually Xcode does when optimizing images?
I know that just letting Xcode to do what it suppose to do is probably more than enough, especially for newer devices with enough memory and cpu power, but I am curios what's happening "under the hood" and is it wasting of time doing optimization in Photoshop?
Does iOS "likes" more png-24?
iOS certainly likes its images to be close to its own hardware format (see below). However, it may not presume a certain format, or convert images at will. This would mean that the default postprocessing could convert images from palettized (8-bit) to true-color images, and that would be destructive if the application expects its images to contain a palette. There are many good & proper uses of palettized images.
Are there any problems with using png-8 instead of png-24 in iOS and what is a preferred choice?
Color depth - higher is better, for some kinds of images (but not all). Size - smaller is better (and for deciding when, you are on your own). Other than Sangony states, the PNG specification is generous enough to allow more than a single bit of alpha even in indexed mode. That is, the usual RGB palette may also be RGBA, including alpha. I am not aware of any "problems" with more common PNG formats, or even the uncommon ones.
What are benefits to optimize image in PS (or some program like TexturePacker) when COMPRESS_PNG_FILES in Xcode is set to YES because I suppose Xcode in some way overwrites our optimization done in PS?
Photoshop is not extremely good at optimizing PNGs, but then again it's certainly not one of the worst. pngcrush (the original) is written specifically to try and squeeze the very last byte out of a PNG -- but at its highest setting, it can really take a while to do so. I may have used Apple's modified pngcrush unknowingly, since it is "on" by default; I have not found such a huge delay when compiling code, so Apple's default may be not the highest possible setting. This suggests that manually running pngcrush could be worth the time, in which case you definitely do not want XCode to undo it.
What actually Xcode does when optimizing images?
The most visible 'optimizations' are: switching storage order from RGB to BGR and discarding the alpha channel by premultiplying it with the color channels. See also my earlier answer.
The storage order thingy is, presumably, optimal for the default target devices (iPads, iPhones). Premultiplying alpha is a common method of optimizing, because then it takes less calculations to display the images in real time. (There are some disadvantages to it as well.)
Without any exact measurements, one can only speculate if these optimizations really matter on modern hardware. All internal conversions to 'display' format may very well be cached as quickly as possible.
Xcode uses PngCrush behind the scenes to optimize .png files. Here is also a good blog post that can answer your questions.
Aside from the available colors between PNG8 and PNG 24, the main difference is the the transparency aspect.
PNG8 alpha can sometimes be somewhat jagged in appearance whereas PNG24 is much smoother. If alpha is not a concern for you and the image looks good enough, then PNG8 is probably the way to go.
PNG8 Alpha
PNG24 Alpha

Software for creating PNG 8-bit transparent images

I'm looking for software to create PNG8 format transparent images as per this article.
NOTE: I need a Linux solution myself, but please submit answers for other OSes.
pngquant does a good job of converting to PNG8 while preserving full transparency.
If you're size-conscious, you may also be interested in pngcrush, which can usually (losslessly) compress PNG files quite a bit.
I also needed a Linux solution and found pngnq to do a pretty good job. It seems to be designed specifically for creating 8-bit PNG images with alpha channels.
apt-get install pngnq # If on Ubuntu/Debian
For Mac: ImageOptim and ImageAlpha are GUIs that run pngcrush, pngquant, and various other normally command-line compression utilities. http://pngmini.com/
The link you provided references ImageMagick, which is an excellent toolkit for manipulating images on Linux.
Ah, if I remember correctly, when I have read this article some months ago, pngquant hadn't a Windows version. I see it has one now. So I tried it, and pngnq too.
The latter seems to do a slightly better job on the IceAlpha.png test image (from libpng.org), at the cost of a slightly bigger image (it can be post-processed with pngcrush or pngout anyway).
The dithering algorithms (the two of pngquant, the only one of pngnq) are different, and it might be worth having both tools, converting images with all algorithms and see what looks the best.
For the record, on the Windows side, IrfanView (4.10) displays these images very well (using the transparency level on each palette entry) while XnView (1.85.1) and GIMP (2.4) apply only a full transparency/opaque display, à la GIF: the light bulb given as an example in the linked article has a transparent background around it, but the orange part is fully opaque.
And the excellent utility TweakPNG shows we have a PLTE (palette, 222 entries) chunk and a tRNS (alpha values for palette colors, 222 entries) chunk. Even more, it allows to edit each palette entry, color and alpha level. It might be an interesting complementary tool for this format.
Note on IrfanView support: if it handles PNG8 correctly for transparency, it doesn't handle gamma information in PNG files: on the toucan image or the ping-pong image, I had to apply a gamma of 2.4 to get similar (lighter) colors.
Note also that IrfanView does an awful job of converting 32-bit PNG images to 256, allowing only one transparent color, which looks bad if full color was dithered!
I see that the GIMP manual states: "his “PNG8” format, like GIF, uses only one bit for transparency; only two transparency levels are possible, transparent or opaque. "
while the ISO/W3C standard states:
"The tRNS chunk specifies either alpha values that are associated with palette entries (for indexed-colour images) or a single transparent colour (for greyscale and truecolour images).". The PNG specification 1.2 added: "Although simple transparency is not as elegant as the full alpha channel, it requires less storage space and is sufficient for many common cases."
It looks like the unique transparent color is more implemented than the full transparency palette, alas. At least browsers get it right.
It depends on what exactly your original images look like.
If your images already contain 256 or fewer colors (RGBA values), you need only look at pngout (Windows) (Linux/BSD/Mac OS X ports), which you should already be using to optimize your PNG images anyway. It can't quantize images, but it can save them as 8-bit, including alpha transparency. Just pass in the /c3 (or -c3 on Linux et al.) color option to force it to save the image as PNG8.
If your images do contain more than 256 colors, you have a few more, but all less than perfect options:
Adobe Fireworks is probably the best option in terms of the resulting image quality. It will do the job if you only need to convert a few images, or if you don't mind relying on Fireworks to do the batch processing. I did find that it sometimes somehow limits the number of colors in the palette, creating a worse quality image than necessary. I don't know if that's perhaps a bug in CS3 that's been fixed in CS4.
If you're not on Windows or OS X this obviously isn't an option, and buying Fireworks just for this probably isn't worth it either.
The only alternatives I know of are the already mentioned pngquant and pngnq. I've had better luck with pngnq, but that's probably just going to depend on which quantization strategy works best on the files you're working with.
Unfortunately, I've noticed that neither of them work very well with small amounts of transparency (say, an opaque image with transparent, rounded corners).
I recommend "The GIMP" as it is possible to output in PNG8 and supports Linux/Windows. If you want a quick Windows-only solution, I also recommend IrfanView.
Microsoft Windows: Ultimate Paint (freeware and shareware
versions are available).
Both versions can save as an 8 bit transparent PNG image.
It can also save as a 4 bit PNG (16 colours). This cuts the
file size in half compared to 8 bit.
Input formats include BMP, GIF, ICO, JPG/JPEG and PNG.
The freeware edition of Ultimate Paint Standard 2.88 LE can
be downloaded directly from
http://www.ultimatepaint.com/up.zip (1.7 MB).

Resources