如何将UIImage保存为iOS中的渐进式JPEG格式?

7
在iOS中,如果想将UIImage保存为JPEG格式,可以使用UIImageJPEGRepresentation函数,但该函数除了压缩比率之外没有其他选项。我希望能将UIImage保存为逐渐显示的JPEG格式,是否有简单的方法可以实现呢?
看起来,在OS X中,有一个NSImageProgressive选项可以将NSImage保存为逐渐显示的格式。

你尝试过使用 UIImageJPEGRepresentation(<#UIImage *image#>, <#CGFloat compressionQuality#>) 吗? - hchouhan02
那并不是进步的表现。 - Robert Mao
2个回答

9
我认为您可以使用ImageIO框架来实现,像这样:

#import <UIKit/UIKit.h>
#import <ImageIO/ImageIO.h>
#import <MobileCoreServices/MobileCoreServices.h>
#import "AppDelegate.h"

int main(int argc, char *argv[])
{
    @autoreleasepool {
        UIImage *sourceImage = [UIImage imageNamed:@"test.jpg"];

        CFURLRef url = CFURLCreateWithString(NULL, CFSTR("file:///tmp/progressive.jpg"), NULL);
        CGImageDestinationRef destination = CGImageDestinationCreateWithURL(url, kUTTypeJPEG, 1, NULL);
        CFRelease(url);

        NSDictionary *jfifProperties = [NSDictionary dictionaryWithObjectsAndKeys:
            (__bridge id)kCFBooleanTrue, kCGImagePropertyJFIFIsProgressive,
            nil];

        NSDictionary *properties = [NSDictionary dictionaryWithObjectsAndKeys:
            [NSNumber numberWithFloat:.6], kCGImageDestinationLossyCompressionQuality,
            jfifProperties, kCGImagePropertyJFIFDictionary,
            nil];

        CGImageDestinationAddImage(destination, sourceImage.CGImage, (__bridge CFDictionaryRef)properties);
        CGImageDestinationFinalize(destination);
        CFRelease(destination);

        return 0;
    }
}

Preview.app显示输出文件为渐进式,ImageMagick的identify命令显示它具有“Interlace: JPEG”。


我在iOS设备上进行了测试,与模拟器不同。 - user501836
结果与https://dev59.com/qmgv5IYBdhLWcg3wI9Sg相同。 - user501836

0
这段代码在设备上是可以工作的 - 关键是要指定所有的密度值(请注意它使用了新的文字语法):
- (UIImage *)imager
{
    UIImage *object = [UIImage imageNamed:@"Untitled.jpg"];
    NSString *str = [[self applicationDocumentsDirectory] stringByAppendingPathComponent:@"Tester.jpg"];
    NSURL *url = [[NSURL alloc] initFileURLWithPath:str];

    CGImageDestinationRef destination = CGImageDestinationCreateWithURL((__bridge CFURLRef)url, kUTTypeJPEG, 1, NULL);

    NSDictionary *jfifProperties = [NSDictionary dictionaryWithObjectsAndKeys:
                                    @72, kCGImagePropertyJFIFXDensity,
                                    @72, kCGImagePropertyJFIFYDensity,
                                    @1, kCGImagePropertyJFIFDensityUnit,
                                    nil];

    NSDictionary *properties = [NSDictionary dictionaryWithObjectsAndKeys:
                                [NSNumber numberWithFloat:.5f], kCGImageDestinationLossyCompressionQuality,
                                jfifProperties, kCGImagePropertyJFIFDictionary,
                                nil];

    CGImageDestinationAddImage(destination, ((UIImage*)object).CGImage, (__bridge CFDictionaryRef)properties);
    CGImageDestinationFinalize(destination);
    CFRelease(destination);

    return [UIImage imageWithContentsOfFile:str];
}

1
(__bridge id)kCFBooleanTrue, kCGImagePropertyJFIFIsProgressive 不应该是 jfifProperties 的一部分吗?我不得不添加它才能将其保存为渐进式图像。 - qix
@Linus,当我回答这个问题时,要么是我错过了这个属性,要么就是根本没有这个属性。显然,这个答案对任何人都没有用,特别是原始的发布者,所以我会怀疑这里的内容(尽管当然我相信它是正确的,否则我就不会发帖了 :-)) - David H

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接