Is PNG preferred over JPEG for all image files on iOS? - iphone

Xcode optimizes png images so they are loaded faster, but is this also recommended for other image resources that are not for buttons and UI (Photos for example)?
Or is it a standard to have UI images as png and "photos" as JPEG?
What is the best practice here?

The best practice is to use PNG files as often as possible when using images within your app. iOS and Xcode load and display PNGs quickest as opposed to any other type of format. If given a choice, go with PNG.
When you use any other file type (or if you load a non-optimized PNG files), your iPhone has to do the byte-swapping and alpha premultiplication at load-time (and possibly re-do the alpha multiplication at display time). Your application basically has to do the same processing that Xcode does, but it's doing it at run-time instead of at build-time. This is going to cost you both in terms of processor cycles and memory overhead. One of the reasons why Mobile Safari is the biggest memory hog of the built-in iPhone applications is because the images it has to load in order to display web-pages are all non-optimized images, mostly JPEGs. Since JPEG is a compressed format, it has the added extra step of having to decompress the image into memory before it can do the premultiplication and byte-swapping.

For what it's worth, Apple recommends using the PNG format for images. There's a lot more information on this topic in this Apple documentation.

Related

What is the fastest way to load compressed images on iOS?

I am writing an iOS app which need to load a lot of full-screen size images into OpenGL. Image storage space is a concern, so I am using png or jpg. Problem is: Loading the image data takes way too long (100s of ms on an iPad2).
I was wondering if someone knows the fastest way to load good-quality compressed image data on an iPad or similar? This could include switching to different image compression formats (?)
Here's what I've found:
Loading jpg via the iOS implementation of libturbo-jpeg is faster than any way I found for png.
If you split jpg images in two, you can parallel-decompress via GCD which almost cuts the load time in half. Still not enough!
The PowerVR compressed PVRTC format can be loaded very quickly, but both compression ratio and image quality are way outside what I need...
No idea how jpeg-2000 would perform, but it seems to be optimized for compression ratio rather than decoding speed.
Any ideas?? This must be a common problem for games or similar..
Are there any newer image formats (jpg is 1986!!) which have portable implementation, maybe slightly less compression than jpg, but decode much faster?
This library might help you out:
https://github.com/path/FastImageCache

How to use a vector image (.svg) with best quality in another format for iPhone?

I have a vector graphics .svg to create a image for iPhone. I know I can't use a .svg directly to iPhone because cocoa touch don't render it (maybe with others libs).
So, I have to convert the image for a format to use in iPhone. So, what is the best format to have the best quality in iPhone? I will create image for Retina (2x) and for normal.
Is it .png the best choice? Any idea?
PNG is definitely the best choice as it's the de-facto standard on iOS. The SDK processes PNGs in build phase and they can be loaded into memory directly. So they're super fast. You need to have normal PNGs and #2x to support retina display.
Rendering vector-based graphics usually costs much resources (just as writing codes to draw with the Core Graphics API). On a mobile device, using raster graphics balances the performance and the quality. I think there's less cases in which we want to scale the UI elements to any level.
Creating 2 sets of design elements do cost you more time, but it's acceptable. With batch processing, you can save some time. Be sure to check each graphic on the real devices and manually refine it for better looking.

web loadable 80x80 thumbnail images - best format choice if compression is done on the server

I've read many of the png vs. jpg threads here and elsewhere. I didn't find this aspect covered for small images that are downloaded from a server.
A short recap:
Xcode optimizes png images that are delivered with the app bundle in a way that they are optimized for the iOS hardware ("png magic")
png images support transparency (which I don't need)
png is the better choice from graphics, jpg for pictures (we have pictures)
I'm building an app that periodically downloads feeds that contain links to thumbnail images (size 80x80). These images are presented side by side the text content in a tableview. I can influence which format is used (jpg, png) on the server side.
If I use an uncompressed png format, it will have about 17k size for one image. This is quite large. And since this png doesn't use the "png magic" of Xcode, the iPhone still might need quite some cpu to get them into the table view compared to an "Xcode prepared" png.
The same image as a compressed jpg is only 3k which is great.
Question: are there lab comparisons that show the real world performance of these 2 formats?
Another one: has anyone used jpgs of a similar size (80x80, 3k) successfully in a table-view?
Many thanks in advance
What do you mean "lab comparisons"? PNG is going to do better with flat colors -- it uses variations on run-length and dictionary encoding as I understand. JPEG will be better with images containing subtle gradients, and loses data mostly in jumps in luminosity which are hard for the human eye to see. "Better" here refers only to file size. It sounds like you would want JPEGs here.

When to use PNG or JPG in iPhone development?

I have an app that will display a bunch of images in a slideshow. Those images will be part of the bundle, thus distributed with the app.
All the images are photographs or photographic, etc.
I've read that it's preferred to use PNG as the image format, but seeing that the JPG version will be much smaller, I'd rather be using that.
Are there any guidelines which format to use and in which case?
PNG's are pixel perfect (non-lossy), and require very little extra CPU energy to display. However, large PNGs may take longer to read from storage than more compressed image formats, and thus be slower to display.
JPG's are smaller to store, but lossy (amount depends on compression level), and to display them requires a much more complicated decoding algorithm. But the typical compression and image quality is usually quite sufficient for photos.
Use JPG's for photos and for anything large, and PNG's for anything small and/or designed to be displayed "pixel perfect" (e.g. small icons) or as a part of a composited transparent overlay, etc.
Apple optimizes PNG images that are included in your iPhone app bundle. In fact, the iPhone uses a special encoding in which the color bytes are optimized for the hardware. XCode handles this special encoding for you when you build your project. So, you do see additional benefits to using PNG's on an iPhone other than their size consideration. For this reason it is definitely recommended to use PNG's for any images that appear as part of the interface (in a table view, labels, etc).
As for displaying a full screen image such as a photograph you may still reap benefits with PNG's since they are non-lossy and the visual quality should be better than a JPG not to mention resource usage with decoding the image. You may need to decrease the quality of your JPG's in order to see a real benefit in file size but then you are displaying non-optimal images.
File size is certainly a factor but there are other considerations at play as well when choosing an image format.
There is one important thing to think about with PNGs. If a PNG is included in your Xcode build it will be optimized for iOS. This is called PNG crush. If your PNG is downloaded at run time it will not be crushed. Crushed PNGs run about the same as 100% JPGs. Lower quality JPGs run better than higher quality JPGs. So from a performance standpoint from fastest to slowest it would go low quality JPG, high quality JPG, PNG Crushed, PNG.
If you need to download PNGs you should consider crushing the PNGs on the server before the download.
http://www.cocoanetics.com/2011/10/avoiding-image-decompression-sickness/
The Cocoanetics blog published a nice iOS performance benchmark of JPGs at various quality levels, and PNGs, with and without crushing.
From his conclusion:
If you absolutely need an alpha channel or have to go with PNGs then
it is advisable to install the pngcrush tool on your web server and
have it process all your PNGs. In almost all other cases high quality
JPEGs combine smaller file sizes (i.e. faster transmission) with
faster compression and rendering.
It turns out that PNGs are great for small images that you would use
for UI elements, but they are not reasonable to use for any full
screen applications like catalogues or magazines. There you would want
to choose a compression quality between 60 and 80% depending on your
source material.
In terms of getting it all to display you will want to hang onto
UIImage instances from which you have drawn once because those have a
cached uncompressed version of the file in them. And where you don’t
the visual pause for a large image to appear on screen you will have
to force decompression for a couple of images in advance. But bear in
mind that these will take large amounts of RAM and if you are
overdoing it that might cause your app to be terminated. NSCache is a
great place to place frequently used images because this automatically
takes care of evicting the images when RAM becomes scarce.
It is unfortunate that we don’t have any way to know whether or not an
image still needs decompressing or not. Also an image might have
evicted the uncompressed version without informing us as to this
effect. That might be a good Radar to raise at Apple’s bug reporting
site. But fortunately accessing the image as shown above takes no time
if the image is already decompressed. So you could just do that not
only “just in time” but also “just in case”.
Just thought I'd share a bit of decompression performance data...
I'm doing some prototyping of a 360 degree viewer - a carousel where the user can spin through a series of photos taken from different angles, to give the impression of being able to smoothly rotate an object.
I have loaded the image data into an array of NSData's to take file i/o out of the equation, but create NSImage's on the fly. Testing at near max frame rate (~25 fps) and watching in Instruments I see the app is clearly CPU-bound and there's an approximately 10% increase in CPU load showing ~275 kb png's vs. ~75 kb jpg's.
I can't say for sure but my guess is the CPU limit is just from general program execution and moving all the data around in memory, but that image decompression is done on the GPU. Either way and the JPG vs. PNG performance argument looks to favour JPG, especially when the smaller file sizes (and therefore smaller sizes of objects in memory at least in some parts of the chain) is taken into consideration.
Of course every situation is different, there's no substitute for testing...
I have found massive differences in animation performance when using jpegs vs png. For example placing three screen-sized jpegs side by side in a UIScrollView and scrolling horizontally on an iPhone4 results in lag and a thoroughly unpleasant jerky animation. With non-transparent pngs of the same dimensions the scrolling is smooth. I never use jpegs, even if the image is large.
I think if you want to use transparent, you have no choice except PNG. But, if your background is opaque already, then you may use JPG. That is the only difference I can see
'Use JPEG for photos' as mentioned in Human Interface Guidelines under section Produce artwork in the appropriate format.

Convert .png to PVRTC *on* the iPhone

Is there a standard mechanism or known library that will convert .png images to compressed PVRTC textures on the iPhone itself (not during development using the standard tools on OS X).
I have a number of .png textures in my application but swapping is an issue. I'd like to create PVRTC variants of the .pngs on the device, should the available memory be low on application startup (or perhaps on first load of the application).
I haven't seen any information on the net regarding how to construct PVRTC images manually and to the best of my knowledge there is no support for this built into the iPhone (and it wouldn't be needed to read the PVRTC files).
For most applications, there is little sense to include or construct both versions of the files. Under optimal conditions, the PVRTC versions should be virtually indistinguishable from the PNG versions and are really just "pre-processed" versions of the files optimized for direct streaming into the video memory.
It is generally best to go through all of your images and make decisions regarding how to best package the image to balance memory conservation and quality for all users, not just under specific restricted memory situations.
A few things to consider (apologies if this is redundant knowledge):
PVRTC files can have problems with complex alpha blended images as the pre-processing can cause unsightly artifacts along the blended edges.
Opaque PNG files should have their alpha channel removed in the original image (saving memory and blending overhead).
For images with a limited range of colors, reduce the image from PNG32 to PNG16 or PNG8 to save memory on disk.
If this is for OpenGL based programs, consider using an enhanced version of Texture2D (such as from Cocos2D) which supports alternate pixel formats such as 565 and 4444. This can greatly reduce the overhead in the graphics card with minimal impact on image quality, by carefully choosing a pixel format which corresponds to the balance of colors in the original image.
Additionally for OpenGL based programs, avoid individual images (320x480) for backgrounds as this will result in a 512x512 texture in memory for each one. Break the image into smaller pieces or make the image 512x512 and fill the extra space with other images so that only one texture needs to load.
As with everything, focus on the largest images first to get the biggest bang for the buck.
It's also worth noting that since your application will be the only thing running (other than system applications), the only real memory overhead is going to be a limited amount of "disk" space. Making a second copy of all the image files will actually be working against you instead of helping.
Barney
I'd be careful assuming that this will help you. Once you reference the images once, i.e. load them into a UIImage, the iPhone will start to cache your pngs whether you like them or not. Compressing them will not serve you well to achieve what you're looking for here, in my opinion.
If you want to compress images to PVR on IOS, you may consider the OpenSceneGraph plugin pvr :
http://www.openscenegraph.org/projects/osg/browser/OpenSceneGraph/branches/OpenSceneGraph-3.0/src/osgPlugins/pvr/ReaderWriterPVR.cpp .