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 関数で表示しています。

results matching ""

    No results matching ""