我决定添加完整的代码来节省内存,如果您使用的是 GIF 文件,请修改 UIImage 缩放方法(在这里找到它,一个 Stackoverflow)。正如 SD Image 中的GangstaGraham所说,存在方法 sd_animatedImageByScalingAndCroppingToSize
@interface UIImage (Scaling)
-(UIImage *)imageByScalingProportionallyToSize:(CGSize)targetSize;
-(UIImage*) croppedImageWithRect: (CGRect) rect;
@end
@implementation UIImage (Scaling)
- (UIImage *)imageByScalingProportionallyToSize:(CGSize)targetSize {
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
if ([[UIScreen mainScreen] scale] == 2.0) {
targetSize.height *= 2.0f;
targetSize.width *= 2.0f;
}
}
NSUInteger width = targetSize.width;
NSUInteger height = targetSize.height;
UIImage *newImage = [self resizedImageWithMinimumSize: CGSizeMake (width, height)];
return [newImage croppedImageWithRect: CGRectMake ((newImage.size.width - width) / 2, (newImage.size.height - height) / 2, width, height)];
}
-(CGImageRef)CGImageWithCorrectOrientation
{
if (self.imageOrientation == UIImageOrientationDown) {
//retaining because caller expects to own the reference
CGImageRetain([self CGImage]);
return [self CGImage];
}
UIGraphicsBeginImageContext(self.size);
CGContextRef context = UIGraphicsGetCurrentContext();
if (self.imageOrientation == UIImageOrientationRight) {
CGContextRotateCTM (context, 90 * M_PI/180);
} else if (self.imageOrientation == UIImageOrientationLeft) {
CGContextRotateCTM (context, -90 * M_PI/180);
} else if (self.imageOrientation == UIImageOrientationUp) {
CGContextRotateCTM (context, 180 * M_PI/180);
}
[self drawAtPoint:CGPointMake(0, 0)];
CGImageRef cgImage = CGBitmapContextCreateImage(context);
UIGraphicsEndImageContext();
return cgImage;
}
-(UIImage*)resizedImageWithMinimumSize:(CGSize)size
{
CGImageRef imgRef = [self CGImageWithCorrectOrientation];
CGFloat original_width = CGImageGetWidth(imgRef);
CGFloat original_height = CGImageGetHeight(imgRef);
CGFloat width_ratio = size.width / original_width;
CGFloat height_ratio = size.height / original_height;
CGFloat scale_ratio = width_ratio > height_ratio ? width_ratio : height_ratio;
CGImageRelease(imgRef);
return [self drawImageInBounds: CGRectMake(0, 0, round(original_width * scale_ratio), round(original_height * scale_ratio))];
}
-(UIImage*)drawImageInBounds:(CGRect)bounds
{
UIGraphicsBeginImageContext(bounds.size);
[self drawInRect: bounds];
UIImage *resizedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return resizedImage;
}
-(UIImage*)croppedImageWithRect:(CGRect)rect
{
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect drawRect = CGRectMake(-rect.origin.x, -rect.origin.y, self.size.width, self.size.height);
CGContextClipToRect(context, CGRectMake(0, 0, rect.size.width, rect.size.height));
[self drawInRect:drawRect];
UIImage* subImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return subImage;
}
-(UIImage *) resizableImageWithCapInsets2: (UIEdgeInsets) inset
{
if ([self respondsToSelector:@selector(resizableImageWithCapInsets:resizingMode:)])
{
return [self resizableImageWithCapInsets:inset resizingMode:UIImageResizingModeStretch];
}
else
{
float left = (self.size.width-2)/2;//The middle points rarely vary anyway
float top = (self.size.height-2)/2;
return [self stretchableImageWithLeftCapWidth:left topCapHeight:top];
}
}
@end
和 UIImageView:
#import <SDWebImage/SDImageCache.h>
@implementation UIImageView (Scaling)
-(void)setImageWithURL:(NSURL*)url scaleToSize:(BOOL)scale
{
if(url.absoluteString.length < 10) return;
if(!scale){
[self setImageWithURL:url];
return;
}
__block UIImageView* selfimg = self;
__block NSString* prevKey = SPRINTF(@"%@_%ix%i", url.absoluteString, (int)self.frame.size.width, (int)self.frame.size.height);
__block UIImage* prevImage = nil;
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^ {
prevImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:prevKey];
if(prevImage){
dispatch_async(dispatch_get_main_queue(), ^ {
[self setImage:prevImage];
});
}else{
[[SDWebImageDownloader sharedDownloader] downloadImageWithURL:url options:SDWebImageDownloaderFILOQueueMode progress:nil completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) {
if(error){
[selfimg setImageWithURL:url scaleToSize:scale];
}else{
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^ {
prevImage = [image imageByScalingProportionallyToSize:self.frame.size];
if(finished)
[[SDImageCache sharedImageCache] storeImage:prevImage forKey:prevKey];
dispatch_async(dispatch_get_main_queue(), ^ {
[self setImage:prevImage];
});
});
}
}];
}
});
return;
}
-(void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder scaleToSize:(BOOL)scale
{
[self setImage:placeholder];
[self setImageWithURL:url scaleToSize:scale];
}
@end