StackOverflow上有几个问题涉及图像翻转,例如here。默认情况下,iOS会在拍摄照片时反转前置摄像头水平图像。我试图防止前置摄像头图像被翻转或将其翻转回正确的方向。我正在与WKWebview
进行互动。
问题在于我不知道在我的ViewController
中调用或放入什么方法来获取相机,然后将其设置为正确的方向或正确的设置以防止此行为。我也不知道如何获取拍摄图像的相机信息。
这是我尝试的一种解决方案,它基于翻译一些Objective-C代码,在相机完成照片后更改图像。但是图片变量是常量,无法更改:
func didTakePicture(_ picture: UIImage) {
var flippedImage = UIImage(cgImage: picture.cgImage!, scale: picture.scale, orientation: .leftMirrored)
picture = flippedImage
}
非常感谢任何帮助。谢谢!
答案 0 :(得分:12)
您正在正确翻转图像,但为什么要将翻转的图像分配回picture
变量,您可以使用flippedImage
变量并将其传递到需要的位置。
func didTakePicture(_ picture: UIImage) {
var flippedImage = UIImage(CGImage: picture.CGImage!, scale: picture.scale, orientation: .leftMirrored)
// Here you have got flipped image you can pass it wherever you are using image
}
我要做的是仅防止前置摄像头图像 被翻转
如果使用默认相机,则无法防止相机阻止翻转图像。要做到这一点,您需要使用AVFoundation创建自己的相机,并需要在那里应用您的逻辑。
如果您准备使用任何三方图书馆,则可以查看LEMirroredImagePicker
答案 1 :(得分:3)
之前我遇到过这个问题。老实说,我不完全理解它,但这就是我的问题,它可能与你的问题有关:
正在发生的事情是iPhone相机(可能由于某些硬件原因)并不总是以正确的方向保存图像数据。根据iPhone型号和相机的不同,它们可以上下颠倒,侧面保存,和/或甚至可以在一个或两个轴上翻转。每当你在iPhone上拍照时,它有时会通过应用EXIF转换元数据来反转它来“纠正”这一点。
在转换的情况下,EXIF元数据告诉如何在打开数据后旋转和翻转数据。我猜这个存在的原因是因为将EXIF转换元数据应用于图像而不是将实际图像数据转换为内存会更便宜。
这有时会出现问题,因为在iOS中显示图像的所有内容都不会影响转换元数据。这可能发生在WKWebview上。它可能是在不检查EXIF数据进行转换的情况下显示图像。
我在过去构建一些图像处理应用时遇到了这个问题。虽然我没有为您提供任何简单的修复,但我的解决方法如下:1)首先从UIImage中删除所有EXIF转换数据。这在计算上更加昂贵,但IMO值得,因为它使图像更容易处理,您不必担心不处理EXIF数据的事情。 2)如果iPhone相机以不合适的方向保存图像,则以正确的方式正确转换图像。
这些可能是一个开始的好地方
剥离EXIF:
https://stackoverflow.com/a/34161629/4102858,
https://stackoverflow.com/a/25595495/4102858
UIImage转换:
https://stackoverflow.com/a/29753437/4102858
这些可能不适合您,但希望它们可以帮助您更好地理解您的问题。
答案 2 :(得分:2)
试试这个:
if captureDevice.position == AVCaptureDevicePosition.back {
if let image = context.createCGImage(ciImage, from: imageRect) {
return UIImage(cgImage: image, scale: UIScreen.main.scale, orientation: .right)
}
}
if captureDevice.position == AVCaptureDevicePosition.front {
if let image = context.createCGImage(ciImage, from: imageRect) {
return UIImage(cgImage: image, scale: UIScreen.main.scale, orientation: .leftMirrored)
}
}
答案 3 :(得分:1)
首先获取设备型号 扩展以检查UIDevice的设备模型 link
import UIKit
public extension UIDevice {
var modelName: String {
var systemInfo = utsname()
uname(&systemInfo)
let machineMirror = Mirror(reflecting: systemInfo.machine)
let identifier = machineMirror.children.reduce("") { identifier, element in
guard let value = element.value as? Int8 where value != 0 else { return identifier }
return identifier + String(UnicodeScalar(UInt8(value)))
}
switch identifier {
case "iPod5,1": return "iPod Touch 5"
case "iPod7,1": return "iPod Touch 6"
case "iPhone3,1", "iPhone3,2", "iPhone3,3": return "iPhone 4"
case "iPhone4,1": return "iPhone 4s"
case "iPhone5,1", "iPhone5,2": return "iPhone 5"
case "iPhone5,3", "iPhone5,4": return "iPhone 5c"
case "iPhone6,1", "iPhone6,2": return "iPhone 5s"
case "iPhone7,2": return "iPhone 6"
case "iPhone7,1": return "iPhone 6 Plus"
case "iPhone8,1": return "iPhone 6s"
case "iPhone8,2": return "iPhone 6s Plus"
case "iPhone9,1", "iPhone9,3": return "iPhone 7"
case "iPhone9,2", "iPhone9,4": return "iPhone 7 Plus"
case "iPhone8,4": return "iPhone SE"
case "iPad2,1", "iPad2,2", "iPad2,3", "iPad2,4":return "iPad 2"
case "iPad3,1", "iPad3,2", "iPad3,3": return "iPad 3"
case "iPad3,4", "iPad3,5", "iPad3,6": return "iPad 4"
case "iPad4,1", "iPad4,2", "iPad4,3": return "iPad Air"
case "iPad5,3", "iPad5,4": return "iPad Air 2"
case "iPad2,5", "iPad2,6", "iPad2,7": return "iPad Mini"
case "iPad4,4", "iPad4,5", "iPad4,6": return "iPad Mini 2"
case "iPad4,7", "iPad4,8", "iPad4,9": return "iPad Mini 3"
case "iPad5,1", "iPad5,2": return "iPad Mini 4"
case "iPad6,3", "iPad6,4", "iPad6,7", "iPad6,8":return "iPad Pro"
case "AppleTV5,3": return "Apple TV"
case "i386", "x86_64": return "Simulator"
default: return identifier
}
}
}
您可以这样称呼:
let modelName = UIDevice.currentDevice().modelName
逻辑是检查图像分辨率。我们可以通过以下代码获取图像的height
和width
,并检查FaceTime(前置)相机的分辨率:
主要代码块
//Getting model Name
let modelName = UIDevice.currentDevice().modelName
//Getting the height and the width of the image captured. The apple devices either have a 7 MP,5 MP front camera or a 1.2 MP front camera.
let heightInPoints = image.size.height
let heightInPixels = heightInPoint * image.scale
let widthInPoints = image.size.width
let widthInPixels = widthInPoints * image.scale
//Checking for 7 megapixel
//3,072 x 2304 or 3180x2375 (Sorry I am not sure about the exact resolution)
if (heightInPixels == 2304 && widthInPixels== 3,072)
{
var flippedImage = UIImage(cgImage: picture.cgImage!, scale: picture.scale, orientation: .leftMirrored)
}
//Checking for 5 megapixel
//2592 x 1936 resolution
if (heightInPixels == 1944 && widthInPixels== 2592)
{
if (modelName == "iPad Mini 2" || modelName == "iPad Mini 3" || modelName == "iPad Air" || modelName == "iPad 4")
{
print ("iPad models with 5mp back camera")
}
else
{
var flippedImage = UIImage(cgImage: picture.cgImage!, scale: picture.scale, orientation: .leftMirrored)
}
}
//Checking for 1.2 MP camera
//1200 x 780 pixels 2MP resolution for iPhone 6/6+/someipad Models they have a 1.2MP camera
//No apple iDevice has a main camera below this resolution
else if (heightInPixels == 780 && widthInPixel == 1200)
{
var flippedImage = UIImage(cgImage: picture.cgImage!, scale: picture.scale, orientation: .leftMirrored)
}
希望这有帮助。
答案 4 :(得分:0)
我知道这个问题已经回答了,但是我认为人们可能会发现下面的链接有用。
摄像机图像始终是横向的,但包含指示捕获时设备方向的元数据方向字段。
不幸的是,有些观众没有阅读此字段并旋转图像。
一种不错的方法是读取此变量并相应地旋转图像。
代码是从这里获取的-https://github.com/nativ18/Swift-Extensions/blob/master/UIImage%2BExtensions
extension UIImage {
func alignOrientationMetadataAndSize() -> UIImage? {
let landscapeMetadata = imageOrientation == .left || imageOrientation == .leftMirrored || imageOrientation == .right || imageOrientation == .rightMirrored
let landscapeSize = size.width > size.height
switch (landscapeSize, landscapeMetadata) {
case (false, true), (true, false):
var newSize = CGSize(width: size.height, height: size.width)
// Trim off the extremely small float value to prevent core graphics from rounding it up
newSize.width = floor(newSize.width)
newSize.height = floor(newSize.height)
UIGraphicsBeginImageContextWithOptions(newSize, false, self.scale)
let context = UIGraphicsGetCurrentContext()!
context.translateBy(x: newSize.width/2, y: newSize.height/2)
self.draw(in: CGRect(x: -self.size.width/2, y: -self.size.height/2, width: self.size.width, height: self.size.height))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
default:
return self
}
}
}