[Processing]画像をwebサーバにPOSTで送信

  • SumoMe

Webサーバに対して、Processingで画像を送信し、保存しなければならなくなり、今回はやっつけで作ったProcessing側の処理をまとめてみます。

概要

今回は、クライアント・サーバ型のプログラミングをします。サーバはwebサーバで、クライアントはProcessingです。Processingは画像をwebサーバに送信し、webサーバは何らかの応答(レスポンス)を返します。

client-server

今回は、webサーバ側ではPOST処理で送られてきた画像を保存する機能が既に用意されているものとします。検索すると数多くのサイトがヒットするのですが、シンプルに以下のサイトが参考になるのではないでしょうか。

ファイルのアップロード | PHP Labo
http://www.php-labo.net/tutorial/php/upload.html

本題に戻りまして、Processing側では、以下の様な手順で送信します。

  1. 画像を送信用に仮にファイルとして保存
  2. webサーバと接続を確立
  3. 送信・応答
  4. 切断

一見難しく見えますが、これらはライブラリを利用しますので、その手順だけ間違わなければ問題ありません。

今回は、こちらを非常に参考にさせていただきました。

Androidでサーバに画像をアップロードする方法 | 株式会社woodsmall(ウッズモール) – Androidアプリ開発・WEBサイト制作会社

準備

今回利用するライブラリは、外部から取り寄せねばなりません。そこで以下の手順で導入します。

ダウンロード

今回はかの有名なApacheからライブラリを拝借してきます。まずは、下記のリンクを開き、「HttpClient 4.2.5 (GA)」という項目の、「4.2.5.zip」をダウンロードしました。このバージョンは現在のもので、時期が異なると同一のものはないかもしれません。およそ、下の方にスクロールすると発見できるかもしれません。

Apache HttpComponents –
HttpComponents Downloads
http://hc.apache.org/downloads.cgi

インストール

  1. ダウンロードした「4.2.5.zip」を解凍
  2. Processingのsketchフォルダを開き、「code」というフォルダを新規作成
  3. 解凍したファイル内のlibフォルダ内にある以下の4つのファイルをコピー
    • httpcore-4.2.4.jar
    • httpclient-4.2.5.jar
    • httpmime-4.2.5.jar
    • commons-logging-1.1.1.jar
  4. sketchフォルダ内に作成した、「code」フォルダ内に、コピーしたファイルを貼り付ける

確認

以下のソースコードをソースコードの先頭に貼り付け、実行し、テキストエリアにエラーメッセージが表示されなければ、インストール成功です。

import org.apache.http.HttpEntity;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;

作成

今回は、プログラムが長くなるので、ファイルを分割しました

機能 ファイル名
メインプログラム post.pde
アップロードプログラム upload.pde

アップロードプログラム部分

とりあえず、関数「Upload」としてまとめました。引数は、アップロード先のURLと送信する画像です。細かい点はコメントに書きました。しかし、意味をさほど理解せずに利用しているため、間違っていると思いますので、今一度自ら調べてみてください。

この関数では、sketchフォルダの中のdataフォルダ中に仮のファイルを保存するようになっています。そこで、実行する前に必ず、sketchフォルダの中にdataフォルダを作成してください。

sketch --- code (ここにライブラリが入る)
        |
        -- data (ここに仮の画像が保存される)
import org.apache.http.HttpEntity;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;

boolean Upload(String url, PImage img) {
  // テンポラリファイル名
  String tempImageFilename = "tmp.png";

  // 画像を、仮に保存
  img.save("data/"+tempImageFilename);
  // 保存した先のパスを取得
  String filePath = dataPath(tempImageFilename);

  try {
    // クライアントインスタンスを作成
    DefaultHttpClient httpClient = new DefaultHttpClient();

    // 接続先を作成(まだつながってない)
    HttpPost  httpPost   = new HttpPost( url );
    // 仮の画像ファイルを読込(まだ読み込んではいないと思うけど)
    File upfile = new File( filePath );
    // エンティティの作成
    MultipartEntity mentity = new MultipartEntity();
    // エンティティにファイルを指定
    // addPart("HTMLではnameに当たる部分", POSTされる値);
    mentity.addPart("file", new FileBody(upfile));

    // クライアントインスタンスにエンティティを設定
    httpPost.setEntity(mentity);

    // 実行し、応答をresponseに受け取る
    HttpResponse response = httpClient.execute( httpPost );
    HttpEntity   entity   = response.getEntity();

    println("----------------------------------------");
    println( response.getStatusLine() );
    println("----------------------------------------");

    if ( entity != null ) entity.writeTo( System.out );
    if ( entity != null ) entity.consumeContent();

    // 切断?
    httpClient.getConnectionManager().shutdown();
  } 
  catch(Exception e) {
    e.printStackTrace();
    return false;
  }
  return true;
}

メインプログラム部分

もちろんこれだけでは動きませんので、Processingではお約束のいつものやつから作成した関数を呼び出します。

void setup(){ 
  PImage img = loadImage("送る画像");
  Upload("接続先のURL",img);
}

このように、関数にURLと画像を指定すると、webサーバへと送られます。ちなみに、今回のsetup関数では有り難みが感じられませんが、例えば、実行画面をPImageに変換してサーバーに送るとか、webカメラの画像をPImageに変換して送るとかすると有用だと思います。

おわりに

今回は、サーバ側の実装の確認のために、Processingで簡単にクライアントが作れないものかというところから出発しました。Javaの機能がそのまま使えるので、情報はたっぷりあるのですが、案外実装に時間がかかってしまいました。

今回利用した、Apacheの外部ライブラリにはライセンスに関する規約ファイル「LICENSE.txt」がありますので、合意してからご使用ください。英語なので参考までに日本語に翻訳したこちらも併せて読むと読みやすいかもしれません。

licenses/Apache_License_2.0 – Open Source Group Japan Wiki – Open Source Group Japan – SourceForge.JP
http://sourceforge.jp/projects/opensource/wiki/licenses%2FApache_License_2.0