iOS 7中的图像解压缩

iOS 7中的图像解压缩,第1张

概述图像解压缩的问题已经在Stack Overflow中进行了大量的讨论,但是直到这个问题,有0个提到kCG ImageSourceShouldCacheImmediately,这是iOS 7中引入的一个选项,理论上讲这个问题是在处理这个问题的.从标题: Specifies whether image decoding and caching should happen at image creati 图像解压缩的问题已经在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方法吗?

解决方法@H_419_18@ 据我所知,实施有一些问题.

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

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

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

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

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

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

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

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

总结

以上是内存溢出为你收集整理的iOS 7中的图像解压缩全部内容,希望文章能够帮你解决iOS 7中的图像解压缩所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1096049.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-28
下一篇 2022-05-28

发表评论

登录后才能评论

评论列表(0条)

保存