关于使用UIKit、CoreGraphics、ImageIO这3
2018-06-30 本文已影响112人
健了个平_24
献上Demo链接
首先感谢这位博主的分享:iOS的5种图片缩略技术以及性能探讨
从这篇博客中了解到5种图片缩略技术以及性能,其中在性能上UIKit、CoreGraphics、ImageIO这3种方式是最常用的,所以另外两种就不作探讨了。
可是这里有一个问题:文章中没有针对不同的[UIScreen mainScreen].scale做相应的缩略处理,图片的清晰度也因此不一样,所以我尝试在博主方法的基础上添加scale处理(由于该博客中用的是swift,而我的项目用得比较多的是oc,所以我这里是对博主的方法“翻译”后再进行修改):
UIKit
- (UIImage *)jp_uiResizeImageWithSize:(CGSize)size scale:(CGFloat)scale {
@autoreleasepool {
if (scale <= 0) scale = [UIScreen mainScreen].scale;
UIGraphicsBeginImageContextWithOptions(size, NO, scale);
[self drawInRect:CGRectMake(0, 0, size.width, size.height)];
UIImage *resizedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return resizedImage;
}
}
- PS:这里使用的是UIGraphicsBeginImageContextWithOptions,因为可以使用scale,如果使用的是UIGraphicsBeginImageContext,其实就是相当于使用了UIGraphicsBeginImageContextWithOptions(size, NO, 1.0)。
CoreGraphics
- (UIImage *)jp_cgResizeImageWithSize:(CGSize)size scale:(CGFloat)scale {
CGImageRef cgImage = self.CGImage;
if (!cgImage) return nil;
if (scale <= 0) scale = [UIScreen mainScreen].scale;
size.width *= scale;
size.height *= scale;
size_t bitsPerComponent = CGImageGetBitsPerComponent(cgImage);
size_t bytesPerRow = CGImageGetBytesPerRow(cgImage);
CGColorSpaceRef colorSpace = CGImageGetColorSpace(cgImage);
CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(cgImage);
CGContextRef context = CGBitmapContextCreate(nil, (size_t)size.width, (size_t)size.height, bitsPerComponent, bytesPerRow, colorSpace, bitmapInfo);
CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
CGContextDrawImage(context, CGRectMake(0, 0, size.width, size.height), cgImage);
CGImageRef resizedCGImage = CGBitmapContextCreateImage(context);
UIImage *resizedImage = [UIImage imageWithCGImage:resizedCGImage scale:scale orientation:self.imageOrientation];
CGContextRelease(context);
CGImageRelease(resizedCGImage);
return resizedImage;
}
- PS:使用CoreGraphics的方法时,记得最后要Release。
ImageIO
- (UIImage *)jp_ioResizeImageWithSize:(CGSize)size scale:(CGFloat)scale {
NSData *data = UIImagePNGRepresentation(self);
if (!data) return nil;
if (scale <= 0) scale = [UIScreen mainScreen].scale;
CGFloat maxPixelSize = MAX(size.width, size.height) * scale;
CGImageSourceRef imageSource = CGImageSourceCreateWithData((__bridge CFDataRef)data, nil);
NSDictionary *options = @{(id)kCGImageSourceCreateThumbnailWithTransform : @(YES),
(id)kCGImageSourceCreateThumbnailFromImageIfAbsent : @(YES),
(id)kCGImageSourceThumbnailMaxPixelSize : @(maxPixelSize)};
CGImageRef resizedCGImage = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, (CFDictionaryRef)options);
UIImage *resizedImage = [UIImage imageWithCGImage:resizedCGImage scale:scale orientation:self.imageOrientation];
CFRelease(imageSource);
CGImageRelease(resizedCGImage);
return resizedImage;
}
- PS:这里非常感谢另一位博主的文章:iOS 修改图片尺寸的方法,以及ImageContext内存占用的问题 ,该博主帮我解答了如何针对不同scale作相应处理,另外也说明了不使用kCGImageSourceCreateThumbnailFromImageAlways是因为会一直创建缩略图,有可能会造成内存浪费,所以使用kCGImageSourceCreateThumbnailFromImageIfAbsent。
缩略后的图片对比:
缩略后的图片对比经修改后,在不同的scale下,图片缩略后清晰度几乎一样了,不过可能有错误的地方,如果发现了请告诉我~
献上Demo链接