Ios 使用CGImage的JPEG压缩质量

Ios 使用CGImage的JPEG压缩质量,ios,image,macos,jpeg,cgimage,Ios,Image,Macos,Jpeg,Cgimage,我正在Mac OS X和iOS上使用CGImage API(CGImageDestination,CGBitmapContext,,CGImage等)将图像压缩为JPEG格式。使用KCGIMAGEDESTIONOSSYCOMPRESSIONQUALITY属性,您可以控制压缩质量:0.0为最大压缩,1.0为最大质量(根据苹果的说法,如果可能的话,是无损的) 我发现,从0.99到1.0时,磁盘大小和图像质量都有巨大的飞跃。例如,我有一个2048x1368图像,当质量设置为0.99时,压缩到430KB

我正在Mac OS X和iOS上使用CGImage API(
CGImageDestination,
CGBitmapContext,
CGImage
等)将图像压缩为JPEG格式。使用
KCGIMAGEDESTIONOSSYCOMPRESSIONQUALITY
属性,您可以控制压缩质量:
0.0
为最大压缩,
1.0
为最大质量(根据苹果的说法,如果可能的话,是无损的)

我发现,从
0.99
1.0时,磁盘大小和图像质量都有巨大的飞跃。例如,我有一个2048x1368图像,当质量设置为
0.99
时,压缩到430KB,但当质量设置为1.0时,压缩到2.3MB。视觉质量也有了很大的提高,
0.99
设置对于这个特定的图像是不可接受的。尝试将质量设置为介于
0.99
1.0
之间的任何值都不起作用,因为大小一直保持在430KB,直到
0.995
跳到2.3MB。另外,
0.90
0.99
的文件大小从~353KB到430KB不等,两者之间的质量实际上没有太大差别,但在视觉质量方面没有太大改善

有人知道有没有办法提高JPEG的质量?我真的需要比
0.99
给我的更好,但比
1.0
提供的更少的东西。也许我还可以使用其他API

我可能会尝试直接使用libjpeg,但我希望不会这样

更新 经过调查发现,对于所有
KCGimageDestinationLossycompression Quality
设置,在
1.0
之前,苹果使用4:2:0(或色度抽取)。这意味着对于YCrCb图像,他们每4个亮度(Y)像素仅采样一个色度像素(CrCb)。换句话说,他们只使用了原始图像色度数据的1/4。对于
1.0
的质量,苹果使用4:4:4色度子采样,即没有色度子采样或每个亮度像素有一个色度像素。这就是当图像包含4倍于质量的颜色数据时,文件大小爆炸的原因 也许我还可以使用其他API

是一种来自谷歌的新图像格式,它比jpg和png(无损和有损)提供更好的压缩。github上有一个非常易于使用的项目:

您只需向项目中添加一个类别和WebP框架即可使用它

//Converting To WebP
// quality value is [0, 100]
NSData *webpData = [UIImage imageToWebP:[UIImage imageNamed:@"image.jpg"] quality:75];

//Converting From WebP
UIImage *webPImage = [UIImage imageFromWebP:@"/path/to/file"];

//Setting image transparency
//alpha value is [0, 1]
UIImage *transparencyImage = [[UIImage imageNamed:image.jpg] imageByApplyingAlpha:0.5];
alpha无法正常工作,但由于您使用的是jpg,我假设您不需要它。

最终更新 经过广泛的研究并遵循上面评论中的建议,似乎没有办法禁用任何苹果内置API的色度二次采样/抽取,除非设置
KCGIMAGEDESTINATIONOSSYCOMPRESSIONQUALITY
1.0
,这会产生非常大的图像


如果您需要能够在保存到JPEG时自己控制色度二次采样/抽取,那么您需要使用第三方库,如libjpeg。

非常好的问题和家庭作业!!!可能有用,也可能没用。它引用了
kCVImageBufferChromaSubsampling[420 | 422 | 411]
,您可以使用一些运行时函数来更新该值。不确定CGImage和CVImageBuffer在何处或是否相关,但这可能会有所帮助。您是否考虑过使用PNG?有几种压缩软件应用程序可以真正缩小文件的大小,而质量损失很小(我想到的是ImageOptim和TinyPNG)。想知道你在做什么以需要如此高的质量级别(如此高的分辨率)。我得到非常好的图像在0.75@David H:2048x1368 png超过3MB,tiff超过4MB@TomRedmanCVImageBuffer看起来只用于视频API。无论如何,我需要444色度子采样,所以它看起来不像一个可行的API。不,对于这个特定的项目,它需要标准的8位有损JPEG压缩。因此,WebP、Jpeg2000或其他格式是不可能的。