【Swift】画像を圧縮する(容量を下げる)方法!jpegData(compressionQuality:)

この記事からわかること

  • Swift画像圧縮する方法
  • jpegData(compressionQuality:)メソッド使い方
  • 容量軽くするには?
  • リサイズするには?
  • UIGraphicsImageRendererクラスのdrawメソッド

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

環境

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
【Swift】画像を圧縮する(容量を下げる)方法!jpegData(compressionQuality:)

ちなみにファイルの容量は以下のように実装すれば調べることができます。詳細は以下の記事を参考にしてください。

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)

画像の選択や保存などの実装は以下の記事を参考にしてください。

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index