最大容量/最大サイズを指定してUIImageをNSDataに変換する
せっかくUIImagePickerControllerで画像を選べるようになったので、ネット経由でいろいろしようかと思ったのですが、最近のiPhoneはカメラが良い事もあって、画像データがそこそこ大きかったりします。
そこで、データにした後の容量と長辺の最大サイズを制限した上で、NSDataにしてくれるような処理を書いてみました。
ソースコードはこちら。(前回のデモの流用です)
See_Ku / ImagePickerDemo — Bitbucket
https://bitbucket.org/See_Ku/imagepickerdemo
ちなみに、UIImagePickerControllerの話はこちら。
UIImagePickerControllerを使ってみた - 開発メモ
http://seeku.hateblo.jp/entry/2016/02/29/210359
動作を確認した環境
環境 | 情報 |
---|---|
Xcode | 7.2.1 (7C1002) |
iOS | 9.2 |
Swift | 2.1.1 |
Date | 2016/3/6 |
ポイント解説
やってる事は単純です。
- 指定された範囲に収まるように画像をリサイズ
- JPEGの圧縮率を下げながら何度もデータ化
基本はこれだけです。簡単ですね。
指定された範囲に収まるように画像をリサイズ
画像のリサイズはこんな感じ。
/// イメージのサイズを変更 func resizeImage(src: UIImage) -> UIImage { // リサイズが必要か? let ss = src.size if maxLongSide == 0 || ( ss.width <= maxLongSide && ss.height <= maxLongSide ) { resizedSize = ss return src } // TODO: リサイズ回りの処理を切りだし // リサイズ後のサイズを計算 let ax = ss.width / maxLongSide let ay = ss.height / maxLongSide let ar = ax > ay ? ax : ay let re = CGRect(x: 0, y: 0, width: ss.width / ar, height: ss.height / ar) // リサイズ UIGraphicsBeginImageContext(re.size) src.drawInRect(re) let dst = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() resizedSize = dst.size return dst }
アスペクト比の計算から実際のリサイズまで、ほとんど、お約束の流れのままです。
JPEGの圧縮率を下げながら何度もデータ化
単純に、forでループを回してるだけです。
// JPEG形式でデータ化 for qualityUse = qualityMax; qualityUse >= qualityMin; qualityUse -= qualityDif { let data = UIImageJPEGRepresentation(resize, qualityUse) if checkDataSize(data) { return data } }
こういう処理を書いてると、C言語風のforループもあって良い気がするんですけど・・・ 本当に無くすんでしょうかね?
SK4ShrinkRepresentationの使い方
実際にイメージをデータに変換する処理をまとめたのが、SK4ShrinkRepresentationクラスになります。最大容量/最大サイズを制限してデータにする場合、こんな感じになります。
// 単純に制限付きでデータにするだけならこんな感じ let data = SK4ShrinkRepresentation.makeData(image, maxDataByte: 1024 * 1024 * 4, maxLongSide: 1024 * 2)
もっと面倒な使い方は・・・ たぶん、必要ないと思うんですけど、気になる方はソースコードを読んで下さい。