裁剪 JPEG 图像而不重新采样

Posted

技术标签:

【中文标题】裁剪 JPEG 图像而不重新采样【英文标题】:Cropping a JPEG image without resampling it 【发布时间】:2019-06-09 19:45:19 【问题描述】:

我的应用程序需要从磁盘读取 JPEG 文件,将其裁剪到已知区域,然后使用不同的文件名保存。我当前的实现看起来像这样:

// 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])

我发现即使我通过裁剪边缘来减小图像的尺寸,保存的文件也最多是原始文件的两倍。我认为这是因为我正在对其重新采样以另存为新的 JPEG。我还注意到图像略有不同 - 可能不那么清晰。我当然可以调整压缩质量以减小文件大小,但这又会影响图像质量。

有没有什么方法可以裁剪已经压缩的 jpeg 文件而不增加文件大小或更改其任何其他特征?

【问题讨论】:

50%?我不这么认为。您说的是 jpeg 而不是未压缩的图像。顺便说一句,50% 的原始图像会产生 1/4 大小的像素 好点 - 我的意思是它当然不应该比原来的大! 如果生成的图像尺寸是 8 的倍数,可以crop a JPEG without recompression,但需要对原始文件进行操作。 CoreImage 做不到。 【参考方案1】:

您的方法看起来是正确的。由于 JPEG 压缩的性质,您不能“仅裁剪”图像而不在此过程中对其进行解码和重新编码。

较大的文件大小应该是您选择的压缩质量造成的。引用文档:

如果目标格式支持,值 1.0 指定使用无损压缩 […]

质量为 1.0 的 JPEG 图像通常比等效的 PNG 图像要大。根据我的经验,介于 0.7 和 0.85 之间的值会产生良好的质量与尺寸平衡。

【讨论】:

有道理,谢谢。我会摆弄质量,看看我能得到什么。 @BenPackard 你提到图像不太清晰,这不应该发生。也许有不同的原因。也许您可以发布一些图片进行比较,我们来看看?

以上是关于裁剪 JPEG 图像而不重新采样的主要内容,如果未能解决你的问题,请参考以下文章

图像复制在 PHP 中重新采样,有人可以解释一下吗?

重新采样表示图像的 numpy 数组

使用 cURL 获取远程图像然后重新采样

当图像重新缩放以适合画布时,织物 js 上的裁剪功能无法正常工作

用php和zend裁剪后如何重新保存图像?

Jpeg 重新启动标记