- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我发现了以下问题,不幸的是其他帖子没有帮助我找到有效的解决方案。
我有一个简单的应用程序可以显示相机预览 (AVCaptureVideoPreviewLayer),其中视频重力已设置为 resizeAspectFill (videoGravity = .resizeAspectFill
)。
据我了解,这只会拉伸(stretch)图像的宽度以填满屏幕。
在我的预览层上,我还应用了一个 CGRect 作为具有固定 x、y、宽度和高度的 mask 。
现在,一旦我拍了一张照片,我就会尝试从图像中裁剪出那个精确的矩形。据我了解,我应该使用某种数学方法将 CGRect 转换为与我从 AVCapturePhotoOutput 方法获得的图像相同的纵横比,但它似乎从未在宽度上正确裁剪。
private func cropImage(image: UIImage) {
let rect = CGRect(x: 25, y: 150, width: 325, height: 230)
let scale = CGAffineTransform(scaleX: 1/self.view.frame.width, y: 1/self.view.frame.height)
let flip = CGAffineTransform(scaleX: 1, y: -1).translatedBy(x: 0, y: -1)
let bounds = rect.applying(scale).applying(flip)
let topLeft = bounds.topLeft.scaled(to: image.size)
let topRight = bounds.topRight.scaled(to: image.size)
let bottomLeft = bounds.bottomLeft.scaled(to: image.size)
let bottomRight = bounds.bottomRight.scaled(to: image.size)
var ciImage = CIImage(image: image.forceSameOrientation())!
ciImage = ciImage.applyingFilter("CIPerspectiveCorrection", parameters: [
"inputTopLeft": CIVector(cgPoint: bottomLeft),
"inputTopRight": CIVector(cgPoint: bottomRight),
"inputBottomLeft": CIVector(cgPoint: topLeft),
"inputBottomRight": CIVector(cgPoint: topRight)
])
let context = CIContext()
let cgImage = context.createCGImage(ciImage, from: ciImage.extent)
let output = UIImage(cgImage: cgImage!)
let vc = PreviewViewController()
vc.imageView.image = output
self.present(vc, animated: true, completion: nil)
}
所以,基本上它确实在正确的高度裁剪,但它只是宽度似乎不太好。
我想要捕捉的图像示例。
如您所见,左上角的边界框在“Q”按钮后停止。
结果:
正如您在这张图片中看到的,它确实在高度上正确裁剪了,但是如果我们看一下左上角,它还包括“Q”(Tab 按钮)左侧的一半按钮
任何对解决方案的帮助将不胜感激!
最佳答案
我设法用这段代码解决了这个问题。
private func cropToPreviewLayer(from originalImage: UIImage, toSizeOf rect: CGRect) -> UIImage? {
guard let cgImage = originalImage.cgImage else { return nil }
// This previewLayer is the AVCaptureVideoPreviewLayer which the resizeAspectFill and videoOrientation portrait has been set.
let outputRect = previewLayer.metadataOutputRectConverted(fromLayerRect: rect)
let width = CGFloat(cgImage.width)
let height = CGFloat(cgImage.height)
let cropRect = CGRect(x: (outputRect.origin.x * width), y: (outputRect.origin.y * height), width: (outputRect.size.width * width), height: (outputRect.size.height * height))
if let croppedCGImage = cgImage.cropping(to: cropRect) {
return UIImage(cgImage: croppedCGImage, scale: 1.0, orientation: originalImage.imageOrientation)
}
return nil
}
在我的案例中使用这段代码:
let rect = CGRect(x: 25, y: 150, width: 325, height: 230)
let croppedImage = self.cropToPreviewLayer(from: image, toSizeOf: rect)
self.imageView.image = croppedImage
关于swift - 从 AVCapturePhotoOutput 裁剪 CGRect (resizeAspectFill),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69328405/
我发现了以下问题,不幸的是其他帖子没有帮助我找到有效的解决方案。 我有一个简单的应用程序可以显示相机预览 (AVCaptureVideoPreviewLayer),其中视频重力已设置为 resizeA
在 watchOS 应用中播放视频。 WKInterfaceMovie — 一个界面元素,可让您在 watchOS 应用程序中播放视频和音频内容。 按预期工作。视频播放。如何将它缩放到填满屏幕? St
我正在尝试设置 CALayer 的 contentGravity 变量,但我不太确定如何执行此操作。我尝试了以下方法但没有成功: var layer = CAShapeLayer.init() lay
我正在使用 Swift 3 开发一个 iOS 应用程序,我在后台播放视频。我的代码工作完全正常,直到随机出现错误消息: Type AVLayerVideoGravity aka (NSString)
我是一名优秀的程序员,十分优秀!