相机视图在 Swift 中旋转 90 度

did*_*isy 1 iphone camera uiimagepickercontroller ios swift

当我在 Swift 中制作定制的相机应用程序时。但是当我尝试访问相机时,相机中的视图旋转了 90 度。我试图找到解决方案。我找到的一个解决方案是添加一个 fixOrientation 函数来修复视图。但不工作......这是我的完整代码:

let CIHueAdjust = "CIHueAdjust"
let CIHueAdjustFilter = CIFilter(name: "CIHueAdjust", withInputParameters: ["inputAngle" : 1.24])

let Filters = [CIHueAdjust: CIHueAdjustFilter]

let FilterNames = [String](Filters.keys).sort()

class LiveCamViewController : UIViewController,AVCaptureVideoDataOutputSampleBufferDelegate{
let mainGroup = UIStackView()
let imageView = UIImageView(frame: CGRectZero)
let filtersControl = UISegmentedControl(items: FilterNames)

override func viewDidLoad()
{
    super.viewDidLoad()

    view.addSubview(mainGroup)
    mainGroup.axis = UILayoutConstraintAxis.Vertical
    mainGroup.distribution = UIStackViewDistribution.Fill

    mainGroup.addArrangedSubview(imageView)
    mainGroup.addArrangedSubview(filtersControl)

    imageView.contentMode = UIViewContentMode.ScaleAspectFit

    filtersControl.selectedSegmentIndex = 0

    let captureSession = AVCaptureSession()
    captureSession.sessionPreset = AVCaptureSessionPresetPhoto

    let backCamera = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)

    do
    {
        let input = try AVCaptureDeviceInput(device: backCamera)

        captureSession.addInput(input)
    }
    catch
    {
        print("can't access camera")
        return
    }

    //get captureOutput invoked
    let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
    view.layer.addSublayer(previewLayer)

    let videoOutput = AVCaptureVideoDataOutput()

    videoOutput.setSampleBufferDelegate(self, queue: dispatch_queue_create("sample buffer delegate", DISPATCH_QUEUE_SERIAL))
    if captureSession.canAddOutput(videoOutput)
    {
        captureSession.addOutput(videoOutput)
    }

    captureSession.startRunning()
}

func captureOutput(captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, fromConnection connection: AVCaptureConnection!)
{
    guard let filter = Filters[FilterNames[filtersControl.selectedSegmentIndex]] else
    {
        return
    }

    let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
    let cameraImage = CIImage(CVPixelBuffer: pixelBuffer!)

    filter!.setValue(cameraImage, forKey: kCIInputImageKey)

    let filteredImage = UIImage(CIImage: filter!.valueForKey(kCIOutputImageKey) as! CIImage!)
    let fixedImage = fixOrientation(filteredImage)

    dispatch_async(dispatch_get_main_queue())
    {
        self.imageView.image = fixedImage
    }
}

func fixOrientation(image: UIImage) -> UIImage {
    if (image.imageOrientation == UIImageOrientation.Up) {
        return image;
    }

    print(image.imageOrientation)

    var transform = CGAffineTransformIdentity

    switch (image.imageOrientation) {
    case .Down, .DownMirrored:
        transform = CGAffineTransformTranslate(transform, image.size.width, image.size.height)
        transform = CGAffineTransformRotate(transform, CGFloat(M_PI))
        break
    case .Left, .LeftMirrored:
        transform = CGAffineTransformTranslate(transform, image.size.width, 0)
        transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))
        break
    case .Right, .RightMirrored:
        transform = CGAffineTransformTranslate(transform, 0, image.size.height)
        transform = CGAffineTransformRotate(transform, CGFloat(-M_PI_2))
        break
    case .Up, .UpMirrored:
        break
    }

    switch (image.imageOrientation) {
    case .UpMirrored, .DownMirrored:
        transform = CGAffineTransformTranslate(transform, image.size.width, 0)
        transform = CGAffineTransformScale(transform, -1, 1)
        break
    case .LeftMirrored, .RightMirrored:
        transform = CGAffineTransformTranslate(transform, image.size.height, 0)
        transform = CGAffineTransformScale(transform, -1, 1)
        break
    case .Up, .Down, .Left, .Right:
        break
    }

    //Draw the underlying CGImage into a new context, applying the transform
    let ctx = CGBitmapContextCreate(nil, Int(image.size.width), Int(image.size.height), CGImageGetBitsPerComponent(image.CGImage), 0, CGImageGetColorSpace(image.CGImage), UInt32(CGImageGetBitmapInfo(image.CGImage).rawValue))

    CGContextConcatCTM(ctx, transform);

    switch (image.imageOrientation) {
    case .Left, .LeftMirrored, .Right, .RightMirrored:
        CGContextDrawImage(ctx, CGRectMake(0, 0, image.size.height, image.size.width), image.CGImage)
        break
    default:
        CGContextDrawImage(ctx, CGRectMake(0, 0, image.size.width, image.size.height), image.CGImage)
        break
    }

    let cgimg = CGBitmapContextCreateImage(ctx)
    let img = UIImage(CGImage:cgimg!)

    return img
}

override func viewDidLayoutSubviews()
{
    mainGroup.frame = CGRect(x: 37, y: 115, width: 301, height: 481)
}
Run Code Online (Sandbox Code Playgroud)

}

我设置了一个断点来测试,代码似乎只运行到

if (image.imageOrientation == UIImageOrientation.Up) {
        return image;
    }
Run Code Online (Sandbox Code Playgroud)

然后它返回相同的视图......

谁能帮我?谢谢!!!

Luk*_*yer 6

在从 CMSampleBuffer 获取 CIImage 的 capture() 中,执行以下操作:

   yourCIImage = yourCIImage.applyingOrientation(6)
Run Code Online (Sandbox Code Playgroud)

根据您想要旋转和镜像的方式,将数字从 1 更改为 8。 https://developer.apple.com/documentation/imageio/kcgimagepropertyorientation