0

我现在正在尝试在 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;
}
4

2 回答 2

4

您最初的问题没有正确说明问题,所以它现在这样做了:这些操作需要这么长时间的原因是缩放图像所需的 CPU 周期数(而不是裁剪它,这更简单、更快)。缩放时,系统需要对一个区域周围的一些像素进行混合,这会消耗大量的 CPU 周期。您可以通过使用多种技术组合来加快速度,但没有单一的答案。

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

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

UIGraphicsBeginImageContext(targetSize);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetInterpolationQuality(context, kCGInterpolationLow);
...

3) 作弊 - 除非通过 2 的幂,否则不要缩放。在这种技术中,您将确定缩小图像的“最佳”乘方,扩大宽度和高度以适合您的目标尺寸。如果可以使用 2 的幂,则可以使用 UIImage 中的 CGImageRef,获取像素指针,然后每隔一个像素/每隔一行复制一次,然后非常快速地创建一个较小的图像(使用 CGImageCreate)。它可能没有让系统缩放图像的质量那么高,但它会更快。这显然是相当多的代码,但是您可以通过这种方式使操作变得非常快。

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

PS:如果这对你有用,不需要赏金,而是帮助别人。

于 2013-05-06T13:31:44.530 回答
1

使用drawInRect缓慢。您可以尝试CGImageCreateWithImageInRect哪个更快(至少比 快 10 倍drawInRect)。

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

UIImage *finalImage = [UIImage imageWithCGImage:imageRef];
于 2013-11-10T13:52:18.733 回答