我正在尝试使用自定义相机开发应用,用户可以在其中添加过滤器或贴纸(如在TextCamera应用中)并分享社交Feed。 但我发现了我的第一个问题。
我使用AVCaptureVideoPreviewLayer向用户显示预览,拍摄照片并将其传递给UiImageView中的另一个视图控制器,但第二张图片比第一张图片大。
我尝试使用此功能调整图片大小:
func resize(image: UIImage) -> UIImage {
let size = image.size
let newWidth = CGFloat(size.width)
let newHeight = CGFloat(size.height - blackBottomTab.bounds.size.height)
let newSize = CGSizeMake(newWidth,newHeight)
let rect = CGRectMake(0, 0, newSize.width, newSize.height)
UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
image.drawInRect(rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
在此功能中,我从图像高度中减去黑色视图(按钮下方)的高度。但是我的结果是不同的(见附图)。
This is my preview with a black view under the button
This is the photo taken larger than preview one
我还尝试在第二个View Controller的Storyboard Image View中使用Aspect Fit,但结果是一样的。
我的错误在哪里?谢谢所有帮助我的人!
答案 0 :(得分:0)
我认为AVCaptureVideoPreviewLayer
框架与屏幕的框架(UIScreen.mainScreen().bounds
)相同,并且您添加了"拍摄照片"在它上面的黑色视图。相反,您应该更改AVCaptureVideoPreviewLayer
。
你的情况(我的想法):
假设绿色矩形是AVCaptureVideoPreviewLayer
帧,红色矩形是黑色视图帧。因此,它覆盖了绿色矩形(顶部)。
让它们看起来像这样:
希望有所帮助。
答案 1 :(得分:0)
我不得不解决类似的问题。正如问题所指出的那样,似乎没有一种简单的方法可以检测视频预览的大小。
https://stackoverflow.com/a/57996039/10449843的答案结尾处提示了我的解决方案,该答案详细说明了我如何拍摄快照并创建带有标签的组合快照。
这里是对该提示的详细说明。
虽然我使用AVCapturePhotoCaptureDelegate拍摄快照,但是我也使用AVCaptureVideoDataOutputSampleBufferDelegate对缓冲区进行一次采样,以便在第一次显示预览时检测快照的比例。
// The preview layer is displayed with aspect fill
let previewLayer = AVCaptureVideoPreviewLayer(session: session)
previewLayer.videoGravity = .resizeAspect
previewLayer.frame = self.cameraView.bounds
检测预览的大小:
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
// Only need to do this once
guard self.sampleVideoSize == true else {
return
}
guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {
return
}
// Sample the size of the preview layer and then store it
DispatchQueue.main.async {
let width = CGFloat(CVPixelBufferGetWidth(pixelBuffer))
let height = CGFloat(CVPixelBufferGetHeight(pixelBuffer))
// Store the video size in a local variable
// We don't care which side is which, we just need the
// picture ratio to decide how to align it on different
// screens.
self.videoSize = CGSize.init(width: width, height: height)
// Now we can set up filters and stickers etc
...
// And we don't need to sample the size again
self.sampleVideoSize = false
}
return
}