25

I use the same big images in a tableView and detailView. Need to make imageView filled in 40x40 when an imags is showed in tableView, but stretched on a half of a screen. I played with several properties but have no positive result:

[cell.imageView setBounds:CGRectMake(0, 0, 50, 50)];
[cell.imageView setClipsToBounds:NO];
[cell.imageView setFrame:CGRectMake(0, 0, 50, 50)];
[cell.imageView setContentMode:UIViewContentModeScaleAspectFill];

I am using SDK 3.0 with build in "Cell Objects in Predefined Styles".

LPL
  • 16,827
  • 6
  • 51
  • 95
slatvick
  • 1,207
  • 2
  • 16
  • 25

7 Answers7

32

I put Ben's code as an extension in my NS-Extensions file so that I can tell any image to make a thumbnail of itself, as in:

UIImage *bigImage = [UIImage imageNamed:@"yourImage.png"];
UIImage *thumb = [bigImage makeThumbnailOfSize:CGSizeMake(50,50)];

Here is .h file:

@interface UIImage (PhoenixMaster)
- (UIImage *) makeThumbnailOfSize:(CGSize)size;
@end

and then in the NS-Extensions.m file:

@implementation UIImage (PhoenixMaster)
- (UIImage *) makeThumbnailOfSize:(CGSize)size
{
    UIGraphicsBeginImageContextWithOptions(size, NO, UIScreen.mainScreen.scale);
    // draw scaled image into thumbnail context
    [self drawInRect:CGRectMake(0, 0, size.width, size.height)];
    UIImage *newThumbnail = UIGraphicsGetImageFromCurrentImageContext();        
    // pop the context
    UIGraphicsEndImageContext();
    if(newThumbnail == nil) 
        NSLog(@"could not scale image");
    return newThumbnail;
}

@end
devios1
  • 36,899
  • 45
  • 162
  • 260
PapaSmurf
  • 2,345
  • 1
  • 20
  • 10
  • 4
    With Retina displays, use `UIGraphicsBeginImageContextWithOptions()` to avoid blurry resizing. :) – toblerpwn Oct 08 '12 at 18:25
  • 1
    @toblerpwn's note is important so I edited the answer to reflect this. It will now work correctly regardless of screen scale. – devios1 Aug 16 '13 at 21:57
  • @chaiguy how come I get a no visible interface for '' declares the selector 'drawInRect"'? please help – 4GetFullOf Apr 10 '14 at 14:53
  • @Mediyum Make sure you are declaring the category on the `UIImage` class, which defines `drawInRect`. – devios1 Apr 10 '14 at 20:21
12

I cache a thumbnail version since using large images scaled down on the fly uses too much memory.

Here's my thumbnail code:

- (UIImage *)thumbnailOfSize:(CGSize)size {
    if( self.previewThumbnail )
        return self.previewThumbnail; // returned cached thumbnail

    UIGraphicsBeginImageContext(size);

    // draw scaled image into thumbnail context
    [self.preview drawInRect:CGRectMake(0, 0, size.width, size.height)];

    UIImage *newThumbnail = UIGraphicsGetImageFromCurrentImageContext();    

    // pop the context
    UIGraphicsEndImageContext();

    if(newThumbnail == nil) 
        NSLog(@"could not scale image");

    self.previewThumbnail = newThumbnail;

    return self.previewThumbnail;
}

Just make sure you properly clear the cached thumbnail if you change your original image (self.preview in my case).

Ben Lachman
  • 3,083
  • 1
  • 28
  • 44
  • Where do I put this? Also, is self.previewThumbnail a UIImage? Finally, what is self.preview? An image, a view? – zardon Mar 24 '11 at 12:19
  • This is awesome, but wouldn't a custom cell with layout set accordingly be more efficient? – spstanley Apr 04 '11 at 21:09
  • I'm not sure how this relates? You can most definitely use this code in a custom cell. It just creates a thumbnail out of a larger image. – Ben Lachman Apr 23 '11 at 23:28
  • @zardon This is a method in one of my model classes (which has a "preview" UIImage). You'll have to edit this a bit to add it to your own model class or at least add a member property called previewThumbnail for it to use for caching. – Ben Lachman Apr 23 '11 at 23:30
4

I have mine wrapped in a UIView and use this code:

imageView.contentMode = UIViewContentModeScaleAspectFit;
imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth |UIViewAutoresizingFlexibleHeight;
[self addSubview:imageView];
imageView.frame = self.bounds;

(self is the wrapper UIView, with the dimensions I want - I use AsyncImageView).

P.J.Radadiya
  • 1,493
  • 1
  • 12
  • 21
alex_c
  • 2,058
  • 2
  • 26
  • 34
2

I thought Ben Lachman's suggestion of generating thumbnails in advance rather than on the fly was smart, so I adapted his code so it could handle a whole array and to make it more portable (no hard-coded property names).

- (NSArray *)arrayOfThumbnailsOfSize:(CGSize)size fromArray:(NSArray*)original {
    NSMutableArray *temp = [NSMutableArray arrayWithCapacity:[original count]];
    for(UIImage *image in original){
        UIGraphicsBeginImageContext(size);
        [image drawInRect:CGRectMake(0,0,size.width,size.height)];
        UIImage *thumb = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        [temp addObject:thumb];
    }
    return [NSArray arrayWithArray:temp];
}
guiller
  • 1
  • 1
-1

you might be able to use this?

yourTableViewController.rowImage = [UIImage imageNamed:@"yourImage.png"];

and/or

cell.image = yourTableViewController.rowImage;

and if your images are already 40x40 then you shouldn't have to worry about setting bounds and stuff... but, i'm also new to this, so, i wouldn't know, haven't played around with Table View row/cell images much

hope this helps.

Wolfcow
  • 2,745
  • 1
  • 17
  • 10
-1

I was able to make this work using interface builder and a tableviewcell. You can set the "Mode" properties for an image view to "Aspect Fit". I'm not sure how to do this programatically.

Jonah
  • 4,810
  • 14
  • 63
  • 76
  • This is how you would do it programmatically: yourTableViewCell.imageView.contentMode = UIViewContentModeScaleAspectFit; – Jonah Apr 16 '10 at 03:04
  • that works, certainly, but using IB is a lot of overhead just to change the size of an image – greenisus Feb 17 '11 at 17:00
-1

Try setting UIImageView.autoresizesSubviews and/or UIImageView.contentStretch.

Cesare
  • 9,139
  • 16
  • 78
  • 130