- Approach.1 - Use CIImage.init(data:)
- ⚠️ Caution
- Approach.2 - Use CIFilter(data: options:)
- Write to file as JPEG
- How to get image-orientation
- Resources
Approach.1 - Use CIImage.init(data:)
let rawImageData: Data = ...
let image: CIImage? = CIImage(data: rawImageData)
This approach won't fix image orientation.
To fix it needs to get the image orientation from EXIF using ImageIO.
Then, using CIImage.oriented
fixes the orientation issue.
⚠️ Caution
As this tweet says, this initializer might create a CIImage that uses a pre-rendered image in the RAW image file. which means, you might get a low-resolution image. If the preview image is not there, I suspect CoreImage renders at the time.
Approach.2 - Use CIFilter(data: options:)
let rawImageData: Data = ...
let filter = CIFilter(imageData: rawImageData, options: [:])!
let ciImage: CIImage = filter.outputImage
This approach won't work on iOS Simulator. CIFilter.outputImage returns nil
.
This approach renders bitmap image from RAW data with options. Actually that CIFilter is CIRawFilter implicitly. To convert to UIImage:
UIImage(ciImage: ciImage)
However, this approach might take a cost of processing in displaying UI.
e.g UIScrollView's zooming.
And, that UIImage instance won't return cgImage
.
Then, to get better performance in UIKit, creating UIImage from CGImage
rendered by CIContext
.
let ciContext = CIContext()
let cgImage = ciContext.createCGImage(image, from: image.extent)!
let image = UIImage(cgImage: cgImage)
Write to file as JPEG
let ciContext = CIContext()
let target = URL(fileURLWithPath: NSTemporaryDirectory() + "/raw_image.jpeg")
try! ciContext.writeJPEGRepresentation(of: image, to: target, colorSpace: image.colorSpace ?? CGColorSpaceCreateDeviceRGB(), options: [:])
How to get image-orientation
As well as
let rawImageData: Data = ...
let source = CGImageSourceCreateWithURL(data as CFData, nil)!
func readOrientation(from imageSource: CGImageSource) -> CGImagePropertyOrientation? {
let propertiesOptions = [kCGImageSourceShouldCache: false] as CFDictionary
guard
let properties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, propertiesOptions)
as? [CFString: Any]
else {
return nil
}
let _orientation: CGImagePropertyOrientation? =
(properties[kCGImagePropertyTIFFOrientation] as? UInt32).flatMap {
CGImagePropertyOrientation(rawValue: $0)
}
guard
let orientation = _orientation
else {
return nil
}
return orientation
}