Having similar problem here.
When using front camera device and recording live photos final Live Photo is flipped horizontally.
If i manually flip it I get error when saving to gallery.
Error Domain=PHPhotosErrorDomain Code=-1 "(null)"
I need to use UIImage or CIImage to flip it and then i use png, jpeg or heic data as stillImageData. Whatever data i use, unless it is photo.fileDataRepresentation, it won't work.
If i use just photo.fileDataRepresentation() as imageStillData it works but image is flipped (orientation is wrong makes face look weird).
How to fix this?
Here is code.
extension CameraInput: AVCapturePhotoCaptureDelegate {
public func photoOutput(_: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: (any Error)?) {
guard error == nil else {
Log.error("Error capturing photo: \(error!)")
return
}
guard let data = photo.fileDataRepresentation(),
let sourceImage = UIImage(data: data)
else {
Log.error("Failed to capture photo data")
return
}
if #available(iOS 17.0, *) {
self.stillImageData = sourceImage.heicData() ?? sourceImage.pngData() ?? sourceImage.jpegData(compressionQuality: 1.0)
} else {
self.stillImageData = sourceImage.pngData() ?? sourceImage.jpegData(compressionQuality: 1.0)
}
// Flip Image Horizontally
let flippedImage = UIImage(
cgImage: sourceImage.cgImage!,
scale: sourceImage.scale,
orientation: .leftMirrored
)
DispatchQueue.main.async {
self.delegate?.didFinishCreating(image: flippedImage)
}
}
public func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingLivePhotoToMovieFileAt outputFileURL: URL, duration: CMTime, photoDisplayTime: CMTime, resolvedSettings: AVCaptureResolvedPhotoSettings, error: (any Error)?) {
if let error {
Log.info("THERE WAS AN ERROR CREATING A LIVE PHOTO TO MOVIE FILE: \(error)")
} else {
Log.info("Finished processing live photo to movie file")
guard let stillImageData else {
Log.error("There is no image data for live photo.")
return
}
// Save to Gallery
PHPhotoLibrary.shared().performChanges(
{
// Add the captured photo's file data as the main resource for the Photos asset.
let creationRequest = PHAssetCreationRequest.forAsset()
creationRequest.addResource(with: .photo, data: stillImageData, options: nil)
// Add the movie file URL as the Live Photo's paired video resource.
let options = PHAssetResourceCreationOptions()
options.shouldMoveFile = true
creationRequest.addResource(with: .pairedVideo, fileURL: outputFileURL, options: options)
}) { _, error in
if let error {
Log.info("CANNOT SAVE LIVE PHOTO TO GALLERY, ERROR \(error)")
} else {
Log.info("SAVED LIVE PHOTO TO GALLERY")
}
}
}
}
}