如何使用Swift将任意图片裁剪为16:9比例的矩形?
实现16:9比例图片裁剪的修改方案
你当前的cropImage函数仅针对正方形裁剪逻辑,要实现16:9比例裁剪,核心是根据原图宽高比与16:9的对比,计算出正确的裁剪区域尺寸和偏移量。以下是修改后的完整代码及关键步骤说明:
修改后的裁剪函数
func cropImageTo16_9() { guard let selectedPhotoData, let image = UIImage(data: selectedPhotoData) else { return } let targetAspectRatio: CGFloat = 16.0 / 9.0 let sourceSize = image.size let sourceAspectRatio = sourceSize.width / sourceSize.height var cropRect: CGRect if sourceAspectRatio > targetAspectRatio { // 原图比16:9更宽,裁剪左右两侧,保留高度不变 let cropWidth = sourceSize.height * targetAspectRatio let xOffset = (sourceSize.width - cropWidth) / 2 cropRect = CGRect(x: xOffset, y: 0, width: cropWidth, height: sourceSize.height) } else { // 原图比16:9更高,裁剪上下两侧,保留宽度不变 let cropHeight = sourceSize.width / targetAspectRatio let yOffset = (sourceSize.height - cropHeight) / 2 cropRect = CGRect(x: 0, y: yOffset, width: sourceSize.width, height: cropHeight) } // 处理UIImage方向与CGImage坐标系的差异 let correctedCropRect = convertRectToCGImageCoordinates(rect: cropRect, for: image) guard let croppedCGImage = image.cgImage?.cropping(to: correctedCropRect) else { return } let croppedImage = UIImage(cgImage: croppedCGImage, scale: image.scale, orientation: image.imageOrientation) selectedThumbData = croppedImage.jpegData(compressionQuality: 0.80) } // 辅助函数:转换UIImage坐标系到CGImage坐标系(适配图片旋转/镜像) private func convertRectToCGImageCoordinates(rect: CGRect, for image: UIImage) -> CGRect { let cgImageSize = image.cgImage?.size ?? image.size var convertedRect = rect // 处理90/270度旋转的宽高互换 switch image.imageOrientation { case .left, .leftMirrored, .right, .rightMirrored: convertedRect = CGRect( x: rect.origin.y, y: rect.origin.x, width: rect.height, height: rect.width ) default: break } // 处理上下/左右镜像的偏移修正 switch image.imageOrientation { case .down, .downMirrored: convertedRect.origin.y = cgImageSize.height - convertedRect.origin.y - convertedRect.height case .leftMirrored, .rightMirrored: convertedRect.origin.x = cgImageSize.width - convertedRect.origin.x - convertedRect.width default: break } return convertedRect.integral // 确保坐标为整数,避免图片模糊 }
关键修改说明
- 目标比例定义:用
targetAspectRatio = 16.0/9.0替代原正方形的1:1比例逻辑,明确裁剪目标。 - 比例对比逻辑:
- 原图宽高比大于16:9时:原图偏宽,裁剪左右两侧,保留原图高度,计算裁剪宽度与x轴偏移量。
- 原图宽高比小于16:9时:原图偏高,裁剪上下两侧,保留原图宽度,计算裁剪高度与y轴偏移量。
- 坐标系适配:新增辅助函数处理
UIImage方向与CGImage坐标系的差异,避免因图片旋转/镜像导致裁剪区域错位。 - 整数坐标修正:使用
.integral确保裁剪区域的坐标和尺寸为整数,避免裁剪后图片出现模糊或边缘异常。
整合到缩略图流程
将原有裁剪函数替换为上述cropImageTo16_9,按你的流程执行:裁剪 -> 缩放 -> 压缩,即可得到符合16:9比例的缩略图。
内容的提问来源于stack exchange,提问作者Alexnnd
相关产品推荐
相关产品推荐

