Node.jsのFile Systemで画像を扱うときの出力方法

Dec 18, 2016

  • Javascript
  • Encoding

Electronを使っていると、けっこう使うFile Systemモジュールですが、画像を扱う際にバイナリとかバッファとかBase64などのエンコーディングでてきますよね?エンコードまわりと基本的なfsモジュールの出力操作について触れたいと思います。

バイナリとは

2進法で表現したデータのことです。2進法とは数字の0と1をつかって数を表す方法です。「デジタルは0と1でできている」とどこの誰かが言ったりしますが、機械は2進法でプログラムを読み取ります。なぜ2進法かというと、単純に計算がし易いからではないかと思います。

日常的にボクたちが使っているのは0~9の10個の数字で表す10進法ですが、コンピュータにとっては理解するのがすこし遠い言語になってしまうわけです。0と1の組み合わせは◯(マル)か☓(バツ)かみたいな判断をしていくことと同じなので、シンプルですね。

つまり、画像データでバイナリということは、色やピクセルの配置、その他画像に含まれる情報がすべて0と1で表現されたデータということです。アプリケーションなんかを作る場合、操作性を意識しますから、バイナリデータを変数に格納して入出力したりすることで、処理が早くなるというメリットがあります。

ただ、注意しなくてはならないのは、ブラウザなどのフロント側ではバイナリデータを直接読み込んで表示するわけではないので、バイナリデータを処理で使用する場合は、jpgやpngなどに変換する作業を挟まないといけません。まぁ小さい画像くらいならいいのですが、大きいサイズの画像や動画とかになったら処理が重たくなりがちなので通信するデータサイズを縮小し、CPUやGPUなどの負荷を小さくするためにバイナリデータをうまく使っていくといいみたいです。

バッファとは

バッファとは、入出力処理において、プログラム処理中のタイムラグを補う目的で実装されたデータを一時的に保存する記憶領域のことを指します。英語では「緩衝記憶装置」「緩衝物」を意味する単語みたいです。

イメージしやすいと思いますが、一時ファイルを扱うので、データを気軽に扱うことができます。あまりに大きなデータを扱うには向きませんが、さらっと「ちょっとこれ持ってて!」くらいのデータだったら柄どころが結構あるのではないでしょうか。

Vimをやっている人ならバッファの概念はお手の物だと思いますが、たとえば、音楽の録音ソフトとかで「バッファサイズが足りません」とかってでる、あれもバッファですね。要するにそうしたエラーがでるのは、「両手塞がってるからもう無理!」という状態のことですね。扱うデータ量の最大値を想像して設計しないとああした自体に陥ります。

手軽なデータに使いましょう。

Base64とは

バイナリデータを「A-Z,a-z,0-9,+,/」の64文字で表現するエンコード規格とのことです。64進数ということですね。◯進数とは「◯文字でデータを表現するのか」ということに近いと思うので、ざっくり覚えたいかたはそう覚えておきましょう。

さて、バイナリデータが軽やかであるという話がでたのに、なぜあわざわざBase64のデータを使うシチュエーションが生まれるのでしょうか?

答えをさきに言うと、ボクたちが日々使うメールのために作られた規格のようです。メール送信でSMTPって聞いたことありますかね?これは送信メールの通信規格なんですけど、当時このSMTPではASCIIデータという7Byteで表現される英数字しか送れなかったようです。日本語とかを扱うためにゴニョゴニョ最適化でもしたのでしょうか。それで、画像や音声のデータをこれじゃ送れないってことで、Base64というデータ変換方式が作られたとさ。

プログラミングにおいては、正規表現などをつかってデータをフィルタリングしたりするのに一貫性のあるデータの方が使いやすいって理由でBase64が使わたり、画像データとしてブラウザでも表示できるので、そのような用途がある場合に使用されたりしています。

パフォーマンスというよりはデータの整形や表示が楽というメリットがあります。

それらを踏まえていざwriteFile

ここまでは前置きでしたが、本題はそう長くありません。扱うデータをいづれかにするというだけなので、はっきりいって結論だけなら10行で終わりでした。前置きを伸ばしたお陰で記事っぽくなってよかったです。

書き方はこうです。

const fs = require('fs');
fs.writeFile(public, data, {encoding: '指定'}, function(err){
    // Any Code
});

指定部分には

  • binary
  • buffer
  • base64

とかがはいったりしますね。

あとは適当に試行錯誤してみると良いと思います。

では。