質問: https://s8a.jp/javascript-image-processing-library-jimp 上記を参考にjimpを使って画像操作をしたいんですが、 jimpがBlobインターフェースを取り込む方法がわからなくて悩んでいます。 HTMLInputElementからFileを取得する動作は組めるんのですが それをjimp.readにどう渡せば機能できますでしょうか?
回答: 画像処理スクリプトJimpでは画像データをURL文字列として受け取ります. そのため, `input[type=file]`要素で入手した画像`File`オブジェクトをJimpで処理する為には前もってURL文字列に変換する必要があります. 一般に`File`(`Blob`)オブジェクトをURL文字列に変換する方法としては次の2つが考えられます. * `FileReader`を用いる方法 `FileReader`オブジェクトは`File`(`Blob`)オブジェクトを(Base64エンコードされた)dataURIスキーム形式のURL文字列に変換します. 得られたURL文字列には元のデータが全て含まれているため, 外部とのデータの受け渡しを行う場合に有効です. 一方, バイナリデータを文字列に変換する過程で若干のコストが掛かります. ``` //FileReaderを用いてFile(Blob)をdataURIスキームに変換する const fileReader = new FileReader(); //File読み込み完了時の処理 fileReader.onloadend = e => { Jimp.read(fileReader.result).then(lenna => lenna.getBase64(Jimp.MIME_PNG, (err, src) => { document.querySelector("#img").src = src; }) ); }; document.querySelector("#file").onchange = e => { const file = e.target.files[0]; if(!file){return;} //FileをURLとして読み込む fileReader.readAsDataURL(file); }; ``` * `URL.createObjectURL`を用いる方法 `URL.createObjectURL`メソッドは`File`(`Blob`)オブジェクトをBlobURIスキーム形式のURL文字列に変換します. 得られたURL文字列は元となる`File`(`Blob`)オブジェクトへの参照を含んでおり, **そのページでのみ**有効です. また, 不必要となった時点で`URL.revokeObjectURL`メソッドを用いてURL文字列を開放(つまり`File`オブジェクトへの参照を破棄)する必要があります. ``` document.querySelector("#file").onchange = e => { const file = e.target.files[0]; if(!file){return;} //Blobを読み込むためのURLを生成する const url = URL.createObjectURL(file); Jimp.read(url).then(lenna => lenna.getBase64(Jimp.MIME_PNG, (err, src) => { document.querySelector("#img").src = src; //不必要となったURLを開放する URL.revokeObjectURL(url); }) ); }; ``` なお, Jimpで画像を処理するケースではFileオブジェクトを使い捨てとすることが多いでしょうから, バイナリデータをそのまま渡すことができる後者のほうが良いでしょう.