Skip to content

Instantly share code, notes, and snippets.

@bogdan
Created December 15, 2024 09:20
Show Gist options
  • Save bogdan/d9d75b522aca231c802ff0b4ecd0c35c to your computer and use it in GitHub Desktop.
Save bogdan/d9d75b522aca231c802ff0b4ecd0c35c to your computer and use it in GitHub Desktop.
test.swift
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