是否可以在 UIScrollView 中平铺图像而无需手动创建所有平铺?

发布于 2024-09-11 03:41:14 字数 884 浏览 2 评论 0 原文

在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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

全部不再 2024-09-18 03:41:15

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.

戴着白色围巾的女孩 2024-09-18 03:41:15

许多图像格式支持基于区域的解码。您可以按需加载和解码 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.

毁梦 2024-09-18 03:41:14

下面是生成平铺图像的代码片段:

在 PhotoScroller 源代码中,将tileForScale: row:col: 替换为以下内容:

inImage - 您想要创建平铺图像的图像

- (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;
}

问候,
迪帕

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

帅的被狗咬 2024-09-18 03:41:14

我发现这可能有帮助: 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.

余生共白头 2024-09-18 03:41:14

抱歉乔纳,但我认为你不能做你想做的事。

我一直在使用相同的示例作为参考来实现一个漫画应用程序,并且有同样的疑问。最后,我意识到,即使您可以在第一次使用图像时加载图像并将其切成图块,但也不应该这样做。这样做的原因有两个:

  1. 进行平铺是为了节省时间并提高响应速度。对于大图像来说,加载和平铺需要时间。
  2. 当用户第一次运行应用程序时,前面的原因尤其重要。

如果这两个原因对您来说没有意义,并且您仍然想这样做,那么我会使用 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:

  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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文