読者です 読者をやめる 読者になる 読者になる

俺が生きている可能性は高い

人生ガンバローン

DataURLから画像へ変換するときはヘッダに気をつけてください的な話

Webブラウザで撮影した写真をサーバにアップロードしたいときってありますよね。

そういうときは大体video要素とかcanvas要素とかをガリガリ使って静止画にして canvas.toDataUrl() ったものをajaxAPIへ送信すると思います。

サーバサイドでは、送信されてきたbase64encodedな画像をdecodeして煮るなり焼くなりすれば良いのですが、実際にはちょっと注意が必要です。

canvas.toDataUrl() の返り値

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAADElEQVQImWNgoBMAAABpAAFEI8ARAAAAAElFTkSuQmCC

ご覧の通り、純粋なbase64文字列ではなく、

  1. データURIスキームであること
  2. 画像の種類
  3. base64エンコードされていること

を示すヘッダがついてます。

この部分ですね

data:image/png;base64,

なので、 ボケーっと

$photo = base64decode($request->input('photo');

とかやると、壊れた画像が出来上がっちゃいます。

ちゃんとヘッダ部分を取り除いてからbase64decodeしましょう。

$offset = strpos($req->input('photo'), 'base64') + 7;
$base64encoded = substr($req->input('photo'), $offset);
$photo = base64_decode($base64encoded);

参考文献

  1. https://developer.mozilla.org/ja/docs/Web/API/HTMLCanvasElement/toDataURL