My fellow developer and I are creating an iPhone app that is creating a composite image. The idea is to have 36 images in a 6x6 grid. Each original image is 400x300px. Hence the final image after processing should be 2400x1800px.
Disclaimer: I'm not doing this programming mysel开发者_开发百科f in particular. My fellow programmer is not on SO and for various reasons I'm compelled to ask for him. I'm personally a .Net developer so forgive my question if it's obvious.
Now, apparently this is creating memory issues. His solution thus far has been attempts to draw the composition to an UIImageView or CATiledLayer, and saving the composition by taking a screenshot of the view. All attempts thus far have either crashed the application due to memory issues, or produced black areas in the composition.
My question is presumably simple. How do we create a large (offscreen?) image, draw the 36 partial images to this composition, save the composition, then put it in an appropriate component that can be viewed by the user?
Edit:
My buddy found the solution himself in the end. I'll post it here together with the accepted answer in order to contribute to the SO wiki :)
UIGraphicsBeginImageContext(svPreview.contentSize);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(ctx, [[UIColor blackColor] CGColor]);
CGContextFillRect(ctx, CGRectMake(0, 0, svPreview.contentSize.width, svPreview.contentSize.height));
for(UIImageView *subview in [svPreview subviews]) {
[subview.image drawAtPoint:subview.frame.origin];
}
UIImage *rawImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(rawImage, self, nil, nil);
The obvious mechanism would be a UIScrollView. It's an object meant to display an image, or a group of images, that are bigger than the screen, and it comes with easily implementable functionality to zoom and scroll.
You'll find a good primer in Apple's Scroll View's Programming Guide to iOS.
You would just need to
- create a new scroll view
- set its
contentSize
property to the total size of the extra large image you want to display - add either the one large image as a subview, or add all the small images, placing them appropriately to fit together
If you wanted to make the one large image, you could just create a large custom view that's the same size as the scroll view's contentSize
. Then, draw each smaill image in its own grid. Finally, add this large custom view as the scroll view's subview.
This is the obvious solution, but it might do everything you're looking for, and afford you some extra functionality.
Edit: A scroll view may be a good starting point, but you may still hit memory limitations. Searching for answers on making scroll views more efficient may be helpful. You may find some good ideas in this related question: ScrollView runs out of memory when it gets too big
Edit 2: The way to manage memory is detailed, code and all, in the above-mentioned guide. Take a look at the ScrollViewSuite demo's third example, on tiling. That should work perfectly for you since your image is already composed of tiles.
The idea is to make a sort of table view out of the scroll view that now recycles image tiles instead of cells. The scroll view is subclassed and a set of reusable tiles is kept as one of its instance variables. The key to the implementation is, in layoutSubviews
, to remove from superview the tiles that have moved out of the visible area, then recycle tiles for newly visible content and add them as subview. In this way, only visible tiles are loaded into memory.
Hope this works for you.
精彩评论