3

On my server, I have three files per image.

  • A thumbnail file, which is cropped to 128 by 128.
  • A small file, which I aspect fit to a max of 160 by 240.
  • A large file, which I aspect fit to a max of 960 by 540.

My method for returning these URLs to three20's gallery looks like this:

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

After having logged when these various values are called, the following happens:

  1. When the thumbnail page loads, only thumbnails are called (as expected)
  2. When an image is tapped, the thumbnail appears, and not the small image.
  3. After that thumbnail appears, the large image is loaded directly (without the small image being displayed).

What I desire to happen is the following

  1. This is the same (thumbnails load as expected on the main page)
  2. When the image is tapped, the small image is loaded first
  3. Then after that, the large image is loaded.

Or, the following

  1. Thumbnails
  2. Straight to large image.

The problem with the thumb, is that I crop it so it is a square.

This means that when a thumbnail image is displayed in the main viewer (after thumb was tapped), it is oversized, and when the large image loads, it immediately scales down to fit.

That looks really bad, and to me, it would make far more sense if it loaded the thumbs in the thumbnail view, and then the small image followed by the large image in the detail view.

Does anyone have any suggestions on how to fix this?
Is the best way simply to make the thumbs the same aspect ratio?

I would appreciate any advice on this issue

Alex Coplan
  • 13,211
  • 19
  • 77
  • 138

2 Answers2

1

Looking at the three20 source I can see that TTPhotoView loads the preview image using the following logic:

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

The problem is that as your small image is on the server and not locally the code skips the image and uses the Thumbnail for the preview.

I would suggest that your best solution would be to edit the thumbnails so that they have the same aspect ratio as the large images. This is what the developer of this class seems to have expected!

Grouchal
  • 9,756
  • 6
  • 34
  • 46
  • Do you think (if this is possible) it would make sense in terms of network/speed to force three20 to load the small image when tapped, and then the big? – Alex Coplan Nov 15 '11 at 15:56
  • I assume that the thinking behind this is that if you already have the large or small versions locally it would make sense to use them as the preview, but it would take longer to show the actual image if you first downloaded the small and then the large. The process will be much quicker if the thumbnail is shown as a placeholder and should feel quick to the user too (especially if the size of the images is the same). – Grouchal Nov 16 '11 at 18:32
0

I think you have three ways to go here:

  1. modify the actual loadPreview implementation from TTPhotoView so that it implements the logic you want (i.e., allowing loading the small version from the network);

  2. subclass TTPhotoView and override loadPreview to the same effect as above;

  3. pre-cache the small versions of your photos; i.e, modify/subclass TTThumbView so that when TTPhotoVersionThumbnail is set, it pre-caches the TTPhotoVersionSmall version; in this case, being the image already present locally, loadPreview will find it without needing to go out for the network; as an aside, you might do the pre-caching at any time that you see fit for your app; to pre-cache the image you would create a TTButton with the proper URL (this will both deal with the TTURLRequest and the cache for you);

  4. otherwise, you could do the crop on-the-fly from the small version to the thumbnail version by using this UIImage category; in this case you should also tweak the way your TTThumbView is drawn by overriding its imageForCurrentState method so that the cropping is applied when necessary. Again, either you modify directly TTThumbView or you subclass it; alternatively, you can define layoutSubviews in your photo view controller and modify there each of the TTThumbViews you have:

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

If you prefer not using the private method contentForCurrentState, you could simply do:

            [tv addSubview:<cropped image>];

As you can see, each option will have its pros and cons; 1 and 2 are the easiest to implement, but the small version will be loaded from the network so it could add some delay; the same holds true for 4, although the approach is different; 3 gives you the most responsive implementation (no additional delay from the network, since you pre-cache), but it is possibly the most complex solution to implement (either you download the image and cache it yourself, or use TTButton to do that for you, which is kind of not very "clean").

Anyway, hope it helps.

sergio
  • 68,819
  • 11
  • 102
  • 123