You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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 // 确保坐标为整数,避免图片模糊
}

关键修改说明

  1. 目标比例定义:用targetAspectRatio = 16.0/9.0替代原正方形的1:1比例逻辑,明确裁剪目标。
  2. 比例对比逻辑:
    • 原图宽高比大于16:9时:原图偏宽,裁剪左右两侧,保留原图高度,计算裁剪宽度与x轴偏移量。
    • 原图宽高比小于16:9时:原图偏高,裁剪上下两侧,保留原图宽度,计算裁剪高度与y轴偏移量。
  3. 坐标系适配:新增辅助函数处理UIImage方向与CGImage坐标系的差异,避免因图片旋转/镜像导致裁剪区域错位。
  4. 整数坐标修正:使用.integral确保裁剪区域的坐标和尺寸为整数,避免裁剪后图片出现模糊或边缘异常。

整合到缩略图流程

将原有裁剪函数替换为上述cropImageTo16_9,按你的流程执行:裁剪 -> 缩放 -> 压缩,即可得到符合16:9比例的缩略图。

内容的提问来源于stack exchange,提问作者Alexnnd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 13:35:28