LoginSignup
1
0

More than 5 years have passed since last update.

ProcessingでGyazoに画像を投稿する

Posted at

Gyazoは画像をアップロードして共有できるサービスです。
APIドキュメンテーションには「multipart/form-dataを使うこと」とあります。
なんじゃそりゃ?ということで作ってみました。多分車輪の再発明。

import java.net.HttpURLConnection;
import java.net.URL;
import java.io.InputStreamReader;
import java.io.FileInputStream;
import java.io.File;
import java.io.DataOutputStream;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.util.UUID;
import java.util.Map;

void setup() {
  PGraphics pg = createGraphics(299, 299);
  pg.beginDraw();
  pg.background(255);
  int count = 0;
  for (int r = 0; r < 256; r+=127)
    for (int g = 0; g < 256; g+=127)
      for (int b = 0; b < 256; b+=127) {
        pg.fill(r, g, b);
        pg.stroke(random(256),random(256),random(256));
        pg.rect(count/6*50, count%6*50, 50, 50);
        count++;
      }
  pg.endDraw();

  HashMap<String, Object> data = new HashMap<String, Object>();

  data.put("access_token", "enteryourtokenhere");
  data.put("title", "Sent from Processing");
  data.put("imagedata", pg);
  multipartSend("https://upload.gyazo.com/api/upload",data);
}

void multipartSend(String api, HashMap<String, Object> data) {
  final String twoHyphens = "--";
  final String boundary =  "*****"+ UUID.randomUUID().toString()+"*****";
  final String lineEnd = "\r\n";

  try {
    HttpURLConnection con = null;
    URL url = new URL(api);

    // 接続用HttpURLConnectionオブジェクト作成
    con = (HttpURLConnection)url.openConnection();
    // リクエストメソッドの設定
    con.setRequestMethod("POST");
    // リダイレクトを自動で許可しない設定
    con.setInstanceFollowRedirects(false);

    con.setRequestProperty("Connection", "Keep-Alive");
    con.setRequestProperty("Content-Type", "multipart/form-data; boundary="+boundary);
    con.setDoOutput(true);
    con.setDoInput(true);
    con.setUseCaches(false);

    DataOutputStream dos = new DataOutputStream(con.getOutputStream());

    for (Map.Entry<String, Object> entry : data.entrySet()) {
      Object value = entry.getValue();
      if (value instanceof File) {
        File file = (File)value;
        if(!file.isFile())continue;
        if(!file.canRead())continue;

        dos.writeBytes(twoHyphens + boundary + lineEnd);
        dos.writeBytes("Content-Disposition: form-data; name=\""+entry.getKey()+"\";filename=\""+file.getName()+"\""+lineEnd);
        dos.writeBytes("Content-Type: application/octet-stream"+lineEnd);
        dos.writeBytes("Content-Transfer-Encoding: binary"+lineEnd);
        dos.writeBytes(lineEnd);

        final int maxBufferSize = 1024*1024*3;

        FileInputStream fileInputStream = new FileInputStream(file);
        int bytesAvailable = fileInputStream.available();
        int bufferSize = Math.min(bytesAvailable, maxBufferSize);
        byte[] buffer = new byte[bufferSize];

        int bytesRead = fileInputStream.read(buffer, 0, bufferSize);
        while (bytesRead > 0) {
          dos.write(buffer, 0, bufferSize);
          bytesAvailable = fileInputStream.available();
          bufferSize = Math.min(bytesAvailable, maxBufferSize);
          bytesRead = fileInputStream.read(buffer, 0, bufferSize);
        }

        dos.writeBytes(lineEnd);
        fileInputStream.close();
      }
      if (value instanceof PImage) {
        PImage pi = (PImage)value;
        pi.updatePixels();
        BufferedImage bi = new BufferedImage(pi.width, pi.height, BufferedImage.TYPE_4BYTE_ABGR);
        bi.setRGB(0, 0, pi.width, pi.height, pi.pixels, 0, pi.width);

        dos.writeBytes(twoHyphens + boundary + lineEnd);
        dos.writeBytes("Content-Disposition: form-data; name=\""+entry.getKey()+"\";filename=\"PImage.png\""+lineEnd);
        dos.writeBytes("Content-Type: application/octet-stream"+lineEnd);
        dos.writeBytes("Content-Transfer-Encoding: binary"+lineEnd);
        dos.writeBytes(lineEnd);
        ImageIO.write(bi, "png", dos);
        dos.writeBytes(lineEnd);
      }
      if (value instanceof String) {
        dos.writeBytes(twoHyphens + boundary + lineEnd);
        dos.writeBytes("Content-Disposition: form-data; name=\""+entry.getKey()+"\""+lineEnd);
        dos.writeBytes("Content-Type: text/plain"+lineEnd);
        dos.writeBytes(lineEnd);
        dos.writeBytes((String)value);
        dos.writeBytes(lineEnd);
      }
    }

    dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

    dos.close();

    con.connect();

    StringBuffer result = new StringBuffer();
    final int status = con.getResponseCode();
    if (status == HttpURLConnection.HTTP_OK) {
      // 通信に成功した
      // テキストを取得する
      final InputStream in = con.getInputStream();
      String encoding = con.getContentEncoding();
      if (null == encoding) {
        encoding = "UTF-8";
      }
      final InputStreamReader inReader = new InputStreamReader(in, encoding);
      final BufferedReader bufReader = new BufferedReader(inReader);
      String line = null;
      // 1行ずつテキストを読み込む
      while ((line = bufReader.readLine()) != null) {
        result.append(line);
      }
      bufReader.close();
      inReader.close();
      in.close();

      print(result);
    } else {
      print("Status:"+status);
    }
  }
  catch(Exception e) {
    e.printStackTrace();
  }
}

使い方

HashMapにパラメータを入れて使ってください。
- String
- PImage
- File
に対応。

トークンは各自取得してください。

参考

MIME タイプ
HttpURLConnectionを使用してHTTP通信を行う
GyazoのAPIをRから使ってみる
AndroidからHTTPのmultipart/form-dataを使ってデータをアップロードする

他にも色々参考にしたと思うんですが忘れました。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0