4

I've been stuck at this for quite some time. I've looked at many other answers and also at Apple's examples.

What I want to know is how I can go about loading large images in UIScrollView, and be able to page through them and zoom in to them, like the Photos app.

I'm working on an app where I need to scroll through large images (by large, I mean images greater than 1024 x 1024). I've already implemented something similar to what the photos app does. However, now that I'm using large images, I get memory warnings and stuff. I know why I'm getting the warning, and I know that I need to Tile the images.

Apple's examples demonstrate tiling with small images which are already present. My app will be downloading multiple images, saving them on a disk and the user will be able to look at them at a later time. Thus, I cannot have the images cut up using other programs.

I need something wherein I can tile the full size images. Any help will be greatly appreciated. Additionally, as I mentioned earlier, I know that I have to do something with Tiling. However, I'm new to this, and I would greatly appreciate if the answers contain some sample code, which I can use as a start off point.

I've looked at other questions, and none seemed to have been answered to my satisfaction, owing to which, I'm asking this question again.

Thanks again!

codeBearer
  • 5,114
  • 4
  • 25
  • 29

1 Answers1

3

To work with tiling you'll need to use a CaTiledLayer in your view. Googling for it will give you good information. Basically you declare that the UIVIew is using it, declare some levels of details for zooming and in the drawRect you'll receive each tile as the rect parameter.

To tile the image, load in a UIImage (it uses memory, but quite less than showing it) and use for each tile you want something like:

UIGraphicsBeginImageContextWithOptions(tileSize, YES, 1);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(ctx, -tileSize.width * columnNumber, -tileSize.height*rowNumber);
[img drawInRect:CGRectMake(0, 0, tileSize.width, tileSize.height)];
UIImage* imgCut = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

and save imgCut. You probably will want to generate tiling with different zooms if you use different level of detail in your CATiledLayer.

Luis
  • 1,282
  • 1
  • 11
  • 25
  • Thanks a ton for your reply. :) So, if I'm getting this correctly, I subclass a UIView and pass it a UIImage (the `img` variable). Assuming this UIView is the same as the TilingView in Apple's PhotoScroller app, then, if I put your code into the `- (UIImage *)tileForScale:(CGFloat)scale row:(int)row col:(int)col` method of Apple's PhotoScroller app, I will get a tiled version of my image? – codeBearer Sep 06 '11 at 19:29
  • I'd suggest to generate the tiles before showing the image and keep them in de cache dir, so you can free the big image after creating them and you'll have all tiles prepared. I don't know about that example, but it looks that this method will return the appropiate tile image for row, column and scale, so it should work – Luis Sep 07 '11 at 10:42
  • So I need to create tiles (by cutting up the image) either when I finish downloading the image or asynchronously when I'm about to load the image on to the screen? – codeBearer Sep 07 '11 at 15:32
  • You can do it on the fly, though it would mean to keep the big image in memory and to calculate them every time, which is slow. So yes, I think it's better to generate tiles after downloading the image, asynchronously or not(depending on your app requirements). – Luis Sep 08 '11 at 11:09
  • Hmm. Well, thanks a ton for your responses. Sorry for the late reply, I was away for the weekend. You are right. I need to cut up the images, either downsample and save them, or have them precut. None of them made any sense for the purpose of my application. Owing to that, I asked my backend engineer to provide me with thumbnails + full size images. That way, while scrolling rapidly, I use the thumbnails. The moment the user stops scrolling, I switch in the actual full size image. My memory usage has dropped and performance has gone up quite well owing to that. :) – codeBearer Sep 12 '11 at 22:56
  • Additionally, I'm accepting your answer as that is indeed one of the ways to get a smaller image from a larger one. If any one actually wishes to do it on the fly, they will be able to refer to it. So, thanks again for your time. :D – codeBearer Sep 12 '11 at 22:57