LoginSignup
7
7

More than 5 years have passed since last update.

iOS6でクライアントサイドオンリーでカメラロールの画像を扱う

Last updated at Posted at 2013-01-09

背景

iOS6になりinputタグのtype=fileの指定が可能になった。
これにより、iPhoneから写真のアップロードが非ネイティブアプリで
可能になった。

しかし、サーバーにファイルをアップロードする分には問題ないのだが、
とはいえ、カメラロールの写真のサイズはそれなりにデカい。
クライアントサイドで扱えないか?
となるわけですが、カメラロールの写真のサイズはMobile Safariで
扱える画像サイズを遥かに超えており、困った。

何とかしてみた

サーバーにアップロードできるんだから、
内部的には、あるていど画像データを扱えているのだろう?
何か方法は無いものかと途方に暮れいた2012年。。

ローカルファイルをバイナリーデータとして読み込めることを知る

先日、File APIでDataURLとして読み込まず、素のバイナリーに近い
形で扱える。FileReader#readAsBinaryStringなるメソッドを
Google DriveのAPIをJavaScriptで叩こうとしていた際に知った。
さらに調べると、バイナリ配列として扱える
FileReader#readAsArrayBuffer
があった!

ニヤリ。

JPEGデコーダはやっぱりあるし。

今回はjpgjsを使用。
撮影時の回転情報を反映してくれないが、それはおいおい。

これらをまとめると

var item = document.getElementById('picInput').files[0];
var reader = new FileReader();
reader.onload = function (e) {
    var j = new JpegImage();
    var buffer = new Uint8Array(reader.result);
    j.parse(buffer);

    var c = document.getElementById("filterdImage");
    // 算数苦手なので、10分の1にとりあえず指定して、画像サイズを小さくする。
    c.width = j.width / 10;
    c.height = j.height / 10;
    var ctx = c.getContext("2d");
    var d = ctx.getImageData(0, 0, j.width / 10, j.height / 10);
    j.copyToImageData(d);
    ctx.putImageData(d, 0, 0);
};
reader.readAsArrayBuffer(item);

サンプルはJsdo.itに

iOS6で扱える画像サイズの制約をかわせるかの実験

2013年今年もよろしくお願いします

追記(2014/9/24)

iOS8では、jpgjsでqt[i]が未定義とエラーが出て動かないようです。

関連投稿

関連記事

7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7