iOSで画像をリサイズして保存するときに気をつけること

はじめに

カメラロールからユーザーが選んだ画像をUIImageViewに表示してから、リサイズしてファイル保存する際に、ちょっとはまったのでメモ。

バージョン

  • Xcode9.0.1
  • Swift4.0

やりたかったこと

  • ユーザーが選択した画像ファイルを一定の幅にリサイズして保存しておき、非同期でアップロードする

起こった事象

  • iPhone SEだとアップロードできる画像が、iPhone Xだとサーバのファイルサイズ制限に引っかかった
  • ファイルを調べると、オリジナル画像よりもファイルサイズが大きくなっていた

コード

最終的にこんな感じのリサイズ処理にしました。

サンプルコードなので単純に縦横半分にしています。

    private func resize(image: UIImage) -> UIImage {
        // 縦横の画素数を半分にする
        let width = image.size.width * 0.5
        let height = image.size.height * 0.5
        // scale の設定が0だとオリジナル画像よりもサイズが大きくなるので1を設定
        UIGraphicsBeginImageContextWithOptions(CGSize(width: width, height: height), false, 1.0)
        image.draw(in: CGRect(x: 0, y: 0, width: width, height: height))
        let resizeImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return resizeImage!
    }

原因

UIGraphicsBeginImageContextWithOptions(_ size: CGSize, _ opaque: Bool, _ scale: CGFloat)scale パラメータに0.0を指定すると、デバイスにあわせて@2/@3の指定にしてくれます。

The scale factor to apply to the bitmap. If you specify a value of 0.0, the scale factor is set to the scale factor of the device’s main screen.

UIGraphicsBeginImageContextWithOptions(_:_:_:) - UIKit | Apple Developer Documentation

その結果、iPhon Xだと@3の画像となり、結果としてファイルサイズが大きくなってしまっていたのでした。

アプリ埋め込みのアイコンなどはデバイスにあわせた画像を用意しますが、ユーザーの写真などは原寸でいいと判断して、scale を 1.0指定することで解決しました。