Ios 相机视图在Swift中旋转90度
当我在Swift中制作定制相机应用程序时。 但当我尝试访问相机时,相机中的视图旋转了90度。我试图找到解决办法。我发现的一个解决方案是添加一个fixOrientation函数来修复视图。但是不工作。。。 这是我的全部代码:Ios 相机视图在Swift中旋转90度,ios,iphone,swift,camera,uiimagepickercontroller,Ios,Iphone,Swift,Camera,Uiimagepickercontroller,当我在Swift中制作定制相机应用程序时。 但当我尝试访问相机时,相机中的视图旋转了90度。我试图找到解决办法。我发现的一个解决方案是添加一个fixOrientation函数来修复视图。但是不工作。。。 这是我的全部代码: let CIHueAdjust = "CIHueAdjust" let CIHueAdjustFilter = CIFilter(name: "CIHueAdjust", withInputParameters: ["inputAngle" : 1.24]) let Fil
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)
}
}
我设置了一个断点进行测试,代码似乎只运行到
if (image.imageOrientation == UIImageOrientation.Up) {
return image;
}
然后它返回相同的视图
有人能帮我吗?
谢谢 试试这个方法:(取自)
请尝试以下方法:(取自)
对于需要Swift 3中@LoVo代码的用户:
func rotateCameraImageToProperOrientation(imageSource : UIImage, maxResolution : CGFloat) -> UIImage {
guard let imgRef = imageSource.cgImage else {
return imageSource
}
let width = CGFloat(imgRef.width);
let height = CGFloat(imgRef.height);
var bounds = CGRect(x: 0, y: 0, width: width, height: height)
var scaleRatio : CGFloat = 1
if (width > maxResolution || height > maxResolution) {
scaleRatio = min(maxResolution / bounds.size.width, maxResolution / bounds.size.height)
bounds.size.height = bounds.size.height * scaleRatio
bounds.size.width = bounds.size.width * scaleRatio
}
var transform = CGAffineTransform.identity
let orient = imageSource.imageOrientation
let imageSize = CGSize(width: CGFloat(imgRef.width), height: CGFloat(imgRef.height))
switch(imageSource.imageOrientation) {
case .up :
transform = CGAffineTransform.identity
case .upMirrored :
transform = CGAffineTransform(translationX: imageSize.width, y: 0.0)
transform = transform.scaledBy(x: -1.0, y: 1.0)
case .down :
transform = CGAffineTransform(translationX: imageSize.width, y: imageSize.height)
transform = transform.rotated(by: CGFloat(M_PI))
case .downMirrored :
transform = CGAffineTransform(translationX: 0.0, y: imageSize.height)
transform = transform.scaledBy(x: 1.0, y: -1.0)
case .left :
let storedHeight = bounds.size.height
bounds.size.height = bounds.size.width
bounds.size.width = storedHeight
transform = CGAffineTransform(translationX: 0.0, y: imageSize.width)
transform = transform.rotated(by: 3.0 * CGFloat(M_PI) / 2.0)
case .leftMirrored :
let storedHeight = bounds.size.height
bounds.size.height = bounds.size.width
bounds.size.width = storedHeight
transform = CGAffineTransform(translationX: imageSize.height, y: imageSize.width)
transform = transform.scaledBy(x: -1.0, y: 1.0)
transform = transform.rotated(by: 3.0 * CGFloat(M_PI) / 2.0)
case .right :
let storedHeight = bounds.size.height
bounds.size.height = bounds.size.width
bounds.size.width = storedHeight
transform = CGAffineTransform(translationX: imageSize.height, y: 0.0)
transform = transform.rotated(by: CGFloat(M_PI) / 2.0)
case .rightMirrored :
let storedHeight = bounds.size.height
bounds.size.height = bounds.size.width
bounds.size.width = storedHeight
transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
transform = transform.rotated(by: CGFloat(M_PI) / 2.0)
}
UIGraphicsBeginImageContext(bounds.size)
guard let context = UIGraphicsGetCurrentContext() else {
return imageSource
}
if orient == .right || orient == .left {
context.scaleBy(x: -scaleRatio, y: scaleRatio)
context.translateBy(x: -height, y: 0)
} else {
context.scaleBy(x: scaleRatio, y: -scaleRatio)
context.translateBy(x: 0, y: -height)
}
context.concatenate(transform);
context.draw(imgRef, in: CGRect(x: 0, y: 0, width: width, height: height))
guard let imageCopy = UIGraphicsGetImageFromCurrentImageContext() else {
return imageSource
}
UIGraphicsEndImageContext();
return imageCopy;
}
对于需要Swift 3中@LoVo代码的用户:
func rotateCameraImageToProperOrientation(imageSource : UIImage, maxResolution : CGFloat) -> UIImage {
guard let imgRef = imageSource.cgImage else {
return imageSource
}
let width = CGFloat(imgRef.width);
let height = CGFloat(imgRef.height);
var bounds = CGRect(x: 0, y: 0, width: width, height: height)
var scaleRatio : CGFloat = 1
if (width > maxResolution || height > maxResolution) {
scaleRatio = min(maxResolution / bounds.size.width, maxResolution / bounds.size.height)
bounds.size.height = bounds.size.height * scaleRatio
bounds.size.width = bounds.size.width * scaleRatio
}
var transform = CGAffineTransform.identity
let orient = imageSource.imageOrientation
let imageSize = CGSize(width: CGFloat(imgRef.width), height: CGFloat(imgRef.height))
switch(imageSource.imageOrientation) {
case .up :
transform = CGAffineTransform.identity
case .upMirrored :
transform = CGAffineTransform(translationX: imageSize.width, y: 0.0)
transform = transform.scaledBy(x: -1.0, y: 1.0)
case .down :
transform = CGAffineTransform(translationX: imageSize.width, y: imageSize.height)
transform = transform.rotated(by: CGFloat(M_PI))
case .downMirrored :
transform = CGAffineTransform(translationX: 0.0, y: imageSize.height)
transform = transform.scaledBy(x: 1.0, y: -1.0)
case .left :
let storedHeight = bounds.size.height
bounds.size.height = bounds.size.width
bounds.size.width = storedHeight
transform = CGAffineTransform(translationX: 0.0, y: imageSize.width)
transform = transform.rotated(by: 3.0 * CGFloat(M_PI) / 2.0)
case .leftMirrored :
let storedHeight = bounds.size.height
bounds.size.height = bounds.size.width
bounds.size.width = storedHeight
transform = CGAffineTransform(translationX: imageSize.height, y: imageSize.width)
transform = transform.scaledBy(x: -1.0, y: 1.0)
transform = transform.rotated(by: 3.0 * CGFloat(M_PI) / 2.0)
case .right :
let storedHeight = bounds.size.height
bounds.size.height = bounds.size.width
bounds.size.width = storedHeight
transform = CGAffineTransform(translationX: imageSize.height, y: 0.0)
transform = transform.rotated(by: CGFloat(M_PI) / 2.0)
case .rightMirrored :
let storedHeight = bounds.size.height
bounds.size.height = bounds.size.width
bounds.size.width = storedHeight
transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
transform = transform.rotated(by: CGFloat(M_PI) / 2.0)
}
UIGraphicsBeginImageContext(bounds.size)
guard let context = UIGraphicsGetCurrentContext() else {
return imageSource
}
if orient == .right || orient == .left {
context.scaleBy(x: -scaleRatio, y: scaleRatio)
context.translateBy(x: -height, y: 0)
} else {
context.scaleBy(x: scaleRatio, y: -scaleRatio)
context.translateBy(x: 0, y: -height)
}
context.concatenate(transform);
context.draw(imgRef, in: CGRect(x: 0, y: 0, width: width, height: height))
guard let imageCopy = UIGraphicsGetImageFromCurrentImageContext() else {
return imageSource
}
UIGraphicsEndImageContext();
return imageCopy;
}
在capture()中,您从CMSampleBuffer获取CIImage,请在以下操作之后执行此操作:
yourCIImage = yourCIImage.applyingOrientation(6)
根据旋转和镜像的方式,将数字从1-8更改为1。
在capture()中,您可以从CMSampleBuffer获取CIImage,然后执行以下操作:
yourCIImage = yourCIImage.applyingOrientation(6)
根据旋转和镜像的方式,将数字从1-8更改为1。
So image.imageOrientation==UIImageOrientation.Up为真,如果要测试下面的逻辑,请注释该部分。@LoVo Hi,谢谢回复。我已经评论过了。但是我仍然有一些错误。与CGBitmapContextCreate:不支持的参数组合类似,CGContextConcatCTM:无效上下文0x0,CGContextDrawImage:无效上下文0x0,CGBitmapContextCreateImage:无效上下文0x0。我不知道怎么了:(你能在程序崩溃之前检查
ctx
和transform
的值吗?@LoVo抱歉,怎么做?在你的应用程序崩溃的那一行之前设置一个断点,但在设置完这些值之后。因此image.imageOrientation==UIImageOrientation.Up是真的,如果你想测试下面的逻辑,请注释该部分。@LoVo Hi,thx用于回复。I我已经对这些内容进行了注释。但我仍然有一些错误。例如CGBitmapContextCreate:不支持的参数组合,CGContextConcatCTM:无效上下文0x0,CGContextDrawImage:无效上下文0x0,CGBitmapContextCreateImage:无效上下文0x0。我不知道发生了什么错误:(你能在崩溃之前检查一下ctx
和transform
的值吗?@LoVo抱歉,怎么做?在你的应用程序崩溃的那一行之前设置一个断点,但在设置了这些值之后。抱歉,这对我仍然不起作用。在我使用任何fixOrientation方法之前:视图逆时针旋转90度,它正在查看。)将手机逆时针旋转90度(水平放置手机)时正确。在我添加you方法后,无论我旋转手机的方向如何,视图总是逆时针改变90度抱歉。我的错误。实际上此方法没有改变任何东西抱歉,当我执行此代码时,它仍然会出现以下错误:CGContextScaleCTM:无效上下文0x0.cgContextTranslateCm:无效上下文0x0.CGContextConcatCTM:invalid context 0x0.CGContextDrawImage:invalid context 0x0.yes,我也尝试过对这个if语句进行注释。视图仍然在旋转。对不起,它对我仍然不起作用。在我使用任何fixOrientation方法之前:视图逆时针旋转90度,当你逆时针旋转手机时,它可以正确查看90度(水平放置手机)。在我添加you方法后,无论我旋转手机的方向如何,视图总是逆时针改变90度抱歉。我的错误。实际上此方法没有改变任何东西抱歉,当我执行此代码时,它仍然会出现以下错误:CGContextScaleCTM:无效上下文0x0.cgContextTranslateCm:无效上下文0x0.CGContextcontctm:invalid context 0x0.CGContextDrawImage:invalid context 0x0.yes,我也尝试过对这个if语句进行注释。视图仍在旋转。到目前为止最简单的解决方案(y)我已经花了一个小时处理转换和上下文,这就是最终解决它的方法。到目前为止最简单的解决方案(y)我花了一个小时努力处理转换、上下文,这就是最终解决问题的方法。