首页 > 解决方案 > Cropping a JPEG image without resampling it

问题描述

My application needs to read a JPEG file from disk, crop it to a known region, and save it with a different file name. My current implementation looks something like this:

// open and crop the image
let image = CIImage(contentsOf: imagePath)
let cropRect = CGRect(x: 100, y: 100, width: 100, height: 100)
let croppedImage = image.cropped(to: cropRect)

// write to disk
let colorSpace = CGColorSpace(name: CGColorSpace.sRGB)
let context = CIContext()
context.writeJPEGRepresentation(of: croppedImage, to: destination, colorSpace: colorSpace, options: [kCGImageDestinationLossyCompressionQuality as CIImageRepresentationOption: 1])

I've found that even though I am reducing the dimensions of the image by cropping the edges, the saved file is up to twice as large as the original. I assume this is because I am resampling it to save as a new JPEG. I also notice the image is slightly different - perhaps less sharp. I can tweak the compression quality of course to bring the file size down, but again that affects the image quality.

Is there some way to just crop the already-compressed jpeg file without increasing the file size or changing any of its other characteristics?

标签: iosswiftmacosuiimagecore-image

解决方案


Your approach looks correct. Due to the nature of JPEG compression you can't "just crop" an image without decoding and re-encoding it in the process.

The large file size should result from the compression quality you chose. To cite the docs:

A value of 1.0 specifies to use lossless compression if destination format supports it […]

JPEG images with 1.0 quality are often larger then a PNG equivalent. In my experience values between 0.7 and 0.85 yield a good quality-to-size balance.


推荐阅读