iOS Image Compression Algorithm - how would I go about creating one? - iphone

I am working on a portion of an app that has uses an ImagePickerViewController to take pictures/use existing pictures for a profile page. I am reducing the size of the resolution of the pictures (all JPEGs) to 480x320 and than compressing it fine. The problem is that I have no way to determine which photos need to have resolutions reduced and compressed.
Now what I want to do is write an algorithm to reduce the resolution of a picture if it is larger than 480x320 and adjust the compression level of a picture so that it will be around 30-50 KB in size. The compression level will scale with the size of the picture so anything less than 30-50 KB has no compression, anything more has as much compression as needed to hit 30-50 KB.
How would I go about writing an algorithm to handle this?

You'll need to do trial and error -- resize the image to 480x320, then save it as a JPEG at, say, 95% quality. Check the file size and if it's too big, try again at 90%. Repeat until you get into the right range.
This will potentially be relatively slow (several seconds?) so do this on a background thread.

Related

Should I resize images from camera / photo library before sending over network?

The images I am getting back from the photo library and camera are HUGE, and it takes a significant amount of time to send them over the network even in good conditions. I can't imagine a scenario in which I would need the full double-digit MB image, but maybe I'm missing something? Is it common practice to resize them before sending them over the network?
Yes it is common practice to alter an image's dimensions and compression so that it is appropriate for application.
As observed, by the default images from the camera are very large so that they can be displayed on large screens, printed to posters, zoomed and cropped etc without appearing unduly pixelated. So unless the app in question is a photo/image manipulating app, then resizing will almost certainly be beneficial in that it can improve networking, the app's memory foot-print and it's overall snappiness.
In terms of how to size and compress, while it is possible to store multiple versions of the image for each device that's being supported.
Practically, it seems that storing a single image at the dimensions required on the lowest resolution device but then only compressing it enough so that the higher resolution devices can scale up as needed without looking ugly seems to deliver reasonable results.
In terms of resizing, there are various posts on SO e.g. How do I resize the UIImage to reduce upload image size
I've also stuck gist for the UIImage extension I'm currently using to do this in my App over on GitHub here.
Have fun.
You can transform the image into data and then use this:
let imageData = image!.jpegData(compressionQuality: 0.5)!
It will make the quality less than usual with 50% to be able to save it quickly and smoothly

Why did the images increase in size after importing them into Unity?

I have a large set of jpg images with a total size of 10 mb, but when I import them into unity, their size increases several times! How do I keep the original size of the images?
Above answers are wrong, thus, I decided to explain it further here.
Be careful, size for disk is different from size in ram/gpu.
The one you found in import settings is the size on ram. The default one(without mip) should be the smallest size(almost) for app size.
Although it shows bigger size in import settings, your app will still compressed them again for the build app, and app installer.
Why the size in ram is so huge?
In graphic rendering, all the images(no matter jpg or png) will be read and decode. The decoded result will be all pixels array..etc, depending on your texture format(after decode), you will have different size in ram.
However, your source image is usually the highly compressed(encoded) image for disk storage. That's why you get a bigger size after importing to Unity. It counts on how many pixels in total.
You can still keep the original size, only if you keep it as separate resource and load it in runtime. as external resource in resource folder etc. However, it won't reduce the memory usage in RAM or GPU.
Any images which you imported to the project, will be resampled and encoded by their format. The size you see in import settings, which is also the size for ram.
JPEG or PNG is just a format for disk storage. The size you seen inside unity is the size in Ram for rendering. The larger the size, the more ram it needs too.
If you are looking for smaller app size, Unity's default compression will be the best(without mipmap). When you export as apk for example, it will recompress all the assets anyway.
Of course you can still keep the original image as external source and load it in runtime, but your overall app size with external source will be much huge, according to my experience.
As external image in resource folder won't be compressed together with the app assets.
you can click at image in unity ,the image has a propertie call Pixel per unit
you can adjust it to control size of image

Reduce image file size without resize and quality lose

In a site i am daily uploading around 100+ images that have taken from digital cameras, a single image file have an average file size of around 3MB. It needs high amount of disk space in server. If i can reduce the average size below 1MB i can upload more images in the current space.
I have tried many online image optimizers, but all of them can't helped me to reduce below at least 1.5MB.
jpeg-tools.com is a best site to optimize images, they accept a maximum of 20MB image files. You will never face any quality lose.

iPad retina landing page size - 2MB

The landing page for an ipad retina (i.e 1536 x 2048) is about 2MB. Apple seems to mandate using a PNG for landing pages. Is it possible to reduce this file size? (my landing page is really simple already)
actually the byte size of image not only depends upon the resolution but also on bit depth.
e.g. 100x100 PNG 16bit/24bit
you can reduce the bit depth of the png if you feel like it is not affecting the image quality and if you do find the image quality becomes unacceptable on reducing bit depth then your image is not that simple.
you can also use colors/gradient instead of an image so that you can completely remove the image
you can also use the tiled image (if it suits you) and can keep a small image in the resources.
see... you have lots of choices my friend..!!
I am using ImageOptim to reduce all my images. Works great and fast. Just download, open and drag and drop a folder or all your images onto the interface.
http://imageoptim.com/
There is even a case study on how well this tool can be used to shrink your iOS-Apps:
http://imageoptim.com/tweetbot.html
Use Image Optimiser. You can optimise image online.

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.