diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..269e896 Binary files /dev/null and b/.DS_Store differ diff --git a/Sources/.DS_Store b/Sources/.DS_Store new file mode 100644 index 0000000..76d86a0 Binary files /dev/null and b/Sources/.DS_Store differ diff --git a/Sources/SwiftyImageIO/.DS_Store b/Sources/SwiftyImageIO/.DS_Store new file mode 100644 index 0000000..e79d0bc Binary files /dev/null and b/Sources/SwiftyImageIO/.DS_Store differ diff --git a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+ColorSpace.swift b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+ColorSpace.swift index 2652570..642da8e 100644 --- a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+ColorSpace.swift +++ b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+ColorSpace.swift @@ -9,7 +9,7 @@ import Foundation public extension ExifProperty { - enum ColorSpace: Int, Codable, Hashable { + enum ColorSpace: Int, Codable, Hashable, Sendable { case sRGB = 0x1 case adobeRGB = 0x2 case wideGamutRGB = 0xfffd diff --git a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+CompositeImageType.swift b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+CompositeImageType.swift index 8958fde..3f3d863 100644 --- a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+CompositeImageType.swift +++ b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+CompositeImageType.swift @@ -9,7 +9,7 @@ import Foundation public extension ExifProperty { - enum CompositeImageType: Int, Codable, Hashable { + enum CompositeImageType: Int, Codable, Hashable, Sendable { case unknown = 0 case notCompositeImage = 1 case generalCompositeImage = 2 diff --git a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+ContrastDirection.swift b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+ContrastDirection.swift index 682f405..ed89654 100644 --- a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+ContrastDirection.swift +++ b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+ContrastDirection.swift @@ -9,7 +9,7 @@ import Foundation public extension ExifProperty { - enum ContrastDirection: Int, Codable, Hashable { + enum ContrastDirection: Int, Codable, Hashable, Sendable { case normal = 0 case soft = 1 case hard = 2 diff --git a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+CustomRenderedType.swift b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+CustomRenderedType.swift index f9fe4e8..951dc99 100644 --- a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+CustomRenderedType.swift +++ b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+CustomRenderedType.swift @@ -9,7 +9,7 @@ import Foundation public extension ExifProperty { - enum CustomRenderedType: Int, Codable, Hashable { + enum CustomRenderedType: Int, Codable, Hashable, Sendable { // MARK: - standard Exif case normal = 0 case custom = 1 diff --git a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+ExposureMode.swift b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+ExposureMode.swift index 94d714d..71dab8c 100644 --- a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+ExposureMode.swift +++ b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+ExposureMode.swift @@ -9,7 +9,7 @@ import Foundation public extension ExifProperty { - enum ExposureMode: Int, Codable, Hashable { + enum ExposureMode: Int, Codable, Hashable, Sendable { case autoExposure = 0 case manualExposure = 1 case autoBracket = 2 diff --git a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+ExposureProgram.swift b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+ExposureProgram.swift index ea18a1c..4a64b34 100644 --- a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+ExposureProgram.swift +++ b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+ExposureProgram.swift @@ -9,7 +9,7 @@ import Foundation public extension ExifProperty { - enum ExposureProgram: Int, Codable, Hashable { + enum ExposureProgram: Int, Codable, Hashable, Sendable { case notDefined = 0 case manual = 1 case normalProgram = 2 diff --git a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+FileSourceType.swift b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+FileSourceType.swift index a30730e..d879a23 100644 --- a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+FileSourceType.swift +++ b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+FileSourceType.swift @@ -9,7 +9,7 @@ import Foundation public extension ExifProperty { - enum FileSourceType: Int, Codable, Hashable { + enum FileSourceType: Int, Codable, Hashable, Sendable { case filmScanner = 1 case reflectionPrintScanner = 2 case digitalCamera = 3 diff --git a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+FlashMode.swift b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+FlashMode.swift index 3495d85..39661e5 100644 --- a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+FlashMode.swift +++ b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+FlashMode.swift @@ -9,7 +9,7 @@ import Foundation public extension ExifProperty { - enum FlashMode: Int, Codable, Hashable { + enum FlashMode: Int, Codable, Hashable, Sendable { case noFlash = 0x0 case fired = 0x1 case firedReturnNotDetected = 0x5 diff --git a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+GainControl.swift b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+GainControl.swift index 5470123..c5cc06b 100644 --- a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+GainControl.swift +++ b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+GainControl.swift @@ -9,7 +9,7 @@ import Foundation public extension ExifProperty { - enum GainControl: Int, Codable, Hashable { + enum GainControl: Int, Codable, Hashable, Sendable { case none = 0 case lowGainUp = 1 case highGainUp = 2 diff --git a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+LightSourceType.swift b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+LightSourceType.swift index 508ec19..bf8ce52 100644 --- a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+LightSourceType.swift +++ b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+LightSourceType.swift @@ -9,7 +9,7 @@ import Foundation public extension ExifProperty { - enum LightSourceType: Int, Codable, Hashable { + enum LightSourceType: Int, Codable, Hashable, Sendable { case unknown = 0 case daylight = 1 case fluorescent = 2 diff --git a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+MeteringMode.swift b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+MeteringMode.swift index c48f489..e464769 100644 --- a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+MeteringMode.swift +++ b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+MeteringMode.swift @@ -9,7 +9,7 @@ import Foundation public extension ExifProperty { - enum MeteringMode: Int, Codable, Hashable { + enum MeteringMode: Int, Codable, Hashable, Sendable { case unknown = 0 case average = 1 case centerWeightedAverage = 2 diff --git a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+PixelFormat.swift b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+PixelFormat.swift index 18db662..a13d89b 100644 --- a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+PixelFormat.swift +++ b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+PixelFormat.swift @@ -9,7 +9,7 @@ import Foundation public extension ExifProperty { - enum PixelFormatType: Int, Codable { + enum PixelFormatType: Int, Codable, Sendable { case blackWhite = 0x5 case _8BitGray = 0x8 diff --git a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+ResolutionUnit.swift b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+ResolutionUnit.swift index 6a9d4e7..0cd0664 100644 --- a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+ResolutionUnit.swift +++ b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+ResolutionUnit.swift @@ -9,7 +9,7 @@ import Foundation public extension ExifProperty { - enum ResolutionUnit: Int, Codable, Hashable { + enum ResolutionUnit: Int, Codable, Hashable, Sendable { case none = 1 case inches = 2 case cm = 3 diff --git a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+SaturationDirection.swift b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+SaturationDirection.swift index 8760abf..b677ef8 100644 --- a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+SaturationDirection.swift +++ b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+SaturationDirection.swift @@ -9,7 +9,7 @@ import Foundation public extension ExifProperty { - enum SaturationDirection: Int, Codable, Hashable { + enum SaturationDirection: Int, Codable, Hashable, Sendable { case normal = 0 case lowSaturation = 1 case highSaturation = 2 diff --git a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+SceneCaptureType.swift b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+SceneCaptureType.swift index 8b236d9..9fa58c1 100644 --- a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+SceneCaptureType.swift +++ b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+SceneCaptureType.swift @@ -9,7 +9,7 @@ import Foundation public extension ExifProperty { - enum SceneCaptureType: Int, Codable, Hashable { + enum SceneCaptureType: Int, Codable, Hashable, Sendable { case standard = 0 case landscape = 1 case portrait = 2 diff --git a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+SensingMethod.swift b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+SensingMethod.swift index 7e91d8b..22685f6 100644 --- a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+SensingMethod.swift +++ b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+SensingMethod.swift @@ -9,7 +9,7 @@ import Foundation public extension ExifProperty { - enum SensingMethod: Int, Codable, Hashable { + enum SensingMethod: Int, Codable, Hashable, Sendable { case notDefined = 1 case oneChipColorAreaSensor = 2 case twoChipColorAreaSensor = 3 diff --git a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+SensitivityType.swift b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+SensitivityType.swift index d29b910..5ca80e2 100644 --- a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+SensitivityType.swift +++ b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+SensitivityType.swift @@ -9,7 +9,7 @@ import Foundation public extension ExifProperty { - enum SensitivityType: Int, Codable, Hashable { + enum SensitivityType: Int, Codable, Hashable, Sendable { case unknown = 0 case standardOutputSensitivity = 1 case recommendedExposureIndex = 2 diff --git a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+SharpnessDirection.swift b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+SharpnessDirection.swift index 0fde3f4..bc83e8d 100644 --- a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+SharpnessDirection.swift +++ b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+SharpnessDirection.swift @@ -9,7 +9,7 @@ import Foundation public extension ExifProperty { - enum SharpnessDirection: Int, Codable, Hashable { + enum SharpnessDirection: Int, Codable, Hashable, Sendable { case normal = 0 case soft = 1 case hard = 2 diff --git a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+SubjectDistanceRangeType.swift b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+SubjectDistanceRangeType.swift index 73bb89a..0a59d41 100644 --- a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+SubjectDistanceRangeType.swift +++ b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+SubjectDistanceRangeType.swift @@ -9,7 +9,7 @@ import Foundation public extension ExifProperty { - enum SubjectDistanceRangeType: Int, Codable, Hashable { + enum SubjectDistanceRangeType: Int, Codable, Hashable, Sendable { case unknown = 0 case macro = 1 case closeView = 2 diff --git a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+WhiteBalanceMode.swift b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+WhiteBalanceMode.swift index f486a08..7f713e6 100644 --- a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+WhiteBalanceMode.swift +++ b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty+WhiteBalanceMode.swift @@ -9,7 +9,7 @@ import Foundation public extension ExifProperty { - enum WhiteBalanceMode: Int, Codable, Hashable { + enum WhiteBalanceMode: Int, Codable, Hashable, Sendable { case autoWhiteBalance = 0 case manualWhiteBalance = 1 } diff --git a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty.swift b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty.swift index 2fd83b6..062b246 100644 --- a/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty.swift +++ b/Sources/SwiftyImageIO/CodableEntities/Exif/ExifProperty.swift @@ -6,12 +6,12 @@ // // -import AnyCodable +@preconcurrency import AnyCodable import Foundation import ImageIO /// Exchangeable Image File Format (EXIF) data. -public struct ExifProperty: Codable, Equatable, Hashable { +public struct ExifProperty: Codable, Equatable, Hashable, Sendable { // MARK: - Camera Settings /// For a particular camera mode, indicates the conditions for taking the picture. @@ -36,7 +36,7 @@ public struct ExifProperty: Codable, Equatable, Hashable { public var spectralSensitivity: Double? /// The ISO speed ratings. - public var isoSpeedRatings: [AnyCodable]? + public var isoSpeedRatings: [Int]? /// The distance to the subject, in meters. public var subjectDistance: Double? @@ -253,4 +253,83 @@ public struct ExifProperty: Codable, Equatable, Hashable { /// The EXIF version. public var exifVersion: [Int]? + + init?(dictionary: Any?) { + guard let dictionary = dictionary as? [String : Any] else { return nil } + self.deviceSettingDescription = dictionary[""] as? AnyCodable + self.fNumber = dictionary[kCGImagePropertyExifFNumber as String] as? Double + self.shutterSpeedValue = dictionary[kCGImagePropertyExifShutterSpeedValue as String] as? Double + self.apertureValue = dictionary[kCGImagePropertyExifApertureValue as String] as? Double + self.maxApertureValue = dictionary[kCGImagePropertyExifMaxApertureValue as String] as? Double + self.focalLength = dictionary[kCGImagePropertyExifFocalLength as String] as? Double + self.spectralSensitivity = dictionary[kCGImagePropertyExifSpectralSensitivity as String] as? Double + self.isoSpeedRatings = dictionary[kCGImagePropertyExifISOSpeedRatings as String] as? [Int] + self.subjectDistance = dictionary[kCGImagePropertyExifSubjectDistance as String] as? Double + self.meteringMode = dictionary[kCGImagePropertyExifMeteringMode as String] as? MeteringMode + self.subjectArea = dictionary[kCGImagePropertyExifSubjectArea as String] as? AnyCodable + self.subjectLocation = dictionary[kCGImagePropertyExifSubjectLocation as String] as? AnyCodable + self.sensingMethod = dictionary[kCGImagePropertyExifSensingMethod as String] as? SensingMethod + self.sceneType = dictionary[kCGImagePropertyExifSceneType as String] as? Int + self.digitalZoomRatio = dictionary[kCGImagePropertyExifDigitalZoomRatio as String] as? Double + self.focalLengthIn35mmFilm = dictionary[kCGImagePropertyExifFocalLenIn35mmFilm as String] as? Double + self.sceneCaptureType = dictionary[kCGImagePropertyExifSceneCaptureType as String] as? SceneCaptureType + self.subjectDistanceRange = dictionary[kCGImagePropertyExifSubjectDistRange as String] as? SubjectDistanceRangeType + self.exposureTime = dictionary[kCGImagePropertyExifExposureTime as String] as? TimeInterval + self.exposureProgram = dictionary[kCGImagePropertyExifExposureProgram as String] as? ExposureProgram + self.exposureIndex = dictionary[kCGImagePropertyExifExposureIndex as String] as? Int + self.exposureMode = dictionary[kCGImagePropertyExifExposureMode as String] as? ExposureMode + self.isoSpeed = dictionary[kCGImagePropertyExifISOSpeed as String] as? AnyCodable + self.isoSpeedLatitudeYYY = dictionary[kCGImagePropertyExifISOSpeedLatitudeyyy as String] as? AnyCodable + self.isoSpeedLatitudeZZZ = dictionary[kCGImagePropertyExifISOSpeedLatitudezzz as String] as? AnyCodable + self.recommendedExposureIndex = dictionary[kCGImagePropertyExifRecommendedExposureIndex as String] as? Int + self.exposureBiasValue = dictionary[kCGImagePropertyExifExposureBiasValue as String] as? Double + self.sensitivityType = dictionary[kCGImagePropertyExifSensitivityType as String] as? SensitivityType + self.standardOutputSensitivity = dictionary[kCGImagePropertyExifStandardOutputSensitivity as String] as? UInt + self.sourceExposureTimesOfCompositeImage = dictionary[kCGImagePropertyExifSourceExposureTimesOfCompositeImage as String] as? AnyCodable + self.cfaPattern = dictionary[kCGImagePropertyExifCFAPattern as String] as? AnyCodable + self.brightnessValue = dictionary[kCGImagePropertyExifBrightnessValue as String] as? Double + self.lightSource = dictionary[kCGImagePropertyExifLightSource as String] as? LightSourceType + self.flash = dictionary[kCGImagePropertyExifFlash as String] as? FlashMode + self.spatialFrequencyResponse = dictionary[kCGImagePropertyExifSpatialFrequencyResponse as String] as? String + self.contrast = dictionary[kCGImagePropertyExifContrast as String] as? ContrastDirection + self.saturation = dictionary[kCGImagePropertyExifSaturation as String] as? SaturationDirection + self.sharpness = dictionary[kCGImagePropertyExifSharpness as String] as? SharpnessDirection + self.gamma = dictionary[kCGImagePropertyExifGamma as String] as? GammaCoefficient + self.whiteBalance = dictionary[kCGImagePropertyExifWhiteBalance as String] as? WhiteBalanceMode + self.gainControl = dictionary[kCGImagePropertyExifGainControl as String] as? GainControl + self.imageUniqueId = dictionary[kCGImagePropertyExifImageUniqueID as String] as? String + self.compressedBitsPerPixel = dictionary[kCGImagePropertyExifCompressedBitsPerPixel as String] as? Double + self.colorSpace = dictionary[kCGImagePropertyExifColorSpace as String] as? ColorSpace + self.pixelXDimension = dictionary[kCGImagePropertyExifPixelXDimension as String] as? UInt + self.pixelYDimension = dictionary[kCGImagePropertyExifPixelYDimension as String] as? UInt + self.relatedSoundFile = dictionary[kCGImagePropertyExifRelatedSoundFile as String] as? String + self.focalPlaneXResolution = dictionary[kCGImagePropertyExifFocalPlaneXResolution as String] as? Double + self.focalPlaneYResolution = dictionary[kCGImagePropertyExifFocalPlaneYResolution as String] as? Double + self.focalPlaneResolutionUnit = dictionary[kCGImagePropertyExifFocalPlaneResolutionUnit as String] as? ResolutionUnit + self.customRendered = dictionary[kCGImagePropertyExifCustomRendered as String] as? CustomRenderedType + self.compositeImage = dictionary[kCGImagePropertyExifCompositeImage as String] as? CompositeImageType + self.oecf = dictionary[kCGImagePropertyExifOECF as String] as? AnyCodable + self.componentsConfiguration = dictionary[kCGImagePropertyExifComponentsConfiguration as String] as? [Int] + self.sourceImageNumberOfCompositeImage = dictionary[kCGImagePropertyExifSourceImageNumberOfCompositeImage as String] as? [Int] + self.fileSource = dictionary[kCGImagePropertyExifFileSource as String] as? FileSourceType + self.dateTimeOriginal = dictionary[kCGImagePropertyExifDateTimeOriginal as String] as? Date + self.dateTimeDigitized = dictionary[kCGImagePropertyExifDateTimeDigitized as String] as? Date + self.subsecTime = dictionary[kCGImagePropertyExifSubsecTime as String] as? String + self.subsecTimeOriginal = dictionary[kCGImagePropertyExifSubsecTimeOriginal as String] as? String + self.subsecTimeDigitized = dictionary[kCGImagePropertyExifSubsecTimeDigitized as String] as? String + self.offsetTime = dictionary[kCGImagePropertyExifOffsetTime as String] as? String + self.offsetTimeOriginal = dictionary[kCGImagePropertyExifOffsetTimeOriginal as String] as? String + self.offsetTimeDigitized = dictionary[kCGImagePropertyExifOffsetTimeDigitized as String] as? String + self.lensSpecification = dictionary[kCGImagePropertyExifLensSpecification as String] as? [Double] + self.lensMake = dictionary[kCGImagePropertyExifLensMake as String] as? String + self.lensModel = dictionary[kCGImagePropertyExifLensModel as String] as? String + self.lensSerialNumber = dictionary[kCGImagePropertyExifLensSerialNumber as String] as? String + self.makerNote = dictionary[kCGImagePropertyExifMakerNote as String] as? AnyCodable + self.userComment = dictionary[kCGImagePropertyExifUserComment as String] as? String + self.cameraOwnerName = dictionary[kCGImagePropertyExifCameraOwnerName as String] as? String + self.bodySerialNumber = dictionary[kCGImagePropertyExifBodySerialNumber as String] as? String + self.flashpixVersion = dictionary[kCGImagePropertyExifFlashPixVersion as String] as? [Int] + self.flashEnergy = dictionary[kCGImagePropertyExifFlashEnergy as String] as? Int + self.exifVersion = dictionary[kCGImagePropertyExifVersion as String] as? [Int] + } } diff --git a/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+AltitudeRef.swift b/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+AltitudeRef.swift index ae23658..2fb0100 100644 --- a/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+AltitudeRef.swift +++ b/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+AltitudeRef.swift @@ -9,7 +9,7 @@ import Foundation public extension GPSProperty { - enum AltitudeRef: UInt8, Codable { + enum AltitudeRef: UInt8, Codable, Sendable { case aboveSeaLevel = 0 case belowSeaLevel = 1 } diff --git a/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+BearingRef.swift b/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+BearingRef.swift index 136f3da..acd469e 100644 --- a/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+BearingRef.swift +++ b/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+BearingRef.swift @@ -9,7 +9,7 @@ import Foundation public extension GPSProperty { - enum BearingRef: String, Codable { + enum BearingRef: String, Codable, Sendable { case magneticNorth = "M" case trueNorth = "T" } diff --git a/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+Differential.swift b/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+Differential.swift index a368347..f98689a 100644 --- a/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+Differential.swift +++ b/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+Differential.swift @@ -9,7 +9,7 @@ import Foundation public extension GPSProperty { - enum Differential: UInt16, Codable { + enum Differential: UInt16, Codable, Sendable { case noCorrection = 0 case corrected = 1 } diff --git a/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+DirectionRef.swift b/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+DirectionRef.swift index a572408..191eaf6 100644 --- a/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+DirectionRef.swift +++ b/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+DirectionRef.swift @@ -9,7 +9,7 @@ import Foundation public extension GPSProperty { - enum DirectionRef: String, Codable { + enum DirectionRef: String, Codable, Sendable { case magneticNorth = "M" case trueNorth = "T" } diff --git a/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+DistanceLengthUnit.swift b/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+DistanceLengthUnit.swift index b35095f..2c9d9d2 100644 --- a/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+DistanceLengthUnit.swift +++ b/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+DistanceLengthUnit.swift @@ -9,7 +9,7 @@ import Foundation public extension GPSProperty { - enum DistanceLengthUnit: String, Codable { + enum DistanceLengthUnit: String, Codable, Sendable { case kilometers = "K" case miles = "M" case nauticalMiles = "N" diff --git a/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+LatitudeRef.swift b/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+LatitudeRef.swift index 32cf964..ed23a29 100644 --- a/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+LatitudeRef.swift +++ b/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+LatitudeRef.swift @@ -9,7 +9,7 @@ import Foundation public extension GPSProperty { - enum LatitudeRef: String, Codable { + enum LatitudeRef: String, Codable, Sendable{ case north = "N" case south = "S" } diff --git a/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+LongitudeRef.swift b/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+LongitudeRef.swift index 496f067..2a1e981 100644 --- a/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+LongitudeRef.swift +++ b/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+LongitudeRef.swift @@ -9,7 +9,7 @@ import Foundation public extension GPSProperty { - enum LongitudeRef: String, Codable { + enum LongitudeRef: String, Codable, Sendable { case east = "E" case west = "W" } diff --git a/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+MeasureMode.swift b/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+MeasureMode.swift index e734d6d..9677a0f 100644 --- a/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+MeasureMode.swift +++ b/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+MeasureMode.swift @@ -9,7 +9,7 @@ import Foundation public extension GPSProperty { - enum MeasureMode: Int, Codable { + enum MeasureMode: Int, Codable, Sendable { case twoDimensionalMeasurement = 2 case threeDimensionalMeasurement = 3 } diff --git a/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+SpeedUnit.swift b/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+SpeedUnit.swift index 2cf9da9..c1e519c 100644 --- a/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+SpeedUnit.swift +++ b/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+SpeedUnit.swift @@ -9,7 +9,7 @@ import Foundation public extension GPSProperty { - enum SpeedUnit: String, Codable { + enum SpeedUnit: String, Codable, Sendable { case kilometerPerHour = "K" case milePerHour = "M" case knots = "N" diff --git a/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+Status.swift b/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+Status.swift index 462c8a5..cacbcfa 100644 --- a/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+Status.swift +++ b/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+Status.swift @@ -9,7 +9,7 @@ import Foundation public extension GPSProperty { - enum Status: String, Codable { + enum Status: String, Codable, Sendable { case measurementActive = "A" case measurementVoid = "V" } diff --git a/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+TrackRef.swift b/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+TrackRef.swift index 868a5eb..1272571 100644 --- a/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+TrackRef.swift +++ b/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty+TrackRef.swift @@ -9,7 +9,7 @@ import Foundation public extension GPSProperty { - enum TrackRef: String, Codable { + enum TrackRef: String, Codable, Sendable { case magneticNorth = "M" case trueNorth = "T" } diff --git a/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty.swift b/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty.swift index caba494..7caa5c7 100644 --- a/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty.swift +++ b/Sources/SwiftyImageIO/CodableEntities/GPS/GPSProperty.swift @@ -6,11 +6,12 @@ // // -import AnyCodable +@preconcurrency import AnyCodable import Foundation +import ImageIO /// Global Positioning System (GPS) information. -public struct GPSProperty: Codable, Equatable, Hashable { +public struct GPSProperty: Codable, Equatable, Hashable, Sendable { // MARK: - GPS Coordinate /// The latitude. @@ -118,4 +119,41 @@ public struct GPSProperty: Codable, Equatable, Hashable { /// The GPS version information. public var gpsVersion: AnyCodable? + + init?(dictionary: Any?) { + guard let dictionary = dictionary as? [String : Any] else { return nil } + + self.latitude = dictionary[kCGImagePropertyGPSLatitude as String] as? Double + self.longitude = dictionary[kCGImagePropertyGPSLongitude as String] as? Double + self.altitude = dictionary[kCGImagePropertyGPSAltitude as String] as? Double + self.latitudeRef = dictionary[kCGImagePropertyGPSLatitudeRef as String] as? LatitudeRef + self.longitudeRef = dictionary[kCGImagePropertyGPSLongitudeRef as String] as? LongitudeRef + self.altitudeRef = dictionary[kCGImagePropertyGPSAltitudeRef as String] as? AltitudeRef + self.hPositioningError = dictionary[kCGImagePropertyGPSHPositioningError as String] as? Double + self.destinationLatitude = dictionary[kCGImagePropertyGPSDestLatitude as String] as? Double + self.destinationLongitude = dictionary[kCGImagePropertyGPSDestLongitude as String] as? Double + self.destinationBearing = dictionary[kCGImagePropertyGPSDestBearing as String] as? Double + self.destinationDistance = dictionary[kCGImagePropertyGPSDestDistance as String] as? Double + self.destinationLatitudeRef = dictionary[kCGImagePropertyGPSDestLatitudeRef as String] as? LatitudeRef + self.destinationLongitudeRef = dictionary[kCGImagePropertyGPSDestLongitudeRef as String] as? LongitudeRef + self.destinationBearingRef = dictionary[kCGImagePropertyGPSDestBearingRef as String] as? BearingRef + self.destinationDistanceRef = dictionary[kCGImagePropertyGPSDestDistanceRef as String] as? DistanceLengthUnit + self.imageDirectionRef = dictionary[kCGImagePropertyGPSImgDirectionRef as String] as? DirectionRef + self.imageDirection = dictionary[kCGImagePropertyGPSImgDirection as String] as? Double + self.status = dictionary[kCGImagePropertyGPSStatus as String] as? Status + self.satellites = dictionary[kCGImagePropertyGPSSatellites as String] as? String + self.measureMode = dictionary[kCGImagePropertyGPSMeasureMode as String] as? MeasureMode + self.dop = dictionary[kCGImagePropertyGPSDOP as String] as? Double + self.speedRef = dictionary[kCGImagePropertyGPSSpeedRef as String] as? SpeedUnit + self.speed = dictionary[kCGImagePropertyGPSSpeed as String] as? Double + self.trackRef = dictionary[kCGImagePropertyGPSTrackRef as String] as? TrackRef + self.track = dictionary[kCGImagePropertyGPSTrack as String] as? Double + self.mapDatum = dictionary[kCGImagePropertyGPSMapDatum as String] as? String + self.processingMethod = dictionary[kCGImagePropertyGPSProcessingMethod as String] as? AnyCodable + self.areaInformation = dictionary[kCGImagePropertyGPSAreaInformation as String] as? AnyCodable + self.differential = dictionary[kCGImagePropertyGPSDifferental as String] as? Differential + self.timeStamp = dictionary[kCGImagePropertyGPSTimeStamp as String] as? String + self.dateStamp = dictionary[kCGImagePropertyGPSDateStamp as String] as? String + self.gpsVersion = dictionary[kCGImagePropertyGPSVersion as String] as? AnyCodable + } } diff --git a/Sources/SwiftyImageIO/CodableEntities/MakerApple/MakerAppleProperty+CodingKeys.swift b/Sources/SwiftyImageIO/CodableEntities/MakerApple/MakerAppleProperty+CodingKeys.swift index b909a20..5843e82 100644 --- a/Sources/SwiftyImageIO/CodableEntities/MakerApple/MakerAppleProperty+CodingKeys.swift +++ b/Sources/SwiftyImageIO/CodableEntities/MakerApple/MakerAppleProperty+CodingKeys.swift @@ -76,7 +76,7 @@ extension MakerAppleProperty { return .init(rawValueInt) } - private var rawValueInt: Int { + internal var rawValueInt: Int { switch self { case .makerNoteVersion: return 0x0001 diff --git a/Sources/SwiftyImageIO/CodableEntities/MakerApple/MakerAppleProperty+HDRImageType.swift b/Sources/SwiftyImageIO/CodableEntities/MakerApple/MakerAppleProperty+HDRImageType.swift index 6aa2c6d..8fa1af2 100644 --- a/Sources/SwiftyImageIO/CodableEntities/MakerApple/MakerAppleProperty+HDRImageType.swift +++ b/Sources/SwiftyImageIO/CodableEntities/MakerApple/MakerAppleProperty+HDRImageType.swift @@ -9,7 +9,7 @@ import Foundation public extension MakerAppleProperty { - enum HDRImageType: Int, Codable { + enum HDRImageType: Int, Codable, Sendable { case hdr = 3 case original = 4 } diff --git a/Sources/SwiftyImageIO/CodableEntities/MakerApple/MakerAppleProperty+RunTimeInformation.swift b/Sources/SwiftyImageIO/CodableEntities/MakerApple/MakerAppleProperty+RunTimeInformation.swift index c266872..808690b 100644 --- a/Sources/SwiftyImageIO/CodableEntities/MakerApple/MakerAppleProperty+RunTimeInformation.swift +++ b/Sources/SwiftyImageIO/CodableEntities/MakerApple/MakerAppleProperty+RunTimeInformation.swift @@ -10,7 +10,7 @@ import Foundation import AnyCodable public extension MakerAppleProperty { - struct RunTimeInformation: Codable, Identifiable { + struct RunTimeInformation: Codable, Identifiable, Sendable { public var id: UUID { return .init() } diff --git a/Sources/SwiftyImageIO/CodableEntities/MakerApple/MakerAppleProperty.swift b/Sources/SwiftyImageIO/CodableEntities/MakerApple/MakerAppleProperty.swift index 17b7640..c0a497f 100644 --- a/Sources/SwiftyImageIO/CodableEntities/MakerApple/MakerAppleProperty.swift +++ b/Sources/SwiftyImageIO/CodableEntities/MakerApple/MakerAppleProperty.swift @@ -7,13 +7,12 @@ // import Foundation -import AnyCodable +import ImageIO +@preconcurrency import AnyCodable /// Metadata for an image from an Apple camera. -public struct MakerAppleProperty: Codable, Identifiable { - public var id: UUID { - return .init() - } +public struct MakerAppleProperty: Codable, Identifiable, Sendable { + public var id: UUID = UUID() public let makerNoteVersion: Int? @@ -108,4 +107,60 @@ public struct MakerAppleProperty: Codable, Identifiable { let unkown_rawValue_59: Int? let unkown_rawValue_60: Int? let unkown_rawValue_74: Int? + + init?(dictionary: Any?) { + guard let dictionary = dictionary as? [Int : Any] else { return nil } + self.makerNoteVersion = dictionary[CodingKeys.makerNoteVersion.rawValueInt] as? Int + self.runTime = dictionary[CodingKeys.runTime.rawValueInt] as? RunTimeInformation + self.aeStable = dictionary[CodingKeys.aeStable.rawValueInt] as? Bool + self.aeTarget = dictionary[CodingKeys.aeTarget.rawValueInt] as? Int + self.aeAverage = dictionary[CodingKeys.aeAverage.rawValueInt] as? Int + self.afStable = dictionary[CodingKeys.afStable.rawValueInt] as? Bool + self.accelerationVector = dictionary[CodingKeys.accelerationVector.rawValueInt] as? [Double] + self.hdrImageType = dictionary[CodingKeys.hdrImageType.rawValueInt] as? HDRImageType + self.burstUUID = dictionary[CodingKeys.burstUUID.rawValueInt] as? String + self.focusDistanceRange = dictionary[CodingKeys.focusDistanceRange.rawValueInt] as? ClosedRange + self.oisMode = dictionary[CodingKeys.oisMode.rawValueInt] as? Int + self.mediaGroupUUID = dictionary[CodingKeys.mediaGroupUUID.rawValueInt] as? String + self.imageCaptureType = dictionary[CodingKeys.imageCaptureType.rawValueInt] as? Int + self.imageUniqueId = dictionary[CodingKeys.imageUniqueId.rawValueInt] as? String + self.livePhotoVideoIndex = dictionary[CodingKeys.livePhotoVideoIndex.rawValueInt] as? Int + self.imageProcessingFlags = dictionary[CodingKeys.imageProcessingFlags.rawValueInt] as? Int + self.qualityHint = dictionary[CodingKeys.qualityHint.rawValueInt] as? String + self.luminanceNoiseAmplitude = dictionary[CodingKeys.luminanceNoiseAmplitude.rawValueInt] as? AnyCodable + self.imageCaptureRequestId = dictionary[CodingKeys.imageCaptureRequestId.rawValueInt] as? String + self.hdrHeadroom = dictionary[CodingKeys.hdrHeadroom.rawValueInt] as? Double + self.sceneFlags = dictionary[CodingKeys.sceneFlags.rawValueInt] as? Int + self.signalToNoiseRatioType = dictionary[CodingKeys.signalToNoiseRatioType.rawValueInt] as? Int + self.signalToNoiseRatio = dictionary[CodingKeys.signalToNoiseRatio.rawValueInt] as? Double + self.photoIdentifier = dictionary[CodingKeys.photoIdentifier.rawValueInt] as? String + self.focusPosition = dictionary[CodingKeys.focusPosition.rawValueInt] as? Int + self.hdrGain = dictionary[CodingKeys.hdrGain.rawValueInt] as? Double + self.afMeasuredDepth = dictionary[CodingKeys.afMeasuredDepth.rawValueInt] as? Int + self.afConfidence = dictionary[CodingKeys.afConfidence.rawValueInt] as? Int + self.greenGhostMitigationStatus = dictionary[CodingKeys.greenGhostMitigationStatus.rawValueInt] as? Int + self.semanticStyle = dictionary[CodingKeys.semanticStyle.rawValueInt] as? Int + self.semanticStyleRenderingVer = dictionary[CodingKeys.semanticStyleRenderingVer.rawValueInt] as? Int + self.semanticStylePreset = dictionary[CodingKeys.semanticStylePreset.rawValueInt] as? Int + self.frontFacingCamera = dictionary[CodingKeys.frontFacingCamera.rawValueInt] as? Bool + self.unkown_rawValue_13 = nil + self.unkown_rawValue_14 = nil + self.unkown_rawValue_16 = nil + self.unkown_rawValue_31 = nil + self.unkown_rawValue_35 = nil + self.unkown_rawValue_40 = nil + self.unkown_rawValue_43 = nil + self.unkown_rawValue_45 = nil + self.unkown_rawValue_46 = nil + self.unkown_rawValue_51 = nil + self.unkown_rawValue_52 = nil + self.unkown_rawValue_53 = nil + self.unkown_rawValue_54 = nil + self.unkown_rawValue_55 = nil + self.unkown_rawValue_57 = nil + self.unkown_rawValue_58 = nil + self.unkown_rawValue_59 = nil + self.unkown_rawValue_60 = nil + self.unkown_rawValue_74 = nil + } } diff --git a/Sources/SwiftyImageIO/CodableEntities/Properties/ImageIOProperties.swift b/Sources/SwiftyImageIO/CodableEntities/Properties/ImageIOProperties.swift index 0cff81c..3400805 100644 --- a/Sources/SwiftyImageIO/CodableEntities/Properties/ImageIOProperties.swift +++ b/Sources/SwiftyImageIO/CodableEntities/Properties/ImageIOProperties.swift @@ -6,15 +6,13 @@ // // -import AnyCodable +@preconcurrency import AnyCodable import Foundation import ImageIO /// Properties that apply to the container in general, and not necessarily to an individual image in the container. -public struct ImageIOProperties: Codable, Identifiable { - public var id: UUID { - return .init() - } +public struct ImageIOProperties: Codable, Identifiable, Sendable { + public var id: UUID = UUID() // MARK: - Common Image Properties @@ -106,4 +104,43 @@ public struct ImageIOProperties: Codable, Identifiable { /// A Lab color model, where color values contain the amount of light and the amounts of four human-perceivable colors. public var lab: AnyCodable? + + public init?(metadata: CFDictionary) { + guard let metadata = metadata as? [String : Any] else { + return nil + } + self.init(metadata: metadata) + } + + public init(metadata: [String : Any]) { + self.exif = ExifProperty(dictionary: metadata[ImageIO.kCGImagePropertyExifDictionary as String]) + self.gps = .init(dictionary: metadata[kCGImagePropertyGPSDictionary as String]) + self.tiff = .init(dictionary: metadata[kCGImagePropertyTIFFDictionary as String]) + self.makerApple = .init(dictionary: metadata[kCGImagePropertyMakerAppleDictionary as String]) + + self.fileSize = nil + self.imageCount = nil + self.isIndexed = metadata[kCGImagePropertyIsIndexed as String] as? Bool + self.images = nil + self.thumbnailImages = nil + self.primaryImage = nil + self.isFloat = metadata[kCGImagePropertyIsFloat as String] as? Bool + if let orientationRawValue = metadata[ImageIO.kCGImagePropertyOrientation as String] as? UInt32 { + self.orientation = CGImagePropertyOrientation(rawValue: orientationRawValue) + } + self.pixelFormat = nil + self.pixelWidth = metadata[kCGImagePropertyPixelWidth as String] as? Int + self.pixelHeight = metadata[kCGImagePropertyPixelHeight as String] as? Int + self.dpiHeight = metadata[kCGImagePropertyDPIWidth as String] as? Int + self.dpiWidth = metadata[kCGImagePropertyDPIHeight as String] as? Int + self.depth = metadata[kCGImagePropertyDepth as String] as? Int + self.hasAlpha = metadata[kCGImagePropertyHasAlpha as String] as? Bool + self.namedColorSpace = metadata[kCGImagePropertyNamedColorSpace as String] as? AnyCodable + self.profileName = metadata[kCGImagePropertyProfileName as String] as? String + self.colorModel = metadata[kCGImagePropertyColorModel as String] as? String + self.rgb = nil + self.cmyk = nil + self.gray = nil + self.lab = nil + } } diff --git a/Sources/SwiftyImageIO/CodableEntities/TIFF/TIFFProperty+CompressionType.swift b/Sources/SwiftyImageIO/CodableEntities/TIFF/TIFFProperty+CompressionType.swift index da816fd..e37c192 100644 --- a/Sources/SwiftyImageIO/CodableEntities/TIFF/TIFFProperty+CompressionType.swift +++ b/Sources/SwiftyImageIO/CodableEntities/TIFF/TIFFProperty+CompressionType.swift @@ -9,7 +9,7 @@ import Foundation public extension TIFFProperty { - enum CompressionType: Int, Codable, Hashable { + enum CompressionType: Int, Codable, Hashable, Sendable { case uncompressed = 1 case ccitt1D = 2 case t4Group3Fax = 3 diff --git a/Sources/SwiftyImageIO/CodableEntities/TIFF/TIFFProperty+ResolutionUnit.swift b/Sources/SwiftyImageIO/CodableEntities/TIFF/TIFFProperty+ResolutionUnit.swift index a93a216..7b09be4 100644 --- a/Sources/SwiftyImageIO/CodableEntities/TIFF/TIFFProperty+ResolutionUnit.swift +++ b/Sources/SwiftyImageIO/CodableEntities/TIFF/TIFFProperty+ResolutionUnit.swift @@ -9,7 +9,7 @@ import Foundation public extension TIFFProperty { - enum ResolutionUnit: Int, Codable { + enum ResolutionUnit: Int, Codable, Sendable { case none = 1 case inch = 2 case centimeter = 3 diff --git a/Sources/SwiftyImageIO/CodableEntities/TIFF/TIFFProperty.swift b/Sources/SwiftyImageIO/CodableEntities/TIFF/TIFFProperty.swift index 0666d4b..1348ea8 100644 --- a/Sources/SwiftyImageIO/CodableEntities/TIFF/TIFFProperty.swift +++ b/Sources/SwiftyImageIO/CodableEntities/TIFF/TIFFProperty.swift @@ -6,12 +6,12 @@ // // -import AnyCodable +@preconcurrency import AnyCodable import Foundation import ImageIO /// the Tagged Image File Format (TIFF). -public struct TIFFProperty: Codable, Equatable, Hashable { +public struct TIFFProperty: Codable, Equatable, Hashable, Sendable { // MARK: - Image Quality /// The compression scheme used on the image data. @@ -75,4 +75,44 @@ public struct TIFFProperty: Codable, Equatable, Hashable { /// The computer or operating system used when the image was created. public var hostComputer: String? + + init?(dictionary: Any?) { + guard let dictionary = dictionary as? [String : Any] else { return nil } + + self.compression = dictionary[kCGImagePropertyTIFFCompression as String] as? CompressionType + self.photometricInterpretation = dictionary[kCGImagePropertyTIFFPhotometricInterpretation as String] as? AnyCodable + self.transferFunction = dictionary[kCGImagePropertyTIFFTransferFunction as String] as? AnyCodable + self.orientation = dictionary[kCGImagePropertyTIFFOrientation as String] as? CGImagePropertyOrientation + self.resolutionX = dictionary[kCGImagePropertyTIFFXResolution as String] as? Int + self.resolutionY = dictionary[kCGImagePropertyTIFFYResolution as String] as? Int + self.resolutionUnit = dictionary[kCGImagePropertyTIFFResolutionUnit as String] as? ResolutionUnit + self.whitePoint = dictionary[kCGImagePropertyTIFFWhitePoint as String] as? AnyCodable + self.primaryChromaticities = dictionary[kCGImagePropertyTIFFPrimaryChromaticities as String] as? AnyCodable + self.tileLength = dictionary[kCGImagePropertyTIFFTileLength as String] as? Int + self.tileWidth = dictionary[kCGImagePropertyTIFFTileWidth as String] as? Int + self.documentName = dictionary[kCGImagePropertyTIFFDocumentName as String] as? String + self.imageDescription = dictionary[kCGImagePropertyTIFFImageDescription as String] as? String + self.artist = dictionary[kCGImagePropertyTIFFArtist as String] as? String + self.copyright = dictionary[kCGImagePropertyTIFFCopyright as String] as? String + if let dateTimeString = dictionary[kCGImagePropertyTIFFDateTime as String] as? String { +// print("dateTimeString", dateTimeString) + self.dateTime = DateFormatter.tiff.date(from: dateTimeString) +// print("self.dateTime", self.dateTime) + } + self.make = dictionary[kCGImagePropertyTIFFMake as String] as? String + self.model = dictionary[kCGImagePropertyTIFFModel as String] as? String + self.software = dictionary[kCGImagePropertyTIFFSoftware as String] as? String + self.hostComputer = dictionary[kCGImagePropertyTIFFHostComputer as String] as? String + } } +//func dateFromColonString(_ dateString: String) -> Date? { +// let dateFormatter = DateFormatter() +// // 设置日期格式,这里的格式需要与传入的字符串完全匹配 +// dateFormatter.dateFormat = "yyyy:MM:dd HH:mm:ss" +// // 设置时区,这里假设是UTC,具体根据你的需要可能需要调整 +// dateFormatter.timeZone = TimeZone(secondsFromGMT: 0) +// // 设置区域,确保无论设备在何地区,解析行为一致 +// dateFormatter.locale = Locale(identifier: "en_US_POSIX") +// // 尝试将字符串转换为Date对象 +// return dateFormatter.date(from: dateString) +//} diff --git a/Sources/SwiftyImageIO/Extensions/Foundation/DateFormatter+.swift b/Sources/SwiftyImageIO/Extensions/Foundation/DateFormatter+.swift index 92f37bc..c3eeeb3 100644 --- a/Sources/SwiftyImageIO/Extensions/Foundation/DateFormatter+.swift +++ b/Sources/SwiftyImageIO/Extensions/Foundation/DateFormatter+.swift @@ -12,8 +12,9 @@ extension DateFormatter { static var tiff: DateFormatter { let formatter: DateFormatter = .init() - formatter.locale = NSLocale.system - formatter.dateFormat = "yyyy:MM:dd HH:mm:ss" + formatter.dateFormat = "yyyy:MM:dd HH:mm:ss" + formatter.timeZone = TimeZone(secondsFromGMT: 0) + formatter.locale = NSLocale.system //Locale(identifier: "en_US_POSIX") return formatter } diff --git a/Sources/SwiftyImageIO/Extensions/ImageIO/CGImagePropertyOrientation+CustomStringConvertible.swift b/Sources/SwiftyImageIO/Extensions/ImageIO/CGImagePropertyOrientation+CustomStringConvertible.swift index 0abb0fe..9f62a4c 100644 --- a/Sources/SwiftyImageIO/Extensions/ImageIO/CGImagePropertyOrientation+CustomStringConvertible.swift +++ b/Sources/SwiftyImageIO/Extensions/ImageIO/CGImagePropertyOrientation+CustomStringConvertible.swift @@ -8,7 +8,7 @@ import ImageIO -extension CGImagePropertyOrientation: CustomStringConvertible { +extension CGImagePropertyOrientation: @retroactive CustomStringConvertible { public var description: String { switch self { case .up: diff --git a/SwiftyImageIO.playground/Contents.swift b/SwiftyImageIO.playground/Contents.swift deleted file mode 100644 index 8b13789..0000000 --- a/SwiftyImageIO.playground/Contents.swift +++ /dev/null @@ -1 +0,0 @@ - diff --git a/SwiftyImageIO.playground/contents.xcplayground b/SwiftyImageIO.playground/contents.xcplayground deleted file mode 100644 index 525867c..0000000 --- a/SwiftyImageIO.playground/contents.xcplayground +++ /dev/null @@ -1,4 +0,0 @@ - - - -