HTTPによる画像データの読み込み
HTTPによって送受信されるリソースはプレーンテキストでなく、画像などのバイナリデータも含まれます。 画像表示を題材に、バイナリデータの扱いについても学習しましょう。
以下は、http://cdn.shibe.online/shibes/76d64e95f942fb9408e908412ce748c56437d8b2.jpg から画像を読み込み画面に表示するプログラムです。 画像は shibe.online から取得しました。
import processing.net.*;
size(400, 400);
Client client = new Client(this, "cdn.shibe.online", 80);
client.write("GET /shibes/76d64e95f942fb9408e908412ce748c56437d8b2.jpg HTTP/1.0\r\n");
client.write("Host: cdn.shibe.online\r\n");
client.write("\r\n");
while (client.active()) {
  if (client.available() > 0) {
    String line = client.readStringUntil('\n');
    print(line);
    if (line != null && line.length() == 2) {
      break;
    }
  }
}
int bufferIndex = 0;
byte[] buffer = new byte[1000000];
byte[] tmp = new byte[1000000];
while (client.active()) {
  if (client.available() > 0) {
    int n = client.readBytes(tmp);
    for (int i = 0; i < n; ++i) {
      buffer[bufferIndex++] = tmp[i];
    }
  }
}
saveBytes("tmp.jpg", buffer);
PImage img = loadImage("tmp.jpg");
image(img, 0, 0, width, height);
この画像URLの場合、ヘッダーにHost情報が記載されていないとエラーになるため、リクエストメッセージのヘッダーを追加しています。
メッセージボディである画像のバイト列はバイナリのデータですが、ヘッダーまでは通常通り文字列となります。
そのため、ここではCRLFのみからなる空行を読み込むまで、1行(\n に到達するまで)ずつヘッダーを読み込んでいます。
空行までを読み込んだ後、残りの部分をバイト列として読み出します。
ネットワークデバイスから、必ずしも一度で残りのバイト列を読み切れるわけではありません。
そこで、最終的な全ての画像のバイト列を格納する変数 buffer と、1度分の読み出し結果を保存する変数 tmp の2つのバイト配列を使用します。
bufferIndex に読み込み済みの合計バイト数を格納しておき、tmp から buffer にコピーしていきます。
読み込んだバイト列を一旦画像ファイルとして保存しておきます。
loadImage 関数によって、再度画像ファイルを読み込み、image 関数で表示しています。