2023-03-24 18:44:16 +01:00
|
|
|
//
|
|
|
|
// https://mczachurski.dev
|
|
|
|
// Copyright © 2023 Marcin Czachurski and the repository contributors.
|
2023-03-28 10:35:38 +02:00
|
|
|
// Licensed under the Apache License 2.0.
|
2023-03-24 18:44:16 +01:00
|
|
|
//
|
2023-04-01 12:10:59 +02:00
|
|
|
|
2023-03-24 18:44:16 +01:00
|
|
|
import SwiftUI
|
|
|
|
|
|
|
|
extension UIImage {
|
|
|
|
public func getJpegData() -> Data? {
|
|
|
|
#if targetEnvironment(simulator)
|
|
|
|
// For testing purposes.
|
|
|
|
let converted = self.convertToExtendedSRGBJpeg()
|
|
|
|
let filePath = URL.temporaryDirectory.appending(path: "\(UUID().uuidString).jpg")
|
|
|
|
try? converted?.write(to: filePath)
|
|
|
|
print(filePath.string)
|
|
|
|
#endif
|
2023-04-01 12:10:59 +02:00
|
|
|
|
2023-03-24 18:44:16 +01:00
|
|
|
// API don't support images over 5K.
|
|
|
|
if self.size.height > 10_000 || self.size.width > 10_000 {
|
|
|
|
return self
|
|
|
|
.resized(to: .init(width: self.size.width / 4, height: self.size.height / 4))
|
|
|
|
.convertToExtendedSRGBJpeg()
|
|
|
|
} else if self.size.height > 5000 || self.size.width > 5000 {
|
|
|
|
return self
|
|
|
|
.resized(to: .init(width: self.size.width / 2, height: self.size.height / 2))
|
|
|
|
.convertToExtendedSRGBJpeg()
|
|
|
|
} else {
|
|
|
|
return self
|
|
|
|
.convertToExtendedSRGBJpeg()
|
|
|
|
}
|
|
|
|
}
|
2023-04-01 12:10:59 +02:00
|
|
|
|
2023-03-24 18:44:16 +01:00
|
|
|
public func convertToExtendedSRGBJpeg() -> Data? {
|
|
|
|
guard let sourceImage = CIImage(image: self, options: [.applyOrientationProperty: true]) else {
|
|
|
|
return self.jpegData(compressionQuality: 0.9)
|
|
|
|
}
|
2023-04-01 12:10:59 +02:00
|
|
|
|
2023-03-24 18:44:16 +01:00
|
|
|
// We have to store correct image orientation.
|
|
|
|
let orientedImage = sourceImage.oriented(forExifOrientation: self.imageOrientation.exifOrientation)
|
2023-04-01 12:10:59 +02:00
|
|
|
|
2023-03-24 18:44:16 +01:00
|
|
|
// We dont have to convert images which already are in sRGB color space.
|
|
|
|
if orientedImage.colorSpace?.name == CGColorSpace.sRGB || orientedImage.colorSpace?.name == CGColorSpace.extendedSRGB {
|
|
|
|
return self.jpegData(compressionQuality: 0.9)
|
|
|
|
}
|
2023-04-01 12:10:59 +02:00
|
|
|
|
2023-03-24 18:44:16 +01:00
|
|
|
guard let colorSpace = CGColorSpace(name: CGColorSpace.extendedSRGB) else {
|
|
|
|
return self.jpegData(compressionQuality: 0.9)
|
|
|
|
}
|
|
|
|
|
|
|
|
guard let displayP3 = CGColorSpace(name: CGColorSpace.displayP3) else {
|
|
|
|
return self.jpegData(compressionQuality: 0.9)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create Core Image context (with working color space).
|
|
|
|
let ciContext = CIContext(options: [CIContextOption.workingColorSpace: orientedImage.colorSpace ?? displayP3])
|
2023-04-01 12:10:59 +02:00
|
|
|
|
2023-03-24 18:44:16 +01:00
|
|
|
// Creating image with new color space (and preserving colors).
|
|
|
|
guard let converted = ciContext.jpegRepresentation(of: orientedImage, colorSpace: colorSpace) else {
|
|
|
|
return self.jpegData(compressionQuality: 0.9)
|
|
|
|
}
|
2023-04-01 12:10:59 +02:00
|
|
|
|
2023-03-24 18:44:16 +01:00
|
|
|
// Returning successfully converted image.
|
|
|
|
return converted
|
|
|
|
}
|
|
|
|
}
|