【Swift】画像を圧縮する(容量を下げる)方法!jpegData(compressionQuality:)
この記事からわかること
- Swiftで画像を圧縮する方法
- jpegData(compressionQuality:)メソッドの使い方
- 容量を軽くするには?
- リサイズするには?
- UIGraphicsImageRendererクラスのdrawメソッド
index
[open]
\ アプリをリリースしました /
友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-
posted withアプリーチ
環境
- Xcode:15.0.1
- iOS:17.1
- Swift:5.9
- macOS:Sonoma 14.1
Swiftで画像の容量を圧縮する方法
Swiftで画像の容量を圧縮するにはUIImage
クラスのjpegData(compressionQuality:)
メソッドを使用します。引数compressionQuality
にはCGFloat
型で圧縮率を指定します。1.0
に近いほど圧縮率は低く、0.1
に近いほど圧縮されます。
公式リファレンス:jpegData(compressionQuality:)
private func saveImage(name: String) {
// 圧縮してjpegに変換する
guard let imageData = image?.jpegData(compressionQuality: 0.1) else { return }
do {
// docURL : ドキュメントディレクトリパスを取得するカスタムメソッド
try imageData.write(to: docURL("\(name).jpg")!)
print("画像を保存できました")
} catch {
print("\(error)")
}
}
例えばシミュレーターの元々入っている以下の画像は通常だと4.4 MB
ありましたが、0.1
を指定して圧縮すると0.4 MB
まで容量を抑えることができました。
圧縮前(1.0)
// 4.4 MB
圧縮後(0.1)
// 0.4 MB
ちなみにファイルの容量は以下のように実装すれば調べることができます。詳細は以下の記事を参考にしてください。
private func getCapacity(name: String) -> String? {
// docURL : ドキュメントディレクトリパスを取得するカスタムメソッド
let path = docURL("\(name).jpg")!.path
let fileManager = FileManager.default
guard fileManager.fileExists(atPath: path) else { return nil }
guard let attributes = try? fileManager.attributesOfItem(atPath: path) else { return nil }
guard let bytes = attributes[.size] as? Int64 else { return nil }
let bcf = ByteCountFormatter()
bcf.allowedUnits = [.useMB]
bcf.countStyle = .file
return bcf.string(fromByteCount: bytes)
}
リサイズする
画像を圧縮する方法として画像自体のサイズをリサイズすることでも容量を抑えることが可能です。リサイズするにはUIGraphicsImageRenderer
を使用して新しいサイズに描画し直すことで実装することができます。
汎用的に使えるようにパーセンテージを渡してリサイズするようにし、UIImage
を拡張して定義しておくと使いやすいです。
extension UIImage {
func resizeByPercentage(percentage: CGFloat) -> UIImage {
let newSize = CGSize(width: size.width * percentage, height: size.height * percentage)
let renderer = UIGraphicsImageRenderer(size: newSize)
return renderer.image { (context) in
self.draw(in: CGRect(origin: .zero, size: newSize))
}
}
}
使用する際は圧縮したいパーセンテージを渡します。10%にしたいなら以下のように実装します。
guard let imageData = image?.resizeByPercentage(percentage: 0.1).jpegData(compressionQuality: 1.0) else { return }
圧縮前(100%サイズ)
// 4.4 MB
// (3000.0, 2002.0)
圧縮後(10%サイズ)
// 0.9 MB
// (900.0, 601.0)
最大限圧縮してみる
既存メソッドのjpegData(compressionQuality:)
とカスタムメソッドのresizeByPercentage(percentage:)
を両方使用してみると41 kB
まで容量を下げることができました。
guard let imageData = image?.resizeByPercentage(percentage: 0.1).jpegData(compressionQuality: 0.1) else { return }
圧縮前(100%サイズ)
// 4.4 MB
// (3000.0, 2002.0)
圧縮後(10%サイズ)
// 41 KB
// (900.0, 601.0)
画像の選択や保存などの実装は以下の記事を参考にしてください。
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。