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