🐷

pixi.jsでブラウザからアップロードした画像を読み込む方法

2020/09/20に公開

前に画像加工アプリを pixi.js を使って実装しました。
そのアプリについては こちら をご覧ください。
ユーザーがアップロードした画像を pixi.js のスプライトとして読み込む必要がありました。
その方法を紹介します。

実装例

実装例はこちらから確認出来ます。

https://orange634nty.github.io/img-upload-to-pixi-sample/

コードはこちらのリポジトリにあげています。

https://github.com/orange634nty/img-upload-to-pixi-sample

ポイント

上の例で関係あるところのみ抜粋しました。

// ファイルアッップロード時のリスナーを登録
document.getElementById('uploadFile').addEventListener('change', evt => {
    // ファイルを読み取る
    const files = evt.target.files;
    if (!files.length) {
        console.log('error! file are not uploaded.');
        return;
    }
    // ImageとFileRaederを使ってアップロードされた画像を読み込む
    const image = new Image();
    const fr = new FileReader();
    // ファイルをdata urlとして読み込みます
    fr.readAsDataURL(files[0]);
    // ファイルをロードした後のイベントリスナを登録
    fr.onload = evt => {
        // base64に変換されたurlをimageのsrcに設定
        image.src = evt.target.result;
        // 画像をロードした後のイベントリスナを登録
        image.onload = () => {
            // アップロードした画像をtextureとして読み込みspriteに貼り付ける
            const loadTexture = new PIXI.Texture(new PIXI.BaseTexture(image));
            const loadSprite = new PIXI.Sprite(loadTexture);
            // 位置調整
            loadSprite.anchor.set(0.5);
            loadSprite.x = app.screen.width / 2;
            loadSprite.x = app.screen.height / 2;
            // 画面にスプライトを追加
            app.stage.addChild(loadSprite);
        };
    }
});

ポイントは FileReaderItem を使って画像を読み込んでいるところです。

FileReader

https://developer.mozilla.org/ja/docs/Web/API/FileReader

FileReader オブジェクトを使うと、ユーザのコンピュータ内にあるファイル(もしくはバッファ上の生データ)を Web アプリケーションから非同期的に読み込むことが出来ます。読み込むファイルやデータは File ないし Blob オブジェクトとして指定します。

今回は画像ファイルを読み込むのに FileReader を使用します。
読み込むために readAsDataURL メソッドを使用します。
これで読み込んだ画像を base64 変換した data utl を取得できます。
読み込んだ後の処理は onload プロパティにイベントリスナを登録します。
実装例から該当箇所のみだと以下のようになります。

const fr = new FileReader();
fr.readAsDataURL(files[0]);
fr.onload = evt => {
    // ロード後の処理
}

Image

https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/Image

The Image() constructor creates a new HTMLImageElement instance.
It is functionally equivalent to document.createElement('img').

読み込んだ画像ファイルを HTMLImageElement にする必要があるので Image コンストラクタを使用します。
画像を読み込ませるために、 HTMLImageElementsrc 属性に先ほど読み込んだ data url を指定します。

image.src = evt.target.result;

また画像読み込み完了後の処理を onload にイベントリスナを登録します。

image.src = evt.target.result;
image.onload = () => {
    // ロード後の処理
}

以上2つを組み合わせて、画像をロードしています。
画像をロードしたら、pixi.jsTexutre として読み込んでスプライトを生成します。

const loadTexture = new PIXI.Texture(new PIXI.BaseTexture(image));
const loadSprite = new PIXI.Sprite(loadTexture);

以上です。
別のもっと簡単な方法があれば教えていただけるとありがたいです。

Discussion