golang
emoji
Slack
SlackDay 23

GolangでSlackのemoji用に画像を分割するツールを作成した

はじめに

これはSlack Advent Calendar 2017の23日の記事です。
遅くなってしまい申し訳ありません。

今回はこちらの記事(Slackで大きな絵文字を使う)を見て、Golangで出来ないものかと思いツールを作成しました。
まだ連携部分が出来ていないのですが、Golangで作成したドラッグ&ドロップでemojiをアップロードできるツールと組み合わせれば、ドラッグ&ドロップ一発で登録することも出来そうです。

概要

以下がレポジトリです。
picture_cutter_go
README.mdが書けていなくて申し訳ありません。
go run picture_cutter.go image_fileで実行可能です。

実行すると以下のことを行ってくれます。

  1. 画像の読み込み
  2. 画像サイズの判定
  3. 画像の縦か横が 128x4 = 512 を超えていたら比率はそのままで512まで縮小する
  4. 128x128 最大4x4 にカットし、ファイルにファイル名_row_column.拡張子で書き出す

上記で生成された画像をemojiに登録して順番通りに並べると隙間なく大きなemojiを貼り付けることが可能です。

はまった点

隙間ができる

最初は画像を分割してそのままファイルに書き出していました。
しかし実際にemojiとして並べてみると隙間ができます。
正方形で登録しないと中心に寄ってしまうため、隙間が出来てしまうということが分かりました。

黒くなる

隙間が出来てはいけないという事が分かったため、対策として128x128に満たない部分は周りを埋めて128x128まで広げる事にしました。
そのために以下の様なコードを書きました。

// 128x128のRectangleを作る
tmpRect := image.Rect(0, 0, int(imageMax), int(imageMax))
// 新しいRGBAの画像を作る
tmpImage := image.NewRGBA(tmpRect)
// subImageには切り出した画像が格納されている
// 左上からsubImageを描画する
draw.Draw(tmpImage, tmpRect, subImage, image.ZP, draw.Src)

しかし、上記コードだと出力された画像が真っ黒になってしまうことがあります。
調べてみるとどうやらjpeg画像をdecodeすると色のモデルがYCbCrとなるため、黒くなってしまう様でした。
なので、一度変換をかけてRGBAにしてから実行するとうまくいきました。

// 128x128のRectangleを作る
tmpRect := image.Rect(0, 0, int(imageMax), int(imageMax))
// 新しいRGBAの画像を作る
tmpImage := image.NewRGBA(tmpRect)
// subImageには切り出した画像が格納されている
// subImageのRectangleを取得する
b := subImage.Bounds()
// 同サイズのRGBAの画像を作成
m := image.NewRGBA(image.Rect(0, 0, b.Dx(), b.Dy()))
// draw.Drawを行うことでRGBAで出力される
draw.Draw(m, m.Bounds(), subImage, b.Min, draw.Src)
// pngとgifは透過色で塗りつぶす
// jpgには透過色がないため、白で塗りつぶす
if ext == ".jpg" || ext == ".jpeg" {
    draw.Draw(tmpImage, tmpRect, &image.Uniform{color.White}, image.ZP, draw.Over)
} else {
    draw.Draw(tmpImage, tmpRect, &image.Uniform{color.Transparent}, image.ZP, draw.Over)
}
// 左上からRGBAに変換したsubImageを描画する
draw.Draw(tmpImage, tmpRect, m, image.ZP, draw.Src)

こうして再度みると変換をかけなくてもdraw.Drawを通せばうまくいくような気もするのですが…
時間があったら調べてみたいとは思います。

感想

画像関連は何度かやっているため段々と分かってきた部分も多くなってきましたが、それでも毎回何かしらつまづいて学ぶことがあります。
今後も作ったら面白そうだなと思ったら積極的に作ってアウトプットして行こうと思います。