Created
December 15, 2024 09:20
-
-
Save bogdan/014874273cc30a1616bc187d88f38340 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extension CameraManagerPhotoOutput: @preconcurrency AVCapturePhotoCaptureDelegate { | |
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: (any Error)?) { | |
guard let imageData = photo.fileDataRepresentation(), | |
let ciImage = CIImage(data: imageData) | |
else { return } | |
// Retrieve metadata from AVCapturePhoto | |
var metadata = photo.metadata | |
// Process the CIImage with filters | |
let capturedCIImage = prepareCIImage(ciImage, parent.attributes.cameraFilters) | |
// Convert back to CGImage | |
guard let capturedCGImage = prepareCGImage(capturedCIImage) else { return } | |
// Convert to UIImage while preserving orientation | |
guard let capturedUIImage = prepareUIImage(capturedCGImage) else { return } | |
// Add orientation metadata | |
if let orientationValue = metadata[kCGImagePropertyOrientation as String] as? NSNumber { | |
metadata[kCGImagePropertyOrientation as String] = orientationValue | |
} | |
// Re-embed metadata into the final image data | |
guard let finalImageData = createImageDataWithMetadata(image: capturedUIImage, metadata: metadata) else { return } | |
// Wrap final data and pass it to the parent | |
let capturedMedia = MCameraMedia(data: finalImageData) | |
parent.setCapturedMedia(capturedMedia) | |
} | |
} | |
private extension CameraManagerPhotoOutput { | |
func prepareCIImage(_ ciImage: CIImage, _ filters: [CIFilter]) -> CIImage { | |
ciImage.applyingFilters(filters) | |
} | |
func prepareCGImage(_ ciImage: CIImage) -> CGImage? { | |
CIContext().createCGImage(ciImage, from: ciImage.extent) | |
} | |
func prepareUIImage(_ cgImage: CGImage?) -> UIImage? { | |
guard let cgImage else { return nil } | |
let frameOrientation = getFixedFrameOrientation() | |
let orientation = UIImage.Orientation(frameOrientation) | |
let uiImage = UIImage(cgImage: cgImage, scale: 1.0, orientation: orientation) | |
return uiImage | |
} | |
/// Embeds metadata into image data | |
func createImageDataWithMetadata(image: UIImage, metadata: [String: Any]) -> Data? { | |
guard let cgImage = image.cgImage else { return nil } | |
// Create a CFData representation of the image | |
let imageData = NSMutableData() | |
guard let destination = CGImageDestinationCreateWithData(imageData, kUTTypeJPEG, 1, nil) else { return nil } | |
// Embed the CGImage and metadata | |
CGImageDestinationAddImage(destination, cgImage, metadata as CFDictionary) | |
CGImageDestinationFinalize(destination) | |
return imageData as Data | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment