iOS 7中的图像解压缩

前端之家收集整理的这篇文章主要介绍了iOS 7中的图像解压缩前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
图像解压缩的问题已经在Stack Overflow中进行了大量的讨论,但是直到这个问题,有0个提到kCG ImageSourceShouldCacheImmediately,这是iOS 7中引入的一个选项,理论上讲这个问题是在处理这个问题的.从标题

Specifies whether image decoding and caching should happen at image creation time.

Objc.io #7彼得·斯坦伯格(Peter Steinberger)建议这样做:

+ (UIImage *)decompressedImageWithData:(NSData *)data 
{
    CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data,NULL);
    CGImageRef cgImage = CGImageSourceCreateImageAtIndex(source,(__bridge CFDictionaryRef)@{(id)kCGImageSourceShouldCacheImmediately: @YES});

    UIImage *image = [UIImage imageWithCGImage:cgImage];
    CGImageRelease(cgImage);
    CFRelease(source);
    return image;
}

像AFNetworking和SDWebImage这样的库仍然使用CGContextDrawImage方法进行图像解压缩.从SDWebImage

+ (UIImage *)decodedImageWithImage:(UIImage *)image {
    if (image.images) {
        // Do not decode animated images
        return image;
    }

    CGImageRef imageRef = image.CGImage;
    CGSize imageSize = CGSizeMake(CGImageGetWidth(imageRef),CGImageGetHeight(imageRef));
    CGRect imageRect = (CGRect){.origin = CGPointZero,.size = imageSize};

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);

    int infoMask = (bitmapInfo & kCGBitmapAlphaInfoMask);
    BOOL anyNonAlpha = (infoMask == kCGImageAlphaNone ||
            infoMask == kCGImageAlphaNoneSkipFirst ||
            infoMask == kCGImageAlphaNoneSkipLast);

    // CGBitmapContextCreate doesn't support kCGImageAlphaNone with RGB.
    // https://developer.apple.com/library/mac/#qa/qa1037/_index.html
    if (infoMask == kCGImageAlphaNone && CGColorSpaceGetNumberOfComponents(colorSpace) > 1) {
        // Unset the old alpha info.
        bitmapInfo &= ~kCGBitmapAlphaInfoMask;

        // Set noneSkipFirst.
        bitmapInfo |= kCGImageAlphaNoneSkipFirst;
    }
            // Some PNGs tell us they have alpha but only 3 components. Odd.
    else if (!anyNonAlpha && CGColorSpaceGetNumberOfComponents(colorSpace) == 3) {
        // Unset the old alpha info.
        bitmapInfo &= ~kCGBitmapAlphaInfoMask;
        bitmapInfo |= kCGImageAlphaPremultipliedFirst;
    }

    // It calculates the bytes-per-row based on the bitsPerComponent and width arguments.
    CGContextRef context = CGBitmapContextCreate(NULL,imageSize.width,imageSize.height,CGImageGetBitsPerComponent(imageRef),colorSpace,bitmapInfo);
    CGColorSpaceRelease(colorSpace);

    // If Failed,return undecompressed image
    if (!context) return image;

    CGContextDrawImage(context,imageRect,imageRef);
    CGImageRef decompressedImageRef = CGBitmapContextCreateImage(context);

    CGContextRelease(context);

    UIImage *decompressedImage = [UIImage imageWithCGImage:decompressedImageRef scale:image.scale orientation:image.imageOrientation];
    CGImageRelease(decompressedImageRef);
    return decompressedImage;
}

我的问题是我们应该在iOS 7中移动到kCGImageSourceShouldCacheImmediately方法吗?

解决方法

据我所知,实施有一些问题.

>这种“新方法”需要在主线程上进行某种渲染.您可以加载图像并设置应该缓存立即标志,但这将在主线程中设置一些操作进行处理.当您加载滚动视图和集合视图时,这将导致口吃.对于我来说,它比在后台派遣队列更旧的方式.
>如果您使用自己的内存缓冲区而不是文件,则需要创建复制数据的数据提供者,因为数据提供者希望内存缓冲区能够挂起.这听起来很明显,但是这个功能中的标志让你相信你可以这样做:

>从一些来源的压缩JPEG数据填充你自己的缓冲区
>创建一个数据提供者并附加JPEG数据
使用CACHE立即设置数据提供者创建图像源
>使用图像源创建一个CG图像
把所有的中间对象拖出去,把你很好地解压缩的CGImage对象直接放到一个可以滚动的UIImage对象上

它不会这样做,因为它会等待主线程进行解压缩.它认为一切都OK,因为它引用了您发布的所有这些中间对象.您发布了所有这些对象,认为它会立即解压缩,就像旗帜所说的那样.如果你也抛出了这个内存缓冲区,并且内存缓冲区是以非复制的方式传递的,那么你将会遇到垃圾.或者,如果内存缓冲区在我的情况下被重用,加载另一个图像,你也会得到垃圾.

你实际上没有办法知道这个图像何时会被解压缩并准备使用.

TL; DR =“考虑到kCGImageSourceShouldCacheImmediately意味着当方便到操作系统”

当你这样做的“老路”时,你们100%知道会有什么可以和什么时候.因为它不是延迟,你可以避免一些复制.我不认为这个API正在做任何神奇的事情,我认为这只是拿着内存缓冲区,然后在“引擎盖”下做“老方法”.

所以基本上没有免费的午餐.看着堆栈跟踪,从这个事情崩溃的时候,当我想到它被全部注销后,我重新使用我的内存缓冲区,我看到它呼叫到CA :: Transaction,CA :: Layer,CA :: Render和进入ImageProviderCopy …一直到JPEGParseJPEGInfo(它崩溃访问我的缓冲区).

这意味着kCGImageSourceShouldCacheImmediately除了设置一个标志之外什么都不做,以便在创建它之后尽可能快地告诉图像在主线程中解压缩,而不是实际上完全按照你的想法意思(正在阅读).如果将图像提交到滚动视图进行显示,并且图像进行绘制,它将完成相同的操作.如果你幸运的话,滚动之间会有一些空闲的循环,这样会改善一些事情,但是基本上我觉得这样做比希望更多.

原文链接:https://www.f2er.com/iOS/329532.html

猜你在找的iOS相关文章