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

Swift中如何同时裁剪截图的顶部与底部以获取居中矩形区域?

问题描述

我尝试对截图的顶部和底部进行裁剪,以获取居中的矩形区域。目前可以通过origin.y值实现顶部裁剪,但还需要实现底部裁剪。以下是调用代码及扩展实现:

调用代码

let screenshot = takeScreenshot(origin: CGPoint(x: 0, y: 0), size: UIScreen.main.bounds.size)

扩展代码

extension View {
    func takeScreenshot(origin: CGPoint, size: CGSize) -> UIImage {
        let window = UIWindow(frame: CGRect(origin: CGPoint(x: 0, y: 0), size: size))
        let hosting = UIHostingController(rootView: self)
        hosting.view.frame = window.frame
        window.addSubview(hosting.view)
        window.makeKeyAndVisible()
        let image = hosting.view.renderedImage(origin: origin)
        return hosting.view.cropImageCaptured(image: image, origin: origin, size: size)
    }
}

extension UIView {
    func renderedImage(origin: CGPoint) -> UIImage {
        // rect of capture
        let rect = CGRect(origin: CGPoint(x: 0, y: 0), size: self.bounds.size)

        // create the context of bitmap
        UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
        let context: CGContext = UIGraphicsGetCurrentContext()!
        self.layer.render(in: context)
        // get a image from current context bitmap
        let capturedImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return capturedImage
    }
    
    func cropImageCaptured(image: UIImage, origin: CGPoint, size: CGSize) -> UIImage {

        let imageCaptured = image.cgImage;

        guard let image = imageCaptured else {
            return UIImage()
        }

        let mySubimageTemp = image.cropping(to: CGRectMake (0, 4032 / 4, 3024, 4032)) ?? UIImage().cgImage
        
        guard let mySubimage = mySubimageTemp else {
            return UIImage()
        }
        
        let finalcapturedimage = UIImage(cgImage: mySubimage)// this will give you your required image.
        return finalcapturedimage
    }
}
解决方案

核心问题是cropImageCaptured函数使用了硬编码尺寸,无法适配通用场景。要实现居中裁剪顶部和底部,可通过原图片与目标裁剪区域的差值动态计算裁剪位置:

修改后的cropImageCaptured函数

func cropImageCaptured(image: UIImage, targetSize: CGSize) -> UIImage {
    guard let cgImage = image.cgImage else {
        return UIImage()
    }
    
    let originalSize = CGSize(width: cgImage.width, height: cgImage.height)
    
    // 计算居中裁剪的起始坐标和尺寸
    let xOffset = (originalSize.width - targetSize.width) / 2
    let yOffset = (originalSize.height - targetSize.height) / 2
    let cropRect = CGRect(
        x: xOffset,
        y: yOffset,
        width: targetSize.width,
        height: targetSize.height
    )
    
    guard let croppedCGImage = cgImage.cropping(to: cropRect) else {
        return UIImage()
    }
    
    return UIImage(cgImage: croppedCGImage)
}

同步简化相关函数

移除冗余参数,让逻辑更清晰:

extension View {
    func takeScreenshot(targetCropSize: CGSize) -> UIImage {
        let window = UIWindow(frame: UIScreen.main.bounds)
        let hosting = UIHostingController(rootView: self)
        hosting.view.frame = window.frame
        window.addSubview(hosting.view)
        window.makeKeyAndVisible()
        let fullImage = hosting.view.renderedImage()
        return hosting.view.cropImageCaptured(image: fullImage, targetSize: targetCropSize)
    }
}

extension UIView {
    func renderedImage() -> UIImage {
        let rect = self.bounds
        UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
        self.layer.render(in: UIGraphicsGetCurrentContext()!)
        let capturedImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return capturedImage
    }
    
    // 上面修改后的cropImageCaptured函数放在这里
}

使用示例

如果需要裁剪出屏幕高度一半的居中矩形:

let targetSize = CGSize(
    width: UIScreen.main.bounds.width,
    height: UIScreen.main.bounds.height / 2
)
let screenshot = takeScreenshot(targetCropSize: targetSize)

关键说明

  1. 动态计算偏移:通过(原高度 - 目标高度)/2得到顶部裁剪偏移,裁剪区域高度设为目标高度后,底部会自动完成裁剪,最终得到居中区域。
  2. 移除硬编码:所有尺寸基于原图片和目标尺寸动态计算,适配不同设备和自定义需求。
  3. 可扩展自定义裁剪:如果需要手动控制上下裁剪高度,可新增topCropHeight和bottomCropHeight参数,直接计算对应裁剪矩形即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 06:05:37