我正在尝试制作一个简单的应用程序,它将在iphone屏幕的上半部分显示后置摄像头看到的原始预览,而在下半部分则使用相同的预览,但应用了各种过滤器。
我首先得到了原始预览部分,感谢几篇SO和博客文章。我正在显示的UIImageView占用了该部分的整个屏幕。
要获得半屏视图,我只需将图像视图的高度除以2,然后将其contentMode设置为显示所有内容,同时保持相同的宽高比:
imageView = UIImageView(frame: CGRectMake(0,0, self.view.frame.size.width, self.view.frame.size.height/2))
imageView.contentMode = UIViewContentMode.ScaleAspectFit
高度降低有效,但视图中的图像是垂直压缩的(例如直视的硬币看起来像水平的椭圆形)。我不认为预览的外观看起来像contentMode默认的ScaleToFill是巧合,但我尝试过没有改变模式。
完整的代码如下 - 项目有一个场景,一个视图控制器类;一切都是以编程方式完成的。
谢谢!
import UIKit
import AVFoundation
class ViewController: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate
{
var imageView : UIImageView!
override func viewDidLoad()
{
super.viewDidLoad()
imageView = UIImageView(frame: CGRectMake(0,0, self.view.frame.size.width, self.view.frame.size.height/2))
imageView.contentMode = UIViewContentMode.ScaleAspectFit
view.addSubview(imageView)
let captureSession = AVCaptureSession()
captureSession.sessionPreset = AVCaptureSessionPresetHigh
let backCamera = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
do
{
let input = try AVCaptureDeviceInput(device: backCamera)
captureSession.addInput(input)
}
catch
{
print("Camera not available")
return
}
// Unused but required for AVCaptureVideoDataOutputSampleBufferDelegate:captureOutput() events to be fired
let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
view.layer.addSublayer(previewLayer)
let videoOutput = AVCaptureVideoDataOutput()
videoOutput.setSampleBufferDelegate(self, queue: dispatch_queue_create("SampleBufferDelegate", DISPATCH_QUEUE_SERIAL))
if captureSession.canAddOutput(videoOutput)
{
captureSession.addOutput(videoOutput)
}
videoOutput.connectionWithMediaType(AVMediaTypeVideo).videoOrientation = AVCaptureVideoOrientation.Portrait
captureSession.startRunning()
}
func captureOutput(captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, fromConnection connection: AVCaptureConnection!)
{
let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
let cameraImage = CIImage(CVPixelBuffer: pixelBuffer!)
dispatch_async(dispatch_get_main_queue())
{
self.imageView.image = UIImage(CIImage: cameraImage)
}
}
}
答案 0 :(得分:1)
我想这行有问题,因为它在viewDidLoad()
方法中。
不确定它与您的问题有关,但我觉得这对您来说非常重要。
imageView = UIImageView(frame: CGRectMake(0,0, self.view.frame.size.width, self.view.frame.size.height/2))
您无法在viewDidLoad()
函数中获得正确的视图大小。
此外,从iOS 10开始,我发现在iOS布局引擎正确布局控件之前,控件的初始大小为(0, 0, 1000, 1000)
。
此外,您在viewDidLoad()
中获得的大小可以是故事板中视图控制器的大小。因此,如果您在4英寸屏幕中布置控件,即使您在iPhone6或更大的屏幕上运行应用程序,它也会以viewDidLoad()
方式返回4英寸屏幕的大小。
另外,请将imageView.layer.maskToBounds
属性设置为true以防止图像出现任何边界。
还有一件事是,当视图边界发生变化时,您应该放置代码以适当地布置图像视图(如屏幕旋转)。