美文网首页
关于使用UIKit、CoreGraphics、ImageIO这3

关于使用UIKit、CoreGraphics、ImageIO这3

作者: 健了个平_24 | 来源:发表于2018-06-30 20:46 被阅读112次

    献上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链接

    相关文章

      网友评论

          本文标题:关于使用UIKit、CoreGraphics、ImageIO这3

          本文链接:https://www.haomeiwen.com/subject/wdhxuftx.html