見出し画像

TWSNMP MV開発12日目:マップ上に画像が表示できない問題で悩む

助手の猫さんは予熱の残る1階で寝ていて2時ぐらいに寒くなって騒ぎながら、かみさんの布団に入っていきました。早すぎるので、もう一度寝ました。5時に起きました。コーヒーを淹れて開発を開始すると5時半ぐらいに、猫さんが、ご飯と言いにきました。

さて、昨日マップの表示ができて快調だと思っていましたが、今朝は画像が表示できない問題で2時間悩みました。
画像は、p5.jsのloadImageを使っています。

イメージを取得するURLは、相対パスしか許していません。スクリプトを読み込んだサーバーと同じところしかだめということです。

URLs such as 'https://example.com/thundercat.jpg' may be blocked due to browser security.

安全のためです。この注意に続けて

Raw image data can also be passed as a base64 encoded image in the form 'data:image/png;base64,arandomsequenceofcharacters'.

とあります。この方法で解決しようと思いました。
TWSNMP FCから画像を取得するのはできますが、生の画像ファイルのデータです。これをbase64にする必要があります。
Googleさんに聞くとJavaScriptで画像をbase64にする説明は、いろいろな方法がありました。でも、スッキリしたものがありません。
試行錯誤の結果

      const res = await fetch(画像のURL, {
        method: 'GET',
      });
      if (res.status != 200) {
        return undefined;
      }
      const reader = new FileReader()
      reader.readAsDataURL(await res.blob());
      await new Promise<void>(resolve => reader.onload = () => resolve());
      return reader.result

で解決しました。FileReaderのreadAsDaraURLを使っていますが、async/awaitで書いているのがミソです。

描画アイテムの画像が表示できました。

失敗したのはいくつかありますが、惜しかったのは

const contentType = res.headers.get('Content-type')
const data = new Uint8Array(await res.arrayBuffer()).toString();
return `data:${contentType};base64,${btoa(data)}`;

です。何となくbase64のdataURLになっていましたが、p5.jsのloadImageに渡すとエラーが発生していました。

明日に続く

開発のための諸経費(機材、Appleの開発者、サーバー運用)に利用します。 ソフトウェアのマニュアルをnoteの記事で提供しています。 サポートによりnoteの運営にも貢献できるのでよろしくお願います。