Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Huge images in iOS app without CATiledLayer?

I have an image at about 7000x6000px. I need this to be in a scrollview/imageView in my app, however this is way to huge for display. It is supposed to be a kind of map. I was hoping to keep the size of the app to the minimum, and the image is just about 13mb in .jpg. In .png it is over 100mb, which is unacceptable. Many have suggested CATiledLayer as an option, but I believe this would result in even bigger file sizes. Anyway, I tried to do it with CATiledLayer, and create my own tiles in TileCutter, (tiles in .jpg), and the size wasn't too bad. But I am having errors all over the place. The iOS version of CATiledLayer is a mystery to me, and I can't find a way to solve this. I get an error saying something about the java-equivalent "index out of bounds of array", even though the array has content at that specific index.. It has a method which returns an array. The array contains data of a .plist. Before the return I log out the content of the array, giving me good data. The call is trying to access

[array objectAtIndex:0]

and put it in a dictionary, but throws OutOfBounds. When logged out the whole array, I can clearly see the content, but when logged out

NSLog("%@",[method objectAtIndex]); I get the same exception.

Anyway, CATiledLayer has given me nothing but problems. I have been reverse-engineering the PhotoScroller project with no luck. Anyone have any other solutions?

Thanks.

like image 822
Sti Avatar asked Nov 30 '22 23:11

Sti


2 Answers

Apple has this really neat project, PhotoScroller, that uses CATiledLayer and lets you scroll through several images and zoom them. This seemed really neat until I found out that Apple "cheated" and pre-tiled the images (about 800 tiles saved as file in the bundle!)

I had need for a similar capability, but had to download the images from the network. Thus came about PhotoScrollerNetwork. With the TiledImageBuilder you can download (or read from disk) massive images - I even tested a 18000x18000 image - and it works.

What this class does is start tiling the image as it downloads (when using libjpegturbo) or can save the file then tile (takes longer). The class figures out how many levels of detail are needed to show the image at full resolution and sized to fit in the containing view (a scrollview).

The class uses the disk cache to hold the tiles, but uses and old Unix trick of creating a file, opening it, then unlinking it so that the tiles never really get saved - once the class is dealloced (and the file descriptor closed) the tiles are freed (or if your app crashes they get freed too.

Someone had problems on an iPad 1 with its quite limited memory, so the class now throttles its use of the file system when concurrently loading multiple images. I had a discussion with the iOS kernel manager at WWDC this year, and after explaining the throttling technique to him, he said the algorithm (on managing the amount of disk cache usage) was probably the best technique that could be used.

like image 184
David H Avatar answered Dec 05 '22 08:12

David H


I think those who suggested CATiledLayer are right. You should really use it! If you need a sample project that displays a huge bitmap using that technology, look here: http://www.cimgf.com/2011/03/01/subduing-catiledlayer/

Many technologies we use as Cocoa/Cocoa Touch developers stand untouched by the faint of heart because often we simply don’t understand them and employing them can seem a daunting task. One of those technologies is found in Core Animation and is referred to as the CATiledLayer. It seems like a magical sort of technology because so much of its implementation is a bit of a black box and this fact contributes to it being misunderstood. CATiledLayer simply provides a way to draw very large images without incurring a severe memory hit. This is important no matter where you’re deploying, but it especially matters on iOS devices as memory is precious and when the OS tells you to free up memory, you better be able to do so or your app will be brought down. This blog post is intended to demonstrate that CATiledLayer works as advertised and implementing it is not as hard as it may have once seemed.

like image 23
Krumelur Avatar answered Dec 05 '22 10:12

Krumelur