更快地裁剪图像

时间:2013-05-05 21:10:37

标签: ios core-graphics avfoundation

我正在尝试在iOS中裁剪一段时间。我的代码运行良好,但速度不够快。当我提供大约20-25张图像时,需要7-10秒来处理它。我已经尝试了一切可能的方法来解决这个问题,但没有成功。我不确定我错过了什么。

- (UIImage *)squareImageWithImage:(UIImage *)image scaledToSize:(CGSize)targetSize {

    UIImage *sourceImage = image;
    UIImage *newImage = nil;
    CGSize imageSize = sourceImage.size;
    CGFloat width = imageSize.width;
    CGFloat height = imageSize.height;
    CGFloat targetWidth = targetSize.width;
    CGFloat targetHeight = targetSize.height;
    CGFloat scaleFactor = 0.0;
    CGFloat scaledWidth = targetWidth;
    CGFloat scaledHeight = targetHeight;
    CGPoint thumbnailPoint = CGPointMake(0.0,0.0);

    if (CGSizeEqualToSize(imageSize, targetSize) == NO)
    {
        CGFloat widthFactor = targetWidth / width;
        CGFloat heightFactor = targetHeight / height;

        if (widthFactor > heightFactor)
        {
            scaleFactor = widthFactor; // scale to fit height
        }
        else
        {
            scaleFactor = heightFactor; // scale to fit width
        }

        scaledWidth  = width * scaleFactor;
        scaledHeight = height * scaleFactor;

        // center the image
        if (widthFactor > heightFactor)
        {
            thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
        }
        else
        {
            if (widthFactor < heightFactor)
            {
                thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
            }
        }
    }

    UIGraphicsBeginImageContext(targetSize); // this will crop

    CGRect thumbnailRect = CGRectZero;
    thumbnailRect.origin = thumbnailPoint;
    thumbnailRect.size.width  = scaledWidth;
    thumbnailRect.size.height = scaledHeight;

    [sourceImage drawInRect:thumbnailRect];

    newImage = UIGraphicsGetImageFromCurrentImageContext();

    if(newImage == nil)
    {
        NSLog(@"could not scale image");
    }

    //pop the context to get back to the default
    UIGraphicsEndImageContext();

    return newImage;
}

2 个答案:

答案 0 :(得分:4)

您的原始问题没有正确说明问题,因此它现在确实如此:这些操作花费这么长时间的原因是缩放图像所需的CPU周期数(不是裁剪它,这更简单,更快)。缩放时,系统需要使用围绕区域的一些像素的混合,这会消耗大量的cpu周期。你可以通过结合使用技术来加快速度,但没有一个答案。

1)使用块并在并发调度队列上调度这些映像操作,以获得并行性。我相信最新的iPad有4个内核,你可以这样使用。 [UIGraphicsBeginImageContext是线程安全的]。

2)获取ContextRef指针,并将插值设置设置为最低设置:

UIGraphicsBeginImageContext(targetSize);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetInterpolationQuality(context, kCGInterpolationLow);
...
3)作弊 - 除了两个权力之外不要扩展。在这种技术中,您将确定两个“最佳”力量来缩小图像,扩展宽度和高度以适合您的目标大小。如果你可以使用2的幂,你可以使用UIImage中的CGImageRef,获取像素指针,并复制每隔一个像素/每隔一行,并快速创建一个较小的图像(使用CGImageCreate)。让系统缩放图像可能不会达到高质量,但速度会更快。这显然是相当多的代码,但你可以通过这种方式快速完成操作。

4)重新定义你的任务。不要尝试调整一组图像的大小,而是更改应用程序,以便一次只显示一个或两个已调整大小的图像,并在用户查看它们时,在后台队列上执行其他图像操作。这是为了完整,我假设你已经想到了这一点。

PS:如果这适合你,不需要赏金,而是帮助别人。

答案 1 :(得分:1)

使用drawInRect的速度很慢。您可以尝试更快CGImageCreateWithImageInRect(至少比drawInRect快10倍)。

CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], theRect); // e.g. theRect={{100,100, {200, 200}}

UIImage *finalImage = [UIImage imageWithCGImage:imageRef];