I currently working on a project that i need to display large images on a UITableView,this is very common problem for a lot of developers and learning with they threads i reached to the following procedure:
NOTE:The large images i refer,they all have 300x300px(600x600px,retina) and about 200kb,JPEG
Create a NSOperationQueue;
Download images asynchronously(Each image has 600x600px,corresponding to the #2x image);
Resize and create the non retina image(300x300px image);
Decompress both images;
Store all images on a NSCache;
After all that procedures have finished i update my UITableView on the main thread.I'am using a UITableViewCell subclass to draw all my needed content(As seen on Apple's sample codes).The main problem is that i'm confused about step 4(decompress images),my doubts:
NOTE:I'm currently storing my decompressed images on a NSCache.
Should i decompress the images and store then as UIImage's or NSData's?
How can i store the decompressed images?(NSCache,NSMutableArray...)
What is the best way to pass the decompressed image to my UITableViewCell subclass?
NOTE:I'm using the decompression code presented here:link
You can't really store an UIImage object to disk, but you can turn it to NSData using UIImagePNGRepresentation
Using UIImage will give you cache out of the box, I bet it's the most efficient you can get
Just put the image into UIImageView, Apple spent a lot of time on making image rendering fast.
That said, your images are not particularly big, especially for retina devices, I would advice looking at something like AFNetworking library that has a complete and tested solution for this problem.
Plus, you can look up the code of AFImageRequestOperation which does exactly what you need: download, store, cache, reuse.
Related
I have a lot of png images in my app which is causing my app to overload the real memory usage of my iPad2 device. My whole app folder with lots of sound files and png images is only about 50-60 MB precompiled, 90 MB on device, but still I'm easily going up to 300MB++ at run time.. ViewControllers on top of former ViewControllers etc.. which I'm also trying to fix..
What I find strange is that by just displaying one background .png image I'm adding 12 MB onto real memory usage(seen in instrument). The image that I used to fill a ImageView image in the storyboard is only 700 KB in my project folder. Taking it out or leaving the image field empty saves me 12 MB of memory...
I'm using a lot of these background images as well as other foreground images in the app which is eating up way to much space.
Any suggestions or help is appreciated
Thanks.
Well, 700kb image on disk space doesn't mean 700kb image in memory. It is compressed while stored on disk, but when it is taken into memory - it will grow in size.
If you are using a lot of images in your project, I would recommend using [UIImage imageWithContentsOfFile:] method. It doesn't cache images internally and you have more control over the memory than using [UIImage imageNamed:].
For me, the general rule of thumb is this. If the image is huge and used once in the app -> [UIImage imageWithContentsOfFile:], but if the image is reused in many places over the app -> [UIImage imageNamed:].
In addition, if you have to use .png format because it has transparency, then you might try giving .webp a chance. This format is not supported officially in ios, however there is a custom implementation on github you can take a loot at.
UPDATE:
I personally don't use interface builder in my apps at all, as I find it extremely time consuming and slow. Instead I create all views programmatically, that gives me more flexibility like choosing between [UIImage imageWithContentsOfFile:] or [UIImage imageNamed:]. You can just set an Outlet to your UIImageView and then set the actual image in code.
As for pngs, there is no such thing as the preferred type of images in iOS. It really depends on your case. If you need transparency -> png, need just a plane image -> jpg. This is just a simple example.
And as for .webp, this format, as I have already mentioned, is not officially supported in iOS, but you can add your own support for it. Basically, .webp will let you replace .png and reduce the size of project folder without loosing transparency in your images.
Hope this helps, cheers!
I am new with cocs2d. I have created an app using Cocos2d. The app is working fine but problem is that application size is too large 350MB. There are many images in this app. I have used png and where possible jpeg images. There are many png images that have larger than 1 mb.
Is there any way to reduce the application size. I've reduced the size whereever possible. Is there any other format that can be used in place of png? There are no many animations. The png are used only purpose of transparency.
Your images are way out of size. Even if you put them on server, and then download it will take time to download.
The best option is to reduce the image size. A couple of sites that can help you do that are:-
Reduce image size
Compress image size
You can keep the image content on your server and then download the image content asynchronously (which is more imp download it first). If there are levels then download initial levels first and download remaining on the background thread. You can always display a loader on launch and display some help kinda stuff meanwhile the data gets download and cached.
You can make use of SDWebImage and other libraries to get your images stuff async.
Hope it helps.
While your pictures are fairly large and you should try to reduce the number and size, you can make gains through packaging the .png into pvr.ccz files. There are multiple different programs available to do this. I like to use Texture Packer which is available here: http://www.codeandweb.com/texturepacker
You can find some tips in my post on reducing memory usage & bundle size.
Most importantly use texture atlases in .pvr.ccz format and where possible reduce image color depth to 16 bit. Avoid JPGs altogether because they're terribly slow to load in cocos2d.
There is no issue in using png files although your images are too large, You can reduce their size by 70 - 80% by using tinypng and it will not going to hurt your graphics.
https://tinypng.com/
I usually edit the image size now https://resizeimage.io , you try!
I'm taking images from the camera or the camera roll and I'm saving them to core data using an ImageToDataTransformer class. I need to use these saved images in two different places in my app: 250x250 imageview and 50x50 imageview.
First, should I use png format for both imageviews?
Second, can I compress the image before I save it to core data, and what's the best way?
Third, should I save two different images, one for the big image and another for the thumbnail in a different view?
When Xcode builds your project, it automatically optimizes PNG files included in your project. So, I guess you should use PNG.
I don't know about runtime.
That would be a good idea if you have a table view and you want to show thumbnails. You wouldn't want to be loading the huge files, that would be excruciatingly slow.
I have around 20 tableview cells that each contain a number (2-5) thumbnail sized pictures (they are VERY small Facebook profile pictures, ex. http://profile.ak.fbcdn.net/hprofile-ak-sf2p/hs254.snc3/23133_201668_2989_q.jpg). Each picture is an UIImageView added to the cell's contentview.
Scrolling performance is poor, and measuring the draw time I've found the UIImage rendering is the bottleneck.
I've researched/thought of some solutions but as I am new to iphone development I am not sure which strategy to pursue:
preload all the images and retrieve
them from disk instead of URL when
drawing cells (I'm not sure if cell
drawing will still be slow, so I want
to hold off on the time investment
here)
Have the cells display a placeholder
image from disk, while the picture is
asynchronously loaded (this seems to
be the best solution, but I'm
currently not sure exactly how to do
best do this)
There's the fast drawing
recommendation from Tweetie, but I
don't know that will have much affect
if it turns out my overhead is in network loading
(http://blog.atebits.com/2008/12/fast-scrolling-in-tweetie-with-uitableview/)
Thoughts/implementation advice? Thanks!
Suggest you do a search in the XCode help docs for LazyTableImages. It's a sample app provided by Apple that asynchronously loads images into a table cell. It should be a good starting point.
You'll probably want to add a local cache to save the images so you don't have to keep downloading them each time, and a way to prune out old images out of the cache.
I have an iPhone application that downloads images from the internet and saves them for display later.
The user can select the images to view from a UITableView, the table view has custom cells which display thumbnails of the original images in varying sizes.
When the large image is first downloaded it is scaled to thumbnail size and the thumbnail is saved using UIImagePNGRepresentation.
What I would like to do is save the thumbnail in the optimized iPhone PNG format. How can I do that? does it happen magically just by loading the original large image into memory and saving it? Do I have to do any further processing on the thumbnail before saving?
Chances are the UIImagePNGRepresentation does not create the images, as they are non-comformant PNGs, and can't be read by anything else. If they API generated PNGs that could not be read I think it would document that, and anyone who uploads PNGs from the phone would notice that they did not work.
The optimization is useful, but most of the optimized PNGs are part of the UI where the optimization is done as part of the build process. Chances are the cost of performing the optimization will offset any gains you get from it.
So it turns out that the RGB565 colorspace used in the optimized format is simply not available in a CGGraphicsContext, which is the rendering class used by all the UIwhatever components.
So if I DID write some code to change the color space of the image before saving it, I couldn't get the texture back into a UI class. The only way to use it is to load it directly into the OpenGL innards and use OpenGL in my app.
Don't worry about the "optimized PNG" format, as it isn't making any significant difference.
It does not affect rendering speed at all, and loading speed is dictated by file size more than file format.
So simply save it in a format that will give you smallest files. If you're not using transparency, then it might be JPEG.
If you need transparency, and can spend more CPU time when saving images, then include pngquant in your program (it's under BSD-like license) and shrink those PNGs to 8-bit palette.