gpt4 book ai didi

ios - AVCAPTURE 图像方向

转载 作者:搜寻专家 更新时间:2023-10-31 22:40:59 24 4
gpt4 key购买 nike

enter image description here我有一个允许用户拍照的 View Controller 。我将 avcapture 边界设置为屏幕上 View 的边界。

在这个 View 之上我有一个 Collection View 。因此用户可以捕获多张照片,然后将它们添加到上面的 Collection View 中。

我在上面的预览中无法正确显示方向。

代码如下:

@IBOutlet weak var imagePreviews: UICollectionView!
@IBOutlet weak var imgPreview: UIView!

var session: AVCaptureSession?
var stillImageOutput: AVCaptureStillImageOutput?
var videoPreviewLayer: AVCaptureVideoPreviewLayer?
var images: [UIImage] = [UIImage]()

var isLandscapeLeft : Bool = false
var isLandscapeRight : Bool = false
var isPortrait : Bool = false
var isPortraitUpsideDown: Bool = false

@IBAction func capture(_ sender: UIButton)
{
if let videoConnection = stillImageOutput?.connection(withMediaType: AVMediaTypeVideo)
{
stillImageOutput?.captureStillImageAsynchronously(from: videoConnection, completionHandler: { (sampleBuffer, error) in
if sampleBuffer != nil {
if let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(sampleBuffer), let dataProvider = CGDataProvider(data: imageData as CFData), let cgImageRef = CGImage(jpegDataProviderSource: dataProvider, decode: nil, shouldInterpolate: true, intent: CGColorRenderingIntent.defaultIntent)
{
var image: UIImage

if (self.isLandscapeLeft || self.isLandscapeRight)
{
image = UIImage(cgImage: cgImageRef, scale: 1.0, orientation: self.isLandscapeLeft ? UIImageOrientation.left : UIImageOrientation.right)
} else {
image = UIImage(cgImage: cgImageRef, scale: 1.0, orientation: self.isPortrait ? UIImageOrientation.up : UIImageOrientation.down)
}

image = self.fixOrientation(img: image)
self.images.append(image)


DispatchQueue.main.async {
self.imagePreviews.reloadData()
}
}
}
})
}
}
}

override func viewDidLayoutSubviews() {

super.viewDidLayoutSubviews()

if let connection = self.videoPreviewLayer?.connection {

let currentDevice: UIDevice = UIDevice.current

let orientation: UIDeviceOrientation = currentDevice.orientation

let previewLayerConnection : AVCaptureConnection = connection

if (previewLayerConnection.isVideoOrientationSupported) {

switch (orientation) {
case .portrait:

isLandscapeLeft = false
isLandscapeRight = false
isPortrait = true
isPortraitUpsideDown = false
updatePreviewLayer(layer: previewLayerConnection, orientation: .portrait)
break

case .landscapeRight:

isLandscapeLeft = false
isLandscapeRight = true
isPortrait = false
isPortraitUpsideDown = false
updatePreviewLayer(layer: previewLayerConnection, orientation: .landscapeRight)
break

case .landscapeLeft:

isLandscapeLeft = true
isLandscapeRight = false
isPortrait = false
isPortraitUpsideDown = false
updatePreviewLayer(layer: previewLayerConnection, orientation: .landscapeLeft)
break
case .portraitUpsideDown:

isLandscapeLeft = false
isLandscapeRight = false
isPortrait = false
isPortraitUpsideDown = true
updatePreviewLayer(layer: previewLayerConnection, orientation: .portraitUpsideDown)
break
default:

updatePreviewLayer(layer: previewLayerConnection, orientation: .portrait)

break
}
}
}
}

func fixOrientation(img: UIImage) -> UIImage {
if (img.imageOrientation == .up) {
return img
}

UIGraphicsBeginImageContextWithOptions(img.size, false, img.scale)
let rect = CGRect(x: 0, y: 0, width: img.size.width, height: img.size.height)
img.draw(in: rect)

let normalizedImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()

return normalizedImage
}

最佳答案

从纵向设备创建图像时,您应该考虑将 UIImage 旋转 90 度,例如:

switch UIApplication.shared.statusBarOrientation {
case .portrait:
image = UIImage(cgImage: cgImageRef, scale: 1.0, orientation: .right)
case .landscapeRight:
image = UIImage(cgImage: cgImageRef, scale: 1.0, orientation: .up)
case .landscapeLeft:
image = UIImage(cgImage: cgImageRef, scale: 1.0, orientation: .down)
case .portraitUpsideDown:
image = UIImage(cgImage: cgImageRef, scale: 1.0, orientation: .left)
default:
fatalError("Unexpected orientation")
}

有关完整示例,请参阅:

import UIKit
import AVFoundation

class ViewController: UIViewController {

@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var videoPreviewView: UIView!
var videoPreviewLayer: AVCaptureVideoPreviewLayer!

var session: AVCaptureSession = AVCaptureSession()
var stillImageOutput: AVCaptureStillImageOutput = {
let output = AVCaptureStillImageOutput()
output.outputSettings = [AVVideoCodecKey: AVVideoCodecJPEG]
return output
}()

var images: [UIImage] = [UIImage]()

var orientation = UIApplication.shared.statusBarOrientation

override func viewDidLoad() {
super.viewDidLoad()

guard let device = AVCaptureDevice.default(for: .video) else {
print("Unable to create capture device")
return
}

let input: AVCaptureDeviceInput
do {
input = try AVCaptureDeviceInput(device: device)
} catch {
print("Unable to create input", error)
return
}

guard session.canAddInput(input) else {
print("Cannot add input")
return
}
session.addInput(input)

guard session.canAddOutput(stillImageOutput) else {
print("Cannot add output")
return
}
session.addOutput(stillImageOutput)

session.startRunning()
videoPreviewLayer = AVCaptureVideoPreviewLayer(session: session)
videoPreviewView.layer.addSublayer(videoPreviewLayer)
}

@IBAction func didTapCaptureButton(_ sender: Any) {
if let connection = stillImageOutput.connection(with: .video) {
stillImageOutput.captureStillImageAsynchronously(from: connection) { sampleBuffer, error in
guard let sampleBuffer = sampleBuffer, error == nil else {
print(error ?? "Unknown error")
return
}

guard
let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(sampleBuffer),
let dataProvider = CGDataProvider(data: imageData as CFData),
let cgImageRef = CGImage(jpegDataProviderSource: dataProvider, decode: nil, shouldInterpolate: true, intent: .defaultIntent) else {
print("unable to capture image")
return
}

var image: UIImage?

switch self.orientation {
case .portrait:
image = UIImage(cgImage: cgImageRef, scale: 1.0, orientation: .right)
case .landscapeRight:
image = UIImage(cgImage: cgImageRef, scale: 1.0, orientation: .up)
case .landscapeLeft:
image = UIImage(cgImage: cgImageRef, scale: 1.0, orientation: .down)
case .portraitUpsideDown:
image = UIImage(cgImage: cgImageRef, scale: 1.0, orientation: .left)
default:
fatalError("Unexpected orientation")
}

guard image != nil else {
print("unable to create UIImage")
return
}

DispatchQueue.main.async {
self.images.append(image!)
self.imageView.image = image
}
}

}
}

override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()

if let connection = self.videoPreviewLayer?.connection {
orientation = UIApplication.shared.statusBarOrientation

switch orientation {
case .portrait: updatePreviewOrientation(for: connection, to: .portrait)
case .landscapeRight: updatePreviewOrientation(for: connection, to: .landscapeRight)
case .landscapeLeft: updatePreviewOrientation(for: connection, to: .landscapeLeft)
case .portraitUpsideDown: updatePreviewOrientation(for: connection, to: .portraitUpsideDown)
default: updatePreviewOrientation(for: connection, to: .portrait)
}
}
}

private func updatePreviewOrientation(for connection: AVCaptureConnection, to orientation: AVCaptureVideoOrientation) {
if connection.isVideoOrientationSupported {
connection.videoOrientation = orientation
}
videoPreviewLayer.frame = videoPreviewView.bounds
}
}

您正在 fixOrientation 中手动转换图像方向。使用适当的 orientationCGImage 创建 UIImage 后,如果您不想要,就不必重新创建图像.

关于ios - AVCAPTURE 图像方向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46913953/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com