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)
关键说明
- 动态计算偏移:通过
(原高度 - 目标高度)/2得到顶部裁剪偏移,裁剪区域高度设为目标高度后,底部会自动完成裁剪,最终得到居中区域。 - 移除硬编码:所有尺寸基于原图片和目标尺寸动态计算,适配不同设备和自定义需求。
- 可扩展自定义裁剪:如果需要手动控制上下裁剪高度,可新增
topCropHeight和bottomCropHeight参数,直接计算对应裁剪矩形即可。
内容的提问来源于stack exchange,提问作者stefanosn
相关产品推荐
相关产品推荐

