UIImage的减压导致滚动滞后

我有此应用,显示了一堆微小的图像的全屏幕的tableView。 这些图像是从网上拉,在后台线程处理,然后保存到使用类似盘:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ UIGraphicsBeginImageContextWithOptions(rect.size, YES, 0); // code that adds some glosses, shadows, etc UIImage *output = UIGraphicsGetImageFromCurrentImageContext(); NSData* cacheData = UIImagePNGRepresentation(output); [cacheData writeToFile:thumbPath atomically:YES]; dispatch_async(dispatch_get_main_queue(), ^{ self.image = output; // refreshes the cell using KVO }); });

此代码仅执行第一次被显示在细胞(因为后该图像是已经在磁盘上)。 在这种情况下,细胞是使用加载:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ UIImage *savedImage = [UIImage imageWithContentsOfFile:thumbPath]; if(savedImage) { dispatch_async(dispatch_get_main_queue(), ^{ self.image = savedImage; // refreshes the cell using KVO }); } });

我的问题是,在第一种情况下,滚动黄油光滑。 但是在第二种情况(它是直接从磁盘读取图像),滚动超生涩,甚至一度加载图像。 绘画是什么造成的滞后。 使用仪器,我看到copyImageBlockSetPNGpng_read_nowinflate占用了大部分的CPU(他们不分配时self.imageUIGraphicsGetImageFromCurrentImageContext()

我假定这是因为在第一种情况下的UIImage是图中的原始输出,而在第二种情况下,它具有每它绘制它的时间来解压缩,PNG。 我试着用JPG格式,而不是PNG格式,我也得到了类似的结果。

有没有办法解决这一问题? 也许有它仅解压缩PNG在第一时间被它吸引?

--------------解决方案-------------

您的问题是+imageWithContentsOfFile:是缓存和延迟加载。 如果你想要做这样的事情,而不是使用此代码对你的背景队列:

// Assuming ARC
NSData* imageFileData = [[NSData alloc] initWithContentsOfFile:thumbPath];
UIImage* savedImage = [[UIImage alloc] initWithData:imageFileData];

// Dispatch back to main queue and set image...

现在,有了这个代码,图像数据的实际减压仍然会偷懒,花费了一点点,但几乎没有一样多文件访问打你与你的代码示例中的延迟加载获得。

因为你看到的仍然是一个性能问题,您还可以强制的UIImage解压缩在后台线程上的图像:

// Still on background, before dispatching to main
UIGraphicsBeginImageContext(CGSizeMake(100, 100)); // this isn't that important since you just want UIImage to decompress the image data before switching back to main thread
[savedImage drawAtPoint:CGPointZero];
UIGraphicsEndImageContext();

// dispatch back to main thread...

Jason的有关图纸预图像进行解压是关键,但你会通过复制整个图像并丢弃原来获得更好的性能技巧。

在运行iOS上创建的图像似乎绘制比已经从文件加载的人,你强迫他们甚至解压缩后得到更好的优化。 出于这个原因,你应该加载这样的(这也是一个好主意,把解压缩图像到NSCache,所以你不必重装保持它):

- (void)loadImageWithPath:(NSString *)path block:(void(^)(UIImage *image))block
{
static NSCache *cache = nil;
if (!cache)
{
cache = [[NSCache alloc] init];
}

//check cache first
UIImage *image = [cache objectForKey:path];
if (image)
{
block(image);
return;
}

//switch to background thread
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{

//load image
UIImage *image = [UIImage imageWithContentsOfFile:path];

//redraw image using device context
UIGraphicsBeginImageContextWithOptions(image.size, YES, 0);
[image drawAtPoint:CGPointZero];
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

//back to main thread
dispatch_async(dispatch_get_main_queue(), ^{

//cache the image
[cache setObject:image forKey:path];

//return the image
block(image);
});
});
}

另一种方法图像解压缩:

NS_INLINE void forceImageDecompression(UIImage *image)
{
CGImageRef imageRef = [image CGImage];
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(NULL, CGImageGetWidth(imageRef), CGImageGetHeight(imageRef), 8, CGImageGetWidth(imageRef) * 4, colorSpace,kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little);
CGColorSpaceRelease(colorSpace);
if (!context) { NSLog(@"Could not create context for image decompression"); return; }
CGContextDrawImage(context, (CGRect){{0.0f, 0.0f}, {CGImageGetWidth(imageRef), CGImageGetHeight(imageRef)}}, imageRef);
CFRelease(context);
}

使用:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
UIImage *image = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%u.jpg", pageIndex]];
forceImageDecompression(image);

dispatch_async(dispatch_get_main_queue(), ^{
[((UIImageView*)page)setImage:image];
});
}

分类:iphone 时间:2012-01-01 人气:0
本文关键词: iphone,IOS,核心显卡
分享到:

相关文章

  • 适用于iOS核心显卡例子 2013-05-21

    没有人知道任何教程和示例使用核心显卡除了核心视频编程指南? --------------解决方案------------- 你可以看看到CocoaIsMyGirlfriend岗位: http://www.cimgf.com/2008/09/10/core-animation-tutorial-rendering-quicktime-movies-in-a-caopengllayer/ 如果在中级/高级方式使用corevideo的,这将是很酷张贴的教程;)

  • 是不是有什么特别的,我必须知道核心显卡绘制图像时? 2012-08-03

    在视网膜显示屏来的iOS,我已经开发了一些控制其使用的是可拉伸的图像和大量的核心图形代码绘制. 现在,我测试了视网膜显示设备上,并且图形被放错位置和歪曲. 是的满载@ 2个后缀,UIImage的imageNamed工作正常,所有其他的事情. 我认为在核心显卡使用图像时,必须有一些特殊的考虑. 例如,我得到CGImage来自UIImage的非常频繁. 有谁知道? --------------解决方案------------- UIImage是上的外观CGImage和IOSurface为私有API)

  • 在iPhone的核心数据使用多个表retrive数据 2012-02-25

    其实我有三个表作为empName(EMPID,empName),empSalary(EMPID,工资),empBonus(工资,奖金). 我有一个名称,需要找到的奖金. 所以我的逻辑是,先找到使用的名字,我会发现EMPID然后使用EMPID找到薪水和最后用工资找到empBonus表中的奖金. 我怎样才能实现按照iPhone在核心数据的事情. --------------解决方案------------- 使用数据之间的关系,所以,只要你找到名字,它也发现从其它表中的工资和奖金. 看这里 我不会做

  • IOS核心定位框架did'nt制定出的iOS 4.2模拟器 2012-04-29

    IOS核心定位框架did'nt制定出的iOS 4.2 simulator.Anybody知道issues.Any一个用于获取当前位置有iOS 4.2的工作代码. 谢谢,VKS --------------解决方案------------- 模拟器总是给你库比蒂诺默认固定的位置......对于核心位置的应用程序进行彻底的测试模拟器中可以使用以下库:https://github.com/futuretap/FTLocationSimulator 你无法在模拟器测试CoreLocation框架. ü与

  • 如何发出从JavaScript通知/警报时,应用程序在后台 - PhoneGap的iPhone / iOS版 2012-12-14

    我想发出一个通知/警报的用户 - 基于从秒表发出一个定时事件. 其中的逻辑是在JavaScript中,应用程序在运行的PhoneGap iPhone上. 问题:iPhone暂停执行JavaScript在iPhone / iOS的web视图当应用程序在后台运行. 触发本地警告​​对话框,例如使用的PhoneGap的navigator.notification.alert()失败,因为该警报是根本就没有,而在后台调用. 我怎样才能有效地,例如,UILocalNotification结合呢? - 任何

  • 如何实现放大和缩小功能与iPhone的核心情节线图? 2013-03-25

    是否有可能实现放大和缩小功能与iPhone的核心情节图表组件? 如果是的话,请建议我该怎么办呢? 提前致谢. --------------解决方案------------- 是的,我做的方式是通过调整像这样的PlotSpace(可能不是最好的解决办法,但最好的我能想出): -(void)zoomOut { CPXYPlotSpace *plotSpace = (CPXYPlotSpace *)graph.defaultPlotSpace; graphScaleX+=5; graphScaleY+

  • 中断来电/短信对iPhone iOS 5 2013-04-20

    我们可以中断对iPhone IOS 5来电/短信? 任何代码样本? 我找了一个应用程序的一些代码示例当呼叫来电/去电从手机/,并获取主叫号码,获取通知. 对于短信同样的事情. 我知道这似乎是间谍,但是这在最后的目的是远路的那. --------------解决方案------------- 我要这个从非越狱的位置(因为你没有在你的问题中指定它). 我们可以中断对iPhone IOS 5来电/短信? 号绝对不是. 在此过程中,你需要三样东西: 一个监听来电/短信的 事件时调用一个电话或短信传入.

  • iPhone / IOS SDK:如何删除/清除用户的文件,如果应用程序更新 2013-04-22

    我的iPhone / iOS的应用程序具有密码保护设置页面. 当用户创建一个密码,我在图书馆/缓存目录中的文件保存密码. 我的问题是:如果用户忘记了密码,他/她有权删除应用程序,并重新安装它,密码文件将被删除. 刚刚更新的应用程序不会删除密码文件. 我想删除/清除此文件时,应用程序更新? 我该怎么办呢? 谢谢 --------------解决方案------------- 你想实现什么目标是有点混乱,却忽略了:每一个应用程序运行时,当它启动时,读一个特殊的文件的内容. 如果该文件不存在,或者如果

  • 分析服务/可为iPhone / iOS平台库? 2014-08-22

    什么分析库/服务是否有适用于iPhone / iOS平台,以收集有关我的应用程序使用数据? 至少以下服务是可用的: 乱舞Analytics(分析) Localytics Medialets 最好的图书馆应报告为多,因为它可以自动完成,但也要允许应用程序作者定义的跟踪事件. 另外,最好它应该包括某种服务(可能是基于Web)中提出的分析数据. --------------解决方案------------- 我在我的应用程序使用乱舞和它的作品相当不错的. 有很多关于应用程序的使用信息的,它是由库自动上

  • 从iPhone / IOS令牌传递到网站 2014-09-28

    我想创造和传承的iPhone / ios的一个认证/身份令牌并发送令牌到网站. 该网站可以利用这个令牌,使用此令牌验证用户/登录. 我不知道如何做到这一点在iOS上,我希望有人能帮助我在此. 有任何想法吗 ? --------------解决方案------------- 我在过去的方法是使用ASIHTTPRequest库发送请求到服务器的登录信息. 这个问题解决了ASIHTTPRequest各种安全问题.

Copyright (C) 55228885.com, All Rights Reserved.

55228885 版权所有 京ICP备15002868号

processed in 0.176 (s). 10 q(s)