Unity(WebGL)からGyazoAPIを使って画像をアップロードする

#こちらは
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">UnityのWebGL出力でも画像シェアやりたいよね…。でもどうすれば・・・。<br><br>という前々からの悩みを「とりあえず、gyazoにアップロードしたリンク貼ろう。twitterでは画像展開されないけど、まぁよかろう」という一応の結論にたどり着いたので、過去のゲームに組み込んでみました。解説記事はまた今度 <a href="https://t.co/4OqRNYQhM5">https://t.co/4OqRNYQhM5</a></p>&mdash; すずきかつーき (@divideby_zero) <a href="https://twitter.com/divideby_zero/status/958390468110204929?ref_src=twsrc%5Etfw">2018年1月30日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

の解説記事になります。

手順としては非常にシンプルで

①Gyazoにアプリケーションを登録、AccessTokenを取得

②Gyazo APIのUpload parameter(画像バイナリ・AccessToken）をセットしてPostする

③アップロードが成功するとJSONが返却されるので、そこからURLを取得

④本文に取得したURLを書いてTweetする。

です。　では順に行きます。

#①Gyazoにアプリケーションを登録、AccessTokenを取得
まず、Gyazoのユーザーが無いとどうしようもないので、登録はしておいてください。
その後 https://gyazo.com/api へ行き、「アプリケーションを登録」
![image.png](https://qiita-image-store.s3.amazonaws.com/0/37184/4674a542-97ee-896e-7eec-4a7f0c365c43.png)

「New Application」のボタンを押し、NameとCallbackURLを入れます。
Nameには自分の好きな名前を。今回は「UnityWebGLImageUpload」としました。
CallbackURLは適当に入れました。よくわかってません。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/37184/414ce329-a89b-559a-7fc3-9605efee5b9b.png)

Submitして作られたApplication名をクリックして、認証情報表示画面へ。
**Your access token** の下に「Generate」のボタンがあると思うので、クリックして、AccessTokenを生成。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/37184/7931a398-8c13-3c8d-ed34-68365f96228d.png)
↓
![image.png](https://qiita-image-store.s3.amazonaws.com/0/37184/e7be3ad6-3b74-a300-0c33-59b8359f6538.png)

**このAccessTokenによって画像アップロードの認証をするので、コピーしてメモ帳にでも取っておきます。**
(もちろん、もう一度この画面を開けば確認できますし。「Regenerate」で再生成も出来ます。）

#②Gyazo APIのUpload parameter(画像バイナリ・AccessToken）をセットしてPostする
https://gyazo.com/api/docs/image#upload に書いてある仕様に合わせてPostデータを作って送信します。

UnityでPostするには`UnityWebRequest.Post`を、Postデータは `WWWWForm`を使いました。

**注意：ここで使われているScreenCapture.CaptureScreenshotAsTextureはUnity2017.3以降じゃないと動きません**

```csharp:そこそこシンプル目サンプルコード
using System;
using System.Collections;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;

public class GyazoUploadTest1 : MonoBehaviour
{
    public Button _sendButton;
    public Text _timeText;

    public void Start()
    {
        //クリックしたらスクリーンショットを撮って、Gyazoにアップロード
        _sendButton.onClick.AddListener(() =>
            StartCoroutine(UploadGyazoIterator("取っておいたAccessTokenを書きねぇ"))
        );
    }

    private IEnumerator UploadGyazoIterator(string accesstoken)
    {
        //スクリーンショット取得
        yield return new WaitForEndOfFrame();
        var tex = ScreenCapture.CaptureScreenshotAsTexture();

        var gyazoUploadUrl = "https://upload.gyazo.com/api/upload";

        var form = new WWWForm();
        form.AddField("access_token", accesstoken);
        form.AddBinaryData("imagedata", tex.EncodeToPNG(), "screenshot.png", "image/png");
        using (var request = UnityWebRequest.Post(gyazoUploadUrl, form))
        {
            yield return request.SendWebRequest();
            var response = request.downloadHandler.text;

            Debug.Log("Gyazo Upload Response:\n" + response);
        }
        UnityEngine.Object.Destroy(tex);//後始末
    }

    void Update()
    {
        //現在時間を表示
        _timeText.text = DateTime.Now.ToString();
    }
}

```

`form.AddField`でAccessTokenを
`form.AddBinaryData`で画像データ(byte[])を格納しています。

これだけで、UnityEditor（およびWEBGLなどでも）実行してボタンをタップすると、現在のスクリーンショットがGyazoにアップロードされ、responseがJSONで返却されていることがわかります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/37184/9fdc12f3-c1fd-dad0-b8b1-4ad3d2858f4d.png)


#③アップロードが成功するとJSONが返却されるので、そこからURLを取得する。
返却はJSONデータで、内容はhttps://gyazo.com/api/docs/image#upload に書いてあるとおりです。

このJSONをパースする方法はいくつかありますが、高速かつ他ライブラリをインポート使う必要が無いという点で、`JsonUtility.FromJson<T>(string JSON);`を使いました。

そのためには、まずレスポンスで返却されるkeyを全部メンバとして持つSerializableなclassを用意します。

```csharp:JSONパース用クラス
    [Serializable]
    public class GyazoResponse
    {
        public string image_id;
        public string permalink_url;
        public string thumb_url;
        public string url;
        public string type;
    }
```

そして、response(JSON)からパースしてあげます。

```csharp:パース＋ブラウザオープン処理
        using (var request = UnityWebRequest.Post(gyazoUploadUrl, form))
        {
            yield return request.SendWebRequest();
            var response = request.downloadHandler.text;
            Debug.Log("Gyazo Upload Response:\n" + response);

            //パース処理+ブラウザによるOpen処理
            var gyazoResponseObj = JsonUtility.FromJson<GyazoResponse>(response);
            Application.OpenURL(gyazoResponseObj.permalink_url);
        }
```

アップロードされてますね！！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/37184/69c0f2cd-fd92-e691-cd4b-32df44e04175.png)

やってみると特につまづきポイントも無く結構簡単！！
*（むしろ、ちゃんとスクリーンショットを撮る方がつまづきポイント多いような・・・）*

#最後に
~~サンプルコードのgithubによる公開および、これら機能を簡単に使えるunitypackage形式のAssetなどを準備中です。
完成次第追記したいと思います。~~

サンプルコード、unitypackge作りました！　↓
[Unity(WebGL)から簡単にGyazoAPIを使って画像をアップロードする](https://qiita.com/divideby_zero/items/a0abee8f63ad2234d392) 

それでは良いGyazoライフを。