14

In the iPhone sample code "PhotoScroller" from WWDC 2010, they show how to do a pretty good mimmic of the Photos app with scrolling, zooming, and paging of images. They also tile the images to show how to display high resolution images and maintain good performance.

Tiling is implemented in the sample code by grabbing pre scaled and cut images for different resolutions and placing them in the grid which makes up the entire image.

My question is: is there a way to tile images without having to manually go through all your photos and create "tiles"? How is it the Photos app is able to display large images on the fly?

Edit Here is the code from Deepa's answer below:

- (UIImage *)tileForScale:(float)scale row:(int)row col:(int)col size:(CGSize)tileSize  image:(UIImage *)inImage
{
CGRect subRect = CGRectMake(col*tileSize.width, row * tileSize.height, tileSize.width, tileSize.height);
CGImageRef tiledImage = CGImageCreateWithImageInRect([inImage CGImage], subRect);
UIImage *tileImage = [UIImage imageWithCGImage:tiledImage]; 
return tileImage;
}
Scar
  • 3,460
  • 3
  • 26
  • 51
Jonah
  • 4,810
  • 14
  • 63
  • 76

5 Answers5

12

Here goes the piece of code for tiled image generation:

In PhotoScroller source code replace tileForScale: row:col: with the following:

inImage - Image that you want to create tiles

- (UIImage *)tileForScale: (float)scale row: (int)row column: (int)col size: (CGSize)tileSize image: (UIImage*)inImage
{
    CGRect subRect = CGRectMake(col*tileSize.width, row * tileSize.height, tileSize.width, tileSize.height);
    CGImageRef tiledImage = CGImageCreateWithImageInRect([inImage CGImage], subRect);
    UIImage *tileImage = [UIImage imageWithCGImage: tiledImage];
    return tileImage;
}

Regards, Deepa

WrightsCS
  • 50,551
  • 22
  • 134
  • 186
spd
  • 2,114
  • 1
  • 29
  • 54
  • Deepa, Thanks for the code. I am getting a bunch of errors when I try to use it. Would you mind inserting as code so it formats correctly. I may be making a simple transcription error. Thanks! – Jonah Dec 09 '10 at 01:52
  • Wow, I got it working. Thanks so much. It's a little slow on the fly, but it does what it's supposed to. I'll paste the code in my question above. – Jonah Dec 09 '10 at 03:51
  • @Jonah: what do you pass in to the inImage? When you call tileForScale in the drawRect, what are you passing as the inImage? – fes Jun 21 '11 at 11:41
  • The image that you want to tile – spd Jun 22 '11 at 09:59
5

I've found this which may be of help: http://www.mikelin.ca/blog/2010/06/iphone-splitting-image-into-tiles-for-faster-loading-with-imagemagick/

You just run it in the Terminal as a shell script on your Mac.

iwasrobbed
  • 46,496
  • 21
  • 150
  • 195
  • That's pretty cool and could save a lot of time. But, what I was looking for is a way to do it within the phone. For example, the Photos app is able to quickly pan/zoom even large images. My guess is that it tiles the images automatically. But, I may be wrong. – Jonah Jul 28 '10 at 16:13
3

Sorry Jonah, but I think that you cannot do what you want to.

I have been implementing a comic app using the same example as a reference and had the same doubt. Finally, I realized that, even if you could load the image and cut it into tiles the first time that you use it, you shouldn't. There are two reasons for that:

  1. You do the tiling to save time and be more responsive. Loading and tiling takes time for a large image.
  2. Previous reason is particularly important the first time the user runs the app.

If these two reasons make no sense to you, and you still want to do it, I would use Quartz to create the tiles. CGImage function CGImageCreateWithImageInRect would be my starting point.

Jorge Ortiz
  • 1,556
  • 1
  • 16
  • 19
  • Definitely agree about doing the tiling yourself in the program... you'd have to load the image into memory which defeats the purpose of tiling to begin with (to save memory). Might be able to upload images to a server and have it pre-cut the images and then re-download them. – iwasrobbed Sep 03 '10 at 12:15
  • That makes sense. But, my question is then: How on earth does the photos app do it? Someone can email you a 10mb photo and it's works perfectly in the photos app. So if not tiling within the app, how'd they do it? – Jonah Sep 03 '10 at 14:48
  • As I mentioned, it can be done with Quartz and the impact isn't so big when the user assumes that it is importing a photo, I think. As for iTunes, you can read a message that says something like "Optimizing photos for the iPod", which I guess is for the tiling – Jorge Ortiz Sep 03 '10 at 22:41
3

Deepa's answer above will load the entire image into memory as a UIImage (the input variable in his function), defeating the purpose of tiling.

Ben Jackson
  • 860
  • 8
  • 11
2

Many image formats support region-based decoding. Instead of loading the whole image into memory, decompressing the whole thing, and discarding all but the region of interest (ROI), you can load and decode only the ROI, on-demand. For the most part, this eliminates the need to pre-generate and save image tiles. I've never worked with ImageMagick but I'd be amazed if it couldn't do it. (I have done it using the Java Advanced Imaging (JAI) API, which isn't going to help you on the iPhone...)

I've played with the PhotoScroller example and the way it works with pre-generated tiles is only to demonstrate the idea behind CATiledLayer, and make a working-self contained project. It's straightforward to replace the image tile loading strategy - just rewrite the TilingView tileForScale:row:col: method to return a UIImage tile from some other source, be it Quartz or ImageMagick or whatever.

alexantd
  • 3,543
  • 3
  • 27
  • 41
  • If what you're saying is correct, this seems like an amazing solution! Do you know how I would go about getting the ROI without loading the whole image into memory with ImageMagick? Will a simple crop, similar to what this person is doing work? Will something like this load the whole image into memory? http://www.mikelin.ca/blog/2010/06/iphone-splitting-image-into-tiles-for-faster-loading-with-imagemagick/ – Homeschooldev Mar 17 '14 at 08:53