如何在3e20画廊加载图像



在我的服务器上,每张图像有三个文件。

  • 一个缩略图文件,被裁剪为128 * 128。
  • 一个小文件,我最大的尺寸是160 * 240。
  • 一个大文件,我最大的尺寸是960 * 540。

将这些url返回到three20的图库的方法如下所示:

- (NSString*)URLForVersion:(TTPhotoVersion)version {
    switch (version) {
        case TTPhotoVersionLarge:
            return _urlLarge;
        case TTPhotoVersionMedium:
            return _urlSmall;
        case TTPhotoVersionSmall:
            return _urlSmall;
        case TTPhotoVersionThumbnail:
            return _urlThumb;
        default:
            return nil;
    }
}

记录了调用这些不同值的时间后,会发生以下情况:

  1. 当缩略图页面加载时,只调用缩略图(如预期)
  2. 当点击图片时,会显示缩略图,而不是小图片。
  3. 缩略图出现后,直接加载大图(不显示小图)。

我希望发生的事情如下

  1. 这是相同的(缩略图加载预期在主页上)
  2. 点击图片时,先加载小图片
  3. 然后加载大图。

或者,下面的

  1. 直接显示大图。

拇指的问题是,我把它裁剪成了一个正方形。

这意味着当缩略图在主查看器中显示时(在拇指被点击之后),它是超大的,当大图像加载时,它会立即缩小以适合。

这看起来真的很糟糕,对我来说,如果它在缩略图视图中加载拇指,然后在细节视图中加载小图像和大图,那就更有意义了。

有没有人对如何解决这个问题有任何建议?
最好的方法是让拇指的宽高比相同吗?

我很感激你对这个问题的任何建议

查看three20源代码,我可以看到TTPhotoView使用以下逻辑加载预览图像:

- (BOOL)loadPreview:(BOOL)fromNetwork {
  if (![self loadVersion:TTPhotoVersionLarge fromNetwork:NO]) {
    if (![self loadVersion:TTPhotoVersionSmall fromNetwork:NO]) {
      if (![self loadVersion:TTPhotoVersionThumbnail fromNetwork:fromNetwork]) {
        return NO;
      }
    }
  }
  return YES;
}

问题是,由于您的小图像在服务器上而不是在本地,代码跳过图像并使用缩略图进行预览。

我建议你最好的解决方案是编辑缩略图,使它们具有与大图像相同的宽高比。这似乎是这个类的开发者所期望的!

我认为你有三种方法:

  1. 修改TTPhotoView的实际loadPreview实现,使其实现您想要的逻辑(即,允许从网络加载小版本);

  2. 子类TTPhotoView和覆盖loadPreview的效果与上述相同;

  3. 预缓存小版本的照片;例如,修改/子类TTThumbView,这样当设置TTPhotoVersionThumbnail时,它会预缓存TTPhotoVersionSmall版本;在这种情况下,由于图像已经在本地存在,loadPreview将找到它,而无需外出到网络;顺便说一句,你可以在任何时候做预缓存,你认为适合你的应用;要预缓存图像,您需要使用适当的URL创建一个TTButton(这将为您处理TTURLRequest和缓存);

  4. 否则,你可以通过使用这个UIImage类别从小版本到缩略图版本进行即时裁剪;在这种情况下,您还应该通过覆盖imageForCurrentState方法来调整TTThumbView的绘制方式,以便在必要时应用裁剪。同样,要么直接修改TTThumbView,要么创建它的子类;或者,你可以在你的照片视图控制器中定义layoutSubviews,并在那里修改你拥有的每个TTThumbView:

    - (void)layoutSubviews {
        [super layoutSubviews];
        for (NSInteger i = 0; i < _thumbViews.count; ++i) {
             TTThumbView* tv = [_thumbViews objectAtIndex:i];
             [tv contentForCurrentState].image = <cropped image>;
    

如果您不喜欢使用私有方法contentForCurrentState,您可以简单地这样做:

            [tv addSubview:<cropped image>];

正如你所看到的,每个选项都有它的优点和缺点;1和2是最容易实现的,但小版本将从网络加载,所以它可能会增加一些延迟;4也是如此,尽管方法不同;3给你最响应的实现(没有额外的延迟从网络,因为你预缓存),但它可能是最复杂的解决方案实现(要么你下载的图像和缓存自己,或使用TTButton为你做的,这是一种不是很"干净")。

无论如何,希望这对你有帮助。

最新更新