5

I am developing an app, which needs to use images that have a resolution higher then (2000 x 2000) for text clarity purposes.

I have a Background image, over which I need to show Overlay Images with the same resolution. The number of overlays are variable, from 2 to 30.

As loading the Image with UIImage, it takes 4 Bytes for every pixel, so if one image has resolution 3000x3000, it will take up-to 34 MB of memory, 15 MB for 2000 x 2000.

Thats where the problem rises, the app crashes after loading 4-5 images on 3GS, and 11-13 images on iPhone 4.

The Overlays need to be placed exactly over the background image. They are just like what we have in Google Maps traffic Overlays. This doesn't rule out tiling, but makes the task relatively complex.

How should I handle this problem?

Tiago Almeida
  • 14,081
  • 3
  • 67
  • 82
Haris Hussain
  • 2,531
  • 3
  • 25
  • 38
  • 1
    This problem can either be solved through tiling or reconsidering the business logic. – Pinser Sep 17 '12 at 11:49
  • Yes, i want to know if there is a way i can handle this problem without tiling. – Haris Hussain Sep 17 '12 at 11:50
  • I'm assuming you're using MapKit considering you mention both Overlays and Google Maps. MKOverlayView *is* a tiled view and as such you probably shouldn't rule out tiling. The MK framework will call `drawMapRect:zoomScale:inContext:` on your overlay view and, as a best practice, you should *only* render to the content as per the provided bounding rect. – Tim Reddy Sep 17 '12 at 15:28
  • 2
    try [this](https://developer.apple.com/library/ios/#samplecode/LargeImageDownsizing/Introduction/Intro.html#//apple_ref/doc/uid/DTS40011173) from apple, it's downsizing the image without affecting the resolution. – Scar Sep 17 '12 at 17:04
  • 1
    Check out the Advanced Scrollview presentation from WWDC2010 - this covers tiling large images using `UIScrollView`. For images of this size, there's really no alternative other than tiling. – TimD Sep 17 '12 at 19:12
  • @ T Reddy - No, im not using MapKit, these are just images used in ScrollView. @ Scar - This is a great example, thanks :) this example also uses tiling for the handling of such large images. @ TimD - Yes, i think there is no alternative other than tiling. – Haris Hussain Sep 18 '12 at 07:27

1 Answers1

0

Definitely, you can't load whole image set into memory at once. You need to load only visible portion of image data and should unload invisible part as fast as possible.

If you want to solve this at QuartzCore level, there's CATiledLayer class just for this purpose.

Apple Reference: https://developer.apple.com/library/mac/#documentation/GraphicsImaging/Reference/CATiledLayer_class/Introduction/Introduction.html

Apple Sample Code: https://developer.apple.com/library/mac/#samplecode/CALayerEssentials/Introduction/Intro.html#//apple_ref/doc/uid/DTS40008029

Additional informations: http://red-glasses.com/index.php/tutorials/catiledlayer-how-to-use-it-how-it-works-what-it-does/

To use this layer, you need to split source images into many tiles. And supply them when the layer needs it. (drawLayer:inContext: method.) The method will be called on non-main thread, so user-interface won't be blocked. Don't forget freeing invisible tile's image to save memory.

Also, you can implement this with low-level OpenGL code with dynamic resource loading using background thread. In this case, you can use PVRTC lossy, in-memory compression which can save video-memory usage a lot, but it's really painful, and time-consuming work. I recommend using of CATiledLayer. This is enough for most cases.

eonil
  • 83,476
  • 81
  • 317
  • 516