コマンドラインから画像やテキスト等を共有する「imgurc.exe」を作った (imgur, transfer.sh対応)

##imgurc.exeとは

画像共有サービスの [imgur](http://imgur.com/) や、任意のファイルをオンライン共有できる [transfer.sh](https://transfer.sh/) をコマンドラインから使うツールです。
ブラウザ無しでぽちぽち画像とか送って共有URLが取得できるんで便利です。

↓ DLはこちらのページの画面右下「Download ZIP」からどうぞ
https://github.com/akatubame/imgurc/

　 
使用言語は例によって **AutoHotkey（略称AHK）**。
前回に続いてAHKを使用して簡単なツールの作り方を紹介するつもりでしたが、「講座なんていらんから表題のツールさっさとくれや」と言われそうなので先にexe作って公開しました。

逆にAHKのソースが見たいと言う方は、次項をすっ飛ばして「AutoHotkeyでの応用編」へどうぞ。

↓ 参考までに前回の記事はこちら
[便利なAutoHotkey言語を宣伝する記事 - Qiita](http://qiita.com/akatubame/items/d23a3860f9909c462a2f)

##使い方

DownLoadした「imgurc-master.zip」を解凍し、展開された「imgurc.exe.zip」をさらに解凍し、展開された「imgurc.exe」を直接コマンドで叩いて使います。

初期設定不要。
オプションに画像パス放り込んで起動するだけで勝手に画像送ってURL拾って来てくれます。
コマンドラインオプションのリファレンスなどはGitHubの [ReadMe](https://github.com/akatubame/imgurc.exe/blob/master/README.md) を参照。

以下はコマンドプロンプトからの使用例：

```lang:「imgurc.exe」コマンドライン記述サンプル
; imgurで画像を共有する
imgurc.exe -i "C:\sample.jpg" |more

; transfer.shでテキストファイルを共有する
imgurc.exe -t "C:\sample.txt" |more
```

**【スクリーンショット】**
![Screenshot.jpg](https://qiita-image-store.s3.amazonaws.com/0/69876/3d869aa3-cf44-36f0-d665-d2cca3169ccb.jpeg)

コマンド最後に目に付く"|more"は、一見関係なさそうですがこれが無いとURLが表示されません。
これはAHKの糞仕様です。どうにもなりませんが、パイプラインや入出力処理かける場合は不要ですので念のため。

これ以上の説明は要らないと思われるので省略。詳細はReadmeを参照。
以降はAutoHotkeyでの使い方の紹介となります。興味ない人は読まずに記事を閉じてOKです。

## AutoHotkeyでの応用編

ここまでAHKを使っていない方向けにコンパイルEXEを使用する方法を紹介しました。
しかしこのアップロード処理、AutoHotkey言語で記述してるんで当然AHKスクリプト内で呼び出すことも可能です。

AHK使いの方なら関数一発で画像を共有、URL取得まで可能なのでおすすめ。ソースは以下。

```lang:「autohotkey.ahk」imgurへのアップロード記述
; imgur APIキーの設定(http://api.imgur.com/oauth2/addclient から入手)
global A_ImgurClientID := ""

; 指定画像ファイルをimgur.comへアップロード
UploadToImgur(file){
	
	; 画像のバイナリデータを読込
	img := ComObjCreate("WIA.ImageFile")
	img.LoadFile(file)
	postdata := img.filedata.binarydata
	FileGetSize, size, %file%
	
	; 画像のアップロード
	WinHttpReq := ComObjCreate("WinHttp.WinHttpRequest.5.1")
	WinHttpReq.Open("POST", "https://api.imgur.com/3/upload")
	WinHttpReq.SetRequestHeader("Authorization", "Client-ID " A_ImgurClientID)
	WinHttpReq.SetRequestHeader("Content-Length", size)
	Try
		WinHttpReq.Send(postdata)
	Catch, e
		throw Exception(file "のアップロードに失敗しました：" e)
	
	; アップロード画像のURLを取得
	imgURL := WinHttpReq.ResponseText
	regex  := "i)""link"":""http:\\/\\/(.*?(jpg|jpeg|png|gif|apng|tiff|tif|bmp|pdf|xcf))""}"
	If ( RegExMatch(imgURL, regex, $) ) {
		imgURL := "https://" RegExReplace($1, "\\/", "/")
	}
	return imgURL
}
```

imgurさん曰く、「画像共有APIは登録したアプリにしか使わせませんぜ」とのことなので、コメントのとおり[登録ページ](http://api.imgur.com/oauth2/addclient)から入手しておきましょう。（※要ログイン）
ちなみにimgurc.exeでは登録済みのIDを使用しているので上記の登録操作は不要です。
　

以下はtransfer.shへ任意のファイルをアップロードする関数。こっちは登録不要でおすすめ。

```lang:「autohotkey.ahk」transfer.shへのアップロード記述
; 指定ファイルをtransfer.shへアップロード
UploadToTransferSh(file){
	
	; ファイルの名前を取得
	SplitPath, %file%, FileName
	
	; ファイルのデータ、データ長をそれぞれ取得
	postData := "", length := ""
	FileReadBin(file, postData, length)
	
	; ファイルのアップロード
	WinHttpReq := ComObjCreate("WinHttp.WinHttpRequest.5.1")
	WinHttpReq.Open("PUT", "https://transfer.sh/" FileName, false)
	WinHttpReq.SetRequestHeader("Content-Length", length)
	Try
		WinHttpReq.Send(postData)
	Catch, e
		throw Exception(file "のアップロードに失敗しました：" e)

	; アップロード画像のURLを取得
	uploadURL := WinHttpReq.ResponseText
	uploadURL := RegExReplace(uploadURL, "(?:\n|\r)$", "") ; 末尾の改行除去
	
	return uploadURL
}
; 指定ファイルの形式を自動で判別して読込み
FileReadBin(path, ByRef data, ByRef nLen){
	stream := ComObjCreate("ADODB.Stream")
	stream.Open()
	stream.Type := isBinFile(path) ? 1 : 2
	stream.LoadFromFile(path)
	
	nLen := stream.Size
	data := isBinFile(path) ? stream.Read(nLen) : stream.ReadText(nLen)
}
; 指定ファイルがバイナリ形式かアスキー形式かを判別する
isBinFile(path, tolerance=5) {
	file := FileOpen(path, "r")
	loop, %tolerance% {
		file.RawRead(a, 1)
		byte := NumGet(&a, "Char")
		if (byte<9) or (byte>126) or ( (byte<32) and (byte>13) ) {
			file.Close()
			return 1
		}
	}
	file.Close()
	return 0
}

```
こっちは少々長いですが、要は画像以外のファイルも読み込めるようにした、というだけでやってる事は大して変わりません。

このようにAHKはWindowsのフレームワークであるCOMオブジェクトを使用することで、VBScriptなどと同様に多彩な動作を実装することができます。
その分、Windows以外の環境に流用したくなった時は途端に難儀させられますが、そもそもAHKの利便性はOS(Win)と強い結びつきがあるが故のものなので（例：ホットキー、ウィンドウ操作など）、Win用と割り切って使うのがコツです。
個人的に、Windowsなら大体の操作はAHKだけで実装するのが一番早いです。Javaでちまちま記述してコンパイルして実行…なんてやってられません。

まぁ、このツールのようにCOM無双するだけなら何もAHKでなくてもいいので、次回はAHK特有の機能と組み合わせた使い方をご紹介します。
以上、本記事ではAutoHotkeyで imgur.com および transfer.sh へファイルをアップロードする方法について紹介しました。

##参考
* [COM Object Reference - AutoHotkey Community](http://www.autohotkey.com/board/topic/56987-com-object-reference-autohotkey-v11/)