【问题标题】:How to render images without blocking UI?如何在不阻塞 UI 的情况下渲染图像?
【发布时间】:2012-09-15 09:06:33
【问题描述】:

我有这个图像渲染功能导致主/UI 线程在渲染时阻塞/卡顿。

在 iOS 中不阻塞线程并在不同线程上呈现的方法有哪些?有本地 API 可以帮助您吗?

更新代码:

+ (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {
    //UIGraphicsBeginImageContext(newSize);
    UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
    [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}

function
{
    UIImage *shrinkedImage = [ThisClass imageWithImage:screenShotImage scaledToSize:shrinkImageToSize];

    UIImage * rotatedImage = [[UIImage alloc] initWithCGImage: shrinkedImage.CGImage
                                                        scale: 1.0
                                                  orientation: UIImageOrientationRight];

}

谢谢

【问题讨论】:

  • 请发布您用于渲染图像的代码。
  • 更新了用于渲染的代码。
  • 为什么要调整大小?如果您只想在屏幕上显示它,请使用图像视图并将其设置为缩放,对其应用旋转变换,然后您就可以在几个语句中完成并具有合理的性能。
  • 怎么样?我的意思是比地雷更好的旋转变换?谢谢。
  • 我需要调整大小和转换,因为我得到的图像是横向模式。如果可以的话,给我看一些可以快速做到这一点的代码。也许我一直在努力。

标签: objective-c ios


【解决方案1】:

您可以考虑以下几点:

  1. 使用instruments tooltime profiler 检查大部分时间占用的时间。
  2. 使用UIImageView 而不是UIImage 来应用一些变换,例如旋转和变换。您需要将这些转换应用到 UIImageView 的 CALayer。
  3. 使用GCD 将图像的加载放在后台线程中。这是一个例子:
dispatch_queue_t preloadQueue = dispatch_queue_create("preload queue", nil);
dispatch_async(preloadQueue, ^{
                                UIImage *yourImage = [UIImage imageNamed:yourImageReferencePath];
                                 dispatch_async(dispatch_get_main_queue(), ^{   
                                                                          yourUIView.image = yourImage});
                                                                          });
dispatch_release(preloadQueue);

【讨论】:

    【解决方案2】:

    您是否尝试使用 GCD 在后台执行任务?

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^{
        // Do your computations in the global queue (background thread)
        UIImage *shrinkedImage = [ThisClass imageWithImage:screenShotImage scaledToSize:shrinkImageToSize];
        UIImage * rotatedImage = [[UIImage alloc] initWithCGImage: shrinkedImage.CGImage
                                                            scale: 1.0
                                                      orientation: UIImageOrientationRight];
        // Once done, always do all your display operations to update the UI on the main thread
        dispatch_sync(dispatch_get_main_queue(), ^{
            yourImageView.image = rotatedImage;
        });
    });
    

    如需了解更多信息,请阅读 Apple 的 Concurrency Programming Guide

    【讨论】:

      猜你喜欢
      • 2011-09-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-09
      • 2021-11-03
      • 1970-01-01
      • 2021-12-29
      • 2020-01-26
      • 1970-01-01
      相关资源
      最近更新 更多