在后台线程中解码图像? [英] Decode images in background thread?

查看:20
本文介绍了在后台线程中解码图像?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个后台线程来加载图像并在主线程中显示它们.我注意到后台线程几乎无所事事,因为实际的图像解码似乎是在主线程中完成的:

I have a background thread that loads images and displays them in the main thread. I noticed that the background thread has almost nothing to do, because the actual image decoding seems to be done in the main thread:

到目前为止,我已经尝试在后台线程中调用 [UIImage imageNamed:][UIImage imageWithData:]CGImageCreateWithJPEGDataProvider 没有不同之处.有没有办法强制在后台线程上进行解码?

So far I’ve tried calling [UIImage imageNamed:], [UIImage imageWithData:] and CGImageCreateWithJPEGDataProvider in the background thread with no difference. Is there a way to force the decoding to be done on the background thread?

这里已经有一个类似的问题,但它没有帮助.正如我在那里写的那样,我尝试了以下技巧:

There’s already a similar question here, but it does not help. As I wrote there, I tried the following trick:

@implementation UIImage (Loading)

- (void) forceLoad
{
    const CGImageRef cgImage = [self CGImage];  

    const int width = CGImageGetWidth(cgImage);
    const int height = CGImageGetHeight(cgImage);

    const CGColorSpaceRef colorspace = CGImageGetColorSpace(cgImage);
    const CGContextRef context = CGBitmapContextCreate(
        NULL, /* Where to store the data. NULL = don’t care */
        width, height, /* width & height */
        8, width * 4, /* bits per component, bytes per row */
        colorspace, kCGImageAlphaNoneSkipFirst);

    NSParameterAssert(context);
    CGContextDrawImage(context, CGRectMake(0, 0, width, height), cgImage);
    CGContextRelease(context);
}

@end

这有效(强制图像解码),但它也会触发对 ImageIO_BGR_A_TO_RGB_A_8Bit 的明显昂贵的调用.

That works (forces the image to decode), but it also triggers an apparently expensive call to ImageIO_BGR_A_TO_RGB_A_8Bit.

推荐答案

我在新的 Retina iPad 上遇到了类似的高分辨率图像问题.大于屏幕尺寸(大致)的图像会导致 UI 响应能力出现重大问题.这些是 JPG,所以让它们在背景上解码似乎是正确的做法.我仍在努力收紧所有这些,但汤米的解决方案对我来说效果很好.我只是想贡献一些代码来帮助下一个人在他们试图确定他们的 UI 为什么会出现大图像时出现口吃.这就是我最终做的事情(这段代码在后台队列的 NSOperation 中运行).该示例是我的代码和上面代码的混合:

I ran into similar issues with hi-res images on the new retina iPad. Images larger than the screen size (roughly) would cause major problems with UI responsiveness. These were JPGs, so getting them to decode on the background seemed to be the right thing to do. I'm still working on tightening all of this up, but Tommy's solution worked great for me. I just wanted to contribute some code to help the next person along when they're trying to identify why their UI is stuttering with large images. Here's what I ended up doing (this code runs in an NSOperation on a background queue). The example is a blend of my code and the code above:

  CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData((CFDataRef)self.data);
  CGImageRef newImage = CGImageCreateWithJPEGDataProvider(dataProvider,
                                    NULL, NO, 
                                    kCGRenderingIntentDefault);


  //////////
  // force DECODE

  const int width = CGImageGetWidth(newImage);
  const int height = CGImageGetHeight(newImage);

  const CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
  const CGContextRef context = CGBitmapContextCreate(
                                                     NULL, /* Where to store the data. NULL = don’t care */
                                                     width, height, /* width & height */
                                                     8, width * 4, /* bits per component, bytes per row */
                                                     colorspace, kCGImageAlphaNoneSkipFirst);

  NSParameterAssert(context);
  CGContextDrawImage(context, CGRectMake(0, 0, width, height), newImage);
  CGImageRef drawnImage = CGBitmapContextCreateImage(context);
  CGContextRelease(context);
  CGColorSpaceRelease(colorspace);

  //////////

  self.downloadedImage = [UIImage imageWithCGImage:drawnImage];

  CGDataProviderRelease(dataProvider);
  CGImageRelease(newImage);
  CGImageRelease(drawnImage);

我仍在优化它.但到目前为止,它似乎做得很好.

I'm still optimizing this. But it seems to do pretty well so far.

这篇关于在后台线程中解码图像?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆