博客> 关于使用UIKit、CoreGraphics、ImageIO这3种图片缩略技术如何针对[UIScreen mainScreen].scale作相应处理
关于使用UIKit、CoreGraphics、ImageIO这3种图片缩略技术如何针对[UIScreen mainScreen].scale作相应处理
2018-09-24 22:45 评论:0 阅读:92 ZjpLoser
ios

献上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:UIImageOrientationUp];

    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:UIImageOrientationUp];

    CFRelease(imageSource);
    CGImageRelease(resizedCGImage);

    return resizedImage;
}
  • PS:这里非常感谢另一位博主的文章:iOS 修改图片尺寸的方法,以及ImageContext内存占用的问题 ,该博主帮我解答了如何针对不同scale作相应处理,另外也说明了不使用kCGImageSourceCreateThumbnailFromImageAlways是因为会一直创建缩略图,有可能会造成内存浪费,所以使用kCGImageSourceCreateThumbnailFromImageIfAbsent。
缩略后的图片对比:

缩略后的图片对比

经修改后,在不同的scale下,图片缩略后清晰度几乎一样了,不过可能有错误的地方,如果发现了请告诉我~ 献上Demo链接

收藏
0
sina weixin mail 回到顶部