概要
CIImage
の properties
を書き換える実装をする機会があったのですが、ネットを調べると CGImageDestinationAddImage
を使って書き換える方法を紹介している記事が大半でした。
新卒のときに務めていた会社で、僕が尊敬しているシニアエンジニアの方から、イミュータブルプログラミングを心がけるようにと言われていた影響もあって、この方法はイミュータブルプログラミングっぽくなく可読性が悪いと感じており、あまり好きではありませんでした。
先日、Apple Developer Documentation を眺めていたときに、たまたまもっと簡単に、イミュータブルに出来る方法があることを知ったので記事にしました。
やり方
用意するもの
- 書き換えたい画像 (CIImage)
CIImage.properties
使用するAPI
https://developer.apple.com/documentation/coreimage/ciimage/1645895-settingproperties
手順
-
CGImageDestinationAddImage
のやり方同様、CIImage.properties
を別の変数に代入して、その変数の辞書を書き換える流れとなっております。 -
コピーした辞書を書き換えてそれを適用する点は一緒ですが、指定された画像の変数を書き換えるか (
CGImageDestinationAddImage
)、Exif が書き換えられた CIImage を新規で生成するか (CIImage.settingProperties
)、という点が異なっています。
-
CIImage.properties
をコピーするlet ciImageFromURL: CIImage = .init(contentsOf: URL(string: "https://hoge.com/fuga.png")) // MARK: 後の手順で書き換えるので、var で宣言 var ciImageProperties: Dictionary<String, Any> = ciImageFromURL.properties
-
書き換えたいプロパティの辞書をコピーする
https://developer.apple.com/documentation/imageio/image_properties
こちらのドキュメントに掲載されている辞書のキーを使って、書き換えたいプロパティの辞書をコピーします。
今回は Exif を書き換えたいので、kCGImagePropertyExifDictionary
を指定します。var exifDictionary: Dictionary<String, Any>? = ciImageProperties[kCGImagePropertyExifDictionary as String] as? [String: Any]
-
書き換える
- 今回は、
kCGImagePropertyExifDateTimeDigitized
を書き換えてみたいと思います。 - なお、Exif の日付フォーマットは特殊なので、
DateFormatter.dateFormat
をいじっています。
var dateFormatterForExif: DateFormatter { let formatter: DateFormatter = .init() formatter.locale = NSLocale.system formatter.dateFormat = "yyyy:MM:dd HH:mm:ss" return formatter } exifDictionary?[kCGImagePropertyExifDateTimeDigitized as String] = dateFormatterForExif.string(from: Date.now)
- 今回は、
-
CIImage.settingProperties(_:)
を使い、Exif が書き換えられた CIImage を生成する// コピーした properties に、書き換えた Exif の辞書を代入 ciImageProperties[kCGImagePropertyExifDictionary as String] = exifDictionary let exifModifiedCIImage: CIImage = ciImageFromURL.settingProperties(ciImageProperties)
以上で、Exif が書き換えられた CIImage を新規で生成することができます。