I’m using the CGImage APIs (CGImageDestination,
CGBitmapContext,
, CGImage
etc.) on Mac OS X as well as iOS to compress images to JPEG. Using the kCGImageDestinationLossyCompressionQuality
property you can control the compression quality: 0.0
being maximum compression and 1.0
being maximum quality (lossless if possible according to Apple).
I’ve found that there’s a huge jump in both disk size & image quality when you go from 0.99
to 1.0.
For example, I’ve got a 2048x1368 image that compresses to 430 KB when the quality is set to 0.99
but balloons to 2.3 MB when the quality is set to 1.0. There’s a big jump in visual quality as well and the 0.99
setting isn’t acceptable for this particular image. Trying to set the quality to anything between 0.99
to 1.0
doesn’t work as the size remains at 430 KB up until 0.995
where it jumps up to 2.3 MB. Also, there really isn’t much difference between qualities of 0.90
to 0.99
which ranges in file size from ~353 KB to 430 KB, but not much improvement in visual quality.
Does anyone know if there’s any way to increase the JPEG quality? I really need something better than what 0.99
is giving me but less than what 1.0
provides. Maybe there’s some other API I could use?
I may try using libjpeg directly but I hope it doesn’t come to that.
Update
After some investigation it turns out that for all kCGImageDestinationLossyCompressionQuality
settings up to 1.0
Apple uses 4:2:0 chroma subsampling (or chroma decimation). This means that for the YCrCb image they only sample one chroma pixel (CrCb) for every 4 luminance (Y) pixels. In other words they’re only using 1/4 of the chroma data from the original image. For a quality of 1.0
Apple uses 4:4:4 chroma subsampling, which is no chroma subsampling or one chroma pixel for every luminance pixel. This is why the file size explodes as the image contains 4x the color data vs. qualities <= 0.99
.
So, does anyone know if there’s a way to turn off chroma subsampling using CGImage (or any other API) for qualities less than 1.0
?