我有一个选择器,可以访问照片/视频库,但是我的问题是,当视频为人像时,视频的宽度和高度会颠倒。 我写了一个补丁来检查视频的大小,当宽度大于高度时,它会旋转它。但是很明显,它不能用于肖像以外的其他视频。
是否可以访问视频的方向?或其他任何解决此问题的方法将受到欢迎。
这是我的adPicker方法,imagePicker(didFinishPickingMediaWithInfo :)委托方法和getFramesFromVideo(fileUrl :)方法的代码:
@objc func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage{
editableView.drawnImage.image = image
initialVC.updateState(newState: .photoAdded)
initialVC.viewUpdater.updateContainerHeight()
}
else if let videoUrl = info[UIImagePickerControllerMediaURL] as? URL
{
imageManager.getFramesFromVideo(fileURL: videoUrl)
}
initialVC.dismiss(animated: true, completion: nil)
}
func addPicker()->UIAlertController{
let myAlert = UIAlertController()
guard let imagePicker = self.initialVC.imagePicker else {
fatalError()
return myAlert
}
for type in alertTypes{
let alertText = type == .photoGallery ? AlertText.typeGalery : type == .camera ? AlertText.typeCamera : type == .video ? AlertText.typeVideo : AlertText.typeCancel
myAlert.title = AlertText.title
myAlert.message = ""
let cameraAction = UIAlertAction(title : alertText, style : .default) { (action) in
imagePicker.delegate = self
imagePicker.allowsEditing = false
//type photo gallery
if type == .photoGallery && UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
imagePicker.sourceType = .photoLibrary
self.initialVC.present(imagePicker, animated: true, completion: nil)
}
//type camera
if type == .camera && UIImagePickerController.isSourceTypeAvailable(.camera) {
imagePicker.sourceType = .camera
self.initialVC.present(imagePicker, animated: true, completion: nil)
}
if type == .video {
imagePicker.mediaTypes = [String(kUTTypeMovie)]
imagePicker.videoQuality = .typeHigh
imagePicker.videoMaximumDuration = VideoTime.maxDuration
self.initialVC.present(imagePicker, animated: true, completion: nil)
}
if type == .cancel {
self.initialVC.dismiss(animated: true, completion: nil)
}
}
myAlert.addAction(cameraAction)
}
return myAlert
}
func getFramesFromVideo(fileURL: URL){
let asset = AVURLAsset(url: fileURL, options: nil)
let videoDuration = asset.duration
print(asset.metadata)
let generator = AVAssetImageGenerator(asset: asset)
generator.requestedTimeToleranceAfter = kCMTimeZero
generator.requestedTimeToleranceBefore = kCMTimeZero
var imageError : Error?
frameForTimes = [NSValue]()
let totalTimeLength = Int(videoDuration.seconds * Double(videoDuration.timescale))
let step = totalTimeLength / VideoTime.maxSampleCounts
for i in 0 ..< VideoTime.maxSampleCounts {
let cmTime = CMTimeMake(Int64(i * step), Int32(videoDuration.timescale))
frameForTimes.append(NSValue(time: cmTime))
}
generator.generateCGImagesAsynchronously(forTimes: frameForTimes, completionHandler: {requestedTime, image, actualTime, result, error in
DispatchQueue.main.async {
guard imageError == nil else {return}
if let image = image {
if self.tempImages.count != self.frameForTimes.count //avoid crash
{
self.videoFrameDelegate?.fillFramesFromVideo(frame: UIImage(cgImage: image))
self.tempImages.updateValue(self.frameForTimes[self.tempImages.count] as! CMTime, forKey: UIImage(cgImage: image))
print("image \(actualTime.seconds) loaded")
}
}
else if (error != nil) {
imageError = error
//TODO: Error handler
generator.cancelAllCGImageGeneration()
self.tempImages.removeAll()
self.videoFrameDelegate?.removeFrames()
print(error as Any)
}
// Completion handler
if self.tempImages.count == self.frameForTimes.count
{
print("frames ended loading")
self.tempImages.removeAll()
self.frameForTimes.removeAll()
self.videoFrameDelegate?.loadFrames()
}
}
})
}
答案 0 :(得分:0)
找到了具有以下属性的解决方案:videoTrack.preferredTransform
▿ CGAffineTransform
- a : 0.0
- b : 1.0
- c : -1.0
- d : 0.0
- tx : 360.0
- ty : 0.0
当tx带有值时,表示视频已旋转。使用简单的if else
可以旋转视频的图像(如果已旋转),将解决此问题:
extension UIImage {
func imageRotatedByDegrees(oldImage: UIImage, deg degrees: CGFloat) -> UIImage {
//Calculate the size of the rotated view's containing box for our drawing space
let rotatedViewBox: UIView = UIView(frame: CGRect(x: 0, y: 0, width: oldImage.size.width, height: oldImage.size.height))
let t: CGAffineTransform = CGAffineTransform(rotationAngle: degrees * CGFloat.pi / 180)
rotatedViewBox.transform = t
let rotatedSize: CGSize = rotatedViewBox.frame.size
//Create the bitmap context
UIGraphicsBeginImageContext(rotatedSize)
let bitmap: CGContext = UIGraphicsGetCurrentContext()!
//Move the origin to the middle of the image so we will rotate and scale around the center.
bitmap.translateBy(x: rotatedSize.width / 2, y: rotatedSize.height / 2)
//Rotate the image context
bitmap.rotate(by: (degrees * CGFloat.pi / 180))
//Now, draw the rotated/scaled image into the context
bitmap.scaleBy(x: 1.0, y: -1.0)
bitmap.draw(oldImage.cgImage!, in: CGRect(x: -oldImage.size.width / 2, y: -oldImage.size.height / 2, width: oldImage.size.width, height: oldImage.size.height))
let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return newImage
}
}
希望它将对某人有所帮助