在iPhone示例代码中“PhotoScroller",它们展示了如何通过滚动、缩放和分页图像来很好地模仿照片应用程序。他们还平铺图像以展示如何显示高分辨率图像并保持良好的性能。
示例代码中通过抓取不同分辨率的预缩放和剪切图像并将它们放置在构成整个图像的网格中来实现平铺。
我的问题是:有没有一种方法可以平铺图像,而无需手动浏览所有照片并创建“平铺”?照片应用程序如何能够动态显示大图像?
编辑
以下是 Deepa 的回答中的代码:
- (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;
}
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;
}
发布评论
评论(5)
Deepa 上面的答案会将整个图像作为 UIImage (其函数中的输入变量)加载到内存中,从而破坏了平铺的目的。
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.
许多图像格式支持基于区域的解码。您可以按需加载和解码 ROI,而不是将整个图像加载到内存中、解压缩整个图像并丢弃除感兴趣区域 (ROI) 之外的所有图像。在大多数情况下,这消除了预先生成和保存图像图块的需要。我从未使用过 ImageMagick,但如果它做不到,我会感到惊讶。 (我使用 Java Advanced Imaging (JAI) API 完成此操作,这对 iPhone 上的您没有帮助...)
我已经使用了 PhotoScroller 示例及其工作方式使用预先生成的图块只是为了演示 CATiledLayer 背后的想法,并制作一个独立的工作项目。替换图像图块加载策略很简单 - 只需重写 TilingView
tileForScale:row:col:
方法即可从其他来源(无论是 Quartz 或 ImageMagick 或其他来源)返回 UIImage 图块。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.下面是生成平铺图像的代码片段:
在 PhotoScroller 源代码中,将tileForScale: row:col: 替换为以下内容:
inImage - 您想要创建平铺图像的图像
问候,
迪帕
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
Regards,
Deepa
我发现这可能有帮助: http://www.mikelin.ca/blog/2010/06/iphone-splitting-image-into-tiles-for-faster-loading-with-imagemagick/
您只需在 Mac 上的
Terminal
中将其作为 shell 脚本运行即可。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.抱歉乔纳,但我认为你不能做你想做的事。
我一直在使用相同的示例作为参考来实现一个漫画应用程序,并且有同样的疑问。最后,我意识到,即使您可以在第一次使用图像时加载图像并将其切成图块,但也不应该这样做。这样做的原因有两个:
如果这两个原因对您来说没有意义,并且您仍然想这样做,那么我会使用 Quartz 来创建图块。 CGImage 函数 CGImageCreateWithImageInRect 将是我的起点。
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:
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.