【问题标题】:Is it possible to tile images in a UIScrollView without having to manually create all the tiles?是否可以在 UIScrollView 中平铺图像而无需手动创建所有平铺?
【发布时间】:2010-07-26 18:38:35
【问题描述】:

在来自 WWDC 2010 的 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;
}

【问题讨论】:

    标签: iphone objective-c image uiscrollview tiles


    【解决方案1】:

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

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

    问候, 迪帕

    【讨论】:

    • Deepa,感谢您的代码。当我尝试使用它时,我遇到了一堆错误。您介意作为代码插入,以便格式正确。我可能犯了一个简单的转录错误。谢谢!
    • 哇,我搞定了。非常感谢。它在飞行中有点慢,但它做了它应该做的事情。我将把代码粘贴到我上面的问题中。
    • @Jonah:你向 inImage 传递了什么?当你在drawRect中调用tileForScale时,你传递的是什么作为inImage?
    • 要平铺的图像
    【解决方案2】:

    我发现这可能会有所帮助:http://www.mikelin.ca/blog/2010/06/iphone-splitting-image-into-tiles-for-faster-loading-with-imagemagick/

    您只需在Terminal 中将其作为 Mac 上的 shell 脚本运行即可。

    【讨论】:

    • 这很酷,可以节省很多时间。但是,我一直在寻找的是一种在手机中进行操作的方法。例如,照片应用程序甚至可以快速平移/缩放大图像。我的猜测是它会自动平铺图像。但是,我可能错了。
    【解决方案3】:

    对不起,乔纳,但我认为你不能做你想做的事。

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

    1. 您进行平铺可以节省时间并提高响应速度。大图像的加载和平铺需要时间。
    2. 用户第一次运行应用时,之前的原因尤为重要。

    如果这两个原因对您来说没有意义,并且您仍然想这样做,我会使用 Quartz 来创建图块。 CGImage 函数CGImageCreateWithImageInRect 将是我的起点。

    【讨论】:

    • 完全同意自己在程序中进行平铺...您必须将图像加载到内存中,这违背了平铺开始的目的(以节省内存)。可能能够将图像上传到服务器并让它预先剪切图像,然后重新下载它们。
    • 这是有道理的。但是,我的问题是:照片应用程序到底是如何做到的?有人可以通过电子邮件向您发送一张 10mb 的照片,它在照片应用程序中完美运行。所以如果不在应用内平铺,他们是怎么做到的?
    • 正如我所提到的,它可以用 Quartz 完成,而且当用户假设它正在导入照片时,我认为影响不是那么大。至于 iTunes,您可以阅读一条消息,上面写着“为 iPod 优化照片”,我猜这是为了平铺
    【解决方案4】:

    Deepa 上面的回答会将整个图像作为 UIImage(他的函数中的输入变量)加载到内存中,从而破坏了平铺的目的。

    【讨论】:

      【解决方案5】:

      许多图像格式都支持基于区域的解码。您可以按需仅加载和解码 ROI,而不是将整个图像加载到内存中、解压缩整个图像并丢弃除感兴趣区域 (ROI) 之外的所有图像。在大多数情况下,这消除了预先生成和保存图像块的需要。我从未使用过 ImageMagick,但如果它做不到,我会感到惊讶。 (我已经使用 Java Advanced Imaging (JAI) API 完成了这项工作,它不会在 iPhone 上为您提供帮助...)

      我玩过 PhotoScroller 示例,它与预先生成的图块一起工作的方式只是为了展示 CATiledLayer 背后的想法,并制作一个独立工作的项目。替换图像瓦片加载策略很简单 - 只需重写 TilingView tileForScale:row:col: 方法以从其他来源返回 UIImage 瓦片,无论是 Quartz 还是 ImageMagick 或其他。

      【讨论】:

      • 如果您说的是正确的,这似乎是一个了不起的解决方案!你知道我如何在不使用 ImageMagick 将整个图像加载到内存的情况下获得 ROI 吗?请问一个简单的作物,类似于这个人正在做什么工作?这样的事情会将整个图像加载到内存中吗? mikelin.ca/blog/2010/06/…
      猜你喜欢
      • 1970-01-01
      • 2012-08-15
      • 2011-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多