1

有一个很棒的 wiki 关于从相机选择器加载图像。这让我意识到以全分辨率拍摄图像的成本。

目前,当一张照片被选中时,我推送一个新的视图控制器并以全分辨率显示图像。推动视图是一种非常缓慢且不稳定的体验(大约 1 fps!),我想平滑它。与在 Instagram 上挑选照片相比,我注意到他们使用的是低分辨率图像,然后换成了完整图像。(我需要完整的 res 图像,因为用户应该能够缩放和平移)

我想要的想法是这样的:

- (void)imagePickerController:(UIImagePickerController *)picker
        didFinishPickingMediaWithInfo:(NSDictionary *)info 
{

    UIImage* fullImage = [info objectForKey:UIImagePickerControllerOriginalImage];

    // Push a view controller and give it the image.....
}

- (void) viewDidLoad {

    CGSize smallerImageSize = _imageView.bounds;
    UIImage* smallerImage = [MyHelper quickAndDirtyImageResize:_fullImage     
                                                        toSize:smallerImageSize];

    // Set the low res image for now... then later swap in the high res
    _imageView.image = smallerImage;

    // Swap in high res image async
    // This is the part im unsure about... Im sure UIKit isn't thread-safe!
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, NULL), ^{
        _imageView.image = _fullImage;
    });
}

我认为 UIImage 在使用之前不是内存映射的。因此,它不会减慢速度,直到将其提供给 imageView。它是否正确?

我认为图像解码已经由系统异步完成,但是,它仍然会在加载时大大减慢手机的速度。

有没有办法执行在非常低优先级的背景队列中显示图像所需的一些工作?

4

3 回答 3

5

您正在尝试以最复杂的方式做事:) 为什么不在推送视图控制器之前准备小图像并将其传递给他们?看看这段代码:

- (void)imagePickerController:(UIImagePickerController *)picker
        didFinishPickingMediaWithInfo:(NSDictionary *)info 
{

    UIImage *fullImage = [info objectForKey:UIImagePickerControllerOriginalImage];
    UIImage *smallImage = [fullImage imageScaledToSize:self.view.bounds];

    // Push a view controller and give it BOTH images
}

// And in your pushed view controller

- (void)viewDidLoad
{
    _imageView.image = self.smallImage;
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    _imageView.image = self.fullImage;
}

主要是viewDidAppear:在动画完成后立即调用它,因此您可以在此处切换图像而无需担心。

于 2012-10-06T11:23:57.713 回答
3

除了安德烈的回答,不要使用imageScaledToSize,使用CGImageSourceCreateThumbnailAtIndex。事实上,很可能(我很确定是这种情况)相册中使用的任何图像都已经有缩略图。因此,与其打扰图像本身,不如抓取现有的缩略图并显示它,然后使用 Andrey 的代码切换到主图像。这样你在动画期间做的工作尽可能少。

调用CGImageSourceCreateThumbnailAtIndex将返回缩略图图像,无论它已经存在还是需要生成。所以它使用起来非常安全,而且可能至少和imageScaledToSize.

您可以在 Apple 文档中找到完整的代码示例以使用它,无需在此处复制。

于 2012-10-10T07:25:20.800 回答
1

您是否尝试过使用 ALAssetsLibrary 加载该图像的缩略图,而不是尝试以全分辨率加载图像?它也比调整大小更快。

于 2012-10-12T11:58:20.853 回答