dondakeshimoの丸太

データサイエンス/Webアプリケーション/

WEBの入門書を読んでやったわ

WEBとはなんなのか

最近勉強しましたが、なんか凄いらしいですね、web。今回は上記のことを知るために以下の二冊をざっと読みました。

真面目に書くと、基本的にはwebではてなやらQiitaやらで調べてコーディングしたいんですけど、わからない単語とか仕組みとかが大量に出てくると面喰らうじゃないですか。だから準備としてその分野の入門に当たる書籍を読むのがいいかなと考えています。書籍のメリットは体系的にまとまったものが多いこと。筆者の責任感が強いこと。儲けたいがために頑張っていること。などです。逆にweb記事のメリットは最新の情報をただで得られることだと考えています。ということで、入門中の入門っぽいやつを読んでみました。

Webを支える技術

よかったところ

総評として、めっちゃよかったです!webの歴史、ブラウザ戦争、いろいろな規約やら何やら。基本的なことはこれで学べたと思っています。とりあえず、web関係のweb記事を読んでももう面くらわない!ってところまではきましたし、いまブログを書いているこの状況が何をしている状況なのかも理解できました。いまからサーバにPUTリクエストを送りつけてやりますよ!

よくなかったところ

よくなかったかなという点は、データフォーマットの話が結構長くて読むのが辛かった割には全く即戦力になる知識じゃなさそうだったことですね。あとはこの本を読んだからといって何かが作れるわけではないということも悲しいところです。

まとめると

前半だけ読んでおけば良い説浮上してますが、とってもよかったと思います!

Webアプリエンジニア養成読本

よかったところ

こっちは読みきったら即何かしらを作れることを目的に作られていました。作者が4編それぞれ違う人だったのも少し面白かったです。一番よかったと思うところは次に読むべき書籍が書かれていたことです。結局、書籍の推薦は主観ですし、書籍の良し悪しも主観なので、本を書くほど高名な方々の主観を知ることができるのはとてもよかったです。

よくなかったところ

全体的に浅めの記述で実践的でした。ここからは主観なのですが、浅めで実践的なものはweb記事で出回ってるので、本として買うのはあまりあれだなと感じました。もちろんとても丁寧で書いてある内容自体はとてもよかったです。これからの自分が買う書籍選びの軸の一つを気づかせてくれたということにします。

まとめ

とんでもないアイデア思いついて、とりあえず早く作ってみたい。もしくは、なーんもアイデアないけど、web関係の実践的知識はお遊び程度でほしいかなーくらいの人にはぴったりな気がしました。

以上

本読んで、気が向いたらまたレビューします!

vimをカスタマイズしてやったわ[set編]

筆者が設定しているsetコマンドを逐一説明して自分が忘れなくするための記事です

vimのsetコマンド

vimには4つのモードがあります。

  • ノーマルモード
  • インサートモード
  • コマンドモード
  • ヴィジュアルモード

これらのうちのコマンドモードにおいて

:set ~~~

となるコマンドが多数存在します。例えば、

:set number

と打ち込むと、左端に行数が出現します。

:set nonumber

と打ち込むと消えます。
おおおぉぉぉ!便利!ってなるコマンドが多数存在するのですが、vimを起動するたびに無数のsetコマンドなんて打ってられるだろうか?(いや、無理(反語))

そこで

前回も少し登場しました ~/.vimrcに気に入ったsetコマンドは打ち込んでいきます。~/.vimrcとはvimが起動されるたびに最初に読み込まれるファイルなので、ここに

:set number
:set ruler

とか打ち込んでおくと起動した時にはすでにnumberがsetされてしまっているということになるのです。これは、まさに、便利!

vimのsetと私

今回はここからスタートです笑

""""""""""""""""""""""↲
" plugin関係なし↲
""""""""""""""""""""""↲
" vimの見た目系↲
set ruler↲
set number↲
set title↲
set showcmd↲
syntax on↲
" 空白系↲
set autoindent↲
set smartindent↲
set shiftwidth=2↲
set expandtab↲
set tabstop=4↲
set ambiwidth=double↲
set list↲
set listchars=tab:»-,trail:-,eol:↲,extends:»,precedes:«,nbsp:%↲
" カーソル系↲
set whichwrap=b,s,[,],<,>↲
set backspace=indent,eol,start↲
set virtualedit=block↲
" ファイル操作系↲
set noswapfile↲
set hidden↲
set wildmenu↲
set backupdir=$HOME/.vimbackup↲
" 文字列系↲
set nrformats-=octal↲
" 検索系↲
set ignorecase↲
set smartcase↲
set hlsearch↲
set incsearch↲
set wrapscan↲
""""""""""""""""""""""↲

見た目系

ruler

右下に現在どの位置にいるかを示してくれる欄が出現します。便利なのでとりあえず入れとけ系ですね。

number

とりあえず入れとけ系第2弾ですね。左端に行数を入れてくれます。問題点を強いていえば、tmuxのコピーモードの時に邪魔です。

title

とりあえず入れとけ系第3弾!その名の通り開いているファイル名を表示してくれます

showcmd

確か一番下にちゃんとコマンドを表示するとかそんなんだった気がするけど…すみません!勉強不足というか、なんというか、とりあえず入れとけ系第4弾!!笑

空白系

autoindent

前の行のインデントと自動で合わせてくれます。わいは毎回tab押したいんやーーーーー!って人はオフにしておきましょう。デフォルトでonだそうです

smartindent

前の行の末尾の文字で勝手に判断してインデントをつけてくれます。これってautoindentと競合しないんだな。

shiftwidth=2

自動インデントでずれる幅です。師匠の2を受け継ぎました。

expandtab

tabを押してできた空白を半角スペースにするというものです。最初から書いてたんでアレなんですけど、この設定なかったらtab空白みたいな馬鹿でかい空白が生まれるんですかね。

tabstop=4

これはtabキーを押した時に半角スペース何個入れるかです。師匠の4を受け継ぎました。

ambiwidth=double

全角スペースを半角スペース二つに置き換える的なやつだった気がするぜ!

list

空白やら改行やらを可視化してくれるのである!地味に便利!

listchars=tab:>>-,trail:-,eol:↲,extends:>>,precedes:<<,nbsp:%

長い!空白文字を如何様にして可視化するかというやつです!

カーソル系

whichwrap=b,s,[,],<,>

折り返しでカーソル移動ができる!行頭でh押したら1行上の末尾に行ける!

backspace=indent,eol,start

backspaceキーをどこでも使えるようにするにはこの設定を入れねばならぬのだよ

virtualedit=block

空白行にもカーソルを移動できるようになるとかそっち系!よくわかってない!

ファイル操作系

noswapfile

なんかvimを使ってるとvimが勝手にswapファイルなるものを生成してるんですよ。鬱陶しくなったら作るな!バカ!と言ってやりましょう。

hidden

重複してファイルを開ける的なやつだった気がしますが、ちゃんと恩恵に預かったことはないです。

wildmenu

多分なんですけど、:eとかでファイル探してるとかに、中途半端なところでtab打って限界まで補完してくれた後、その後ろどうするって表示してくれるやつですね。便利

backupdir=$HOME/.vimbackup

backupファイルを作る場所を指定しております

文字列系

nrformats-=octal

0スタートの数字も10進数で扱ってください。普通の人間は16進数など使わんですよvimさん。

ignorecase

検索をかける時に大文字小文字の区別をなくしてくれるらしい!

smartcase

これをignorecaseと一緒に書いておけば、大文字を書いた時だけ大文字小文字を区別してくれるらしい!

hlsearch

high light searcdです。検索結果がハイライトされます

incsearch

インクリメントサーチができます。Google検索みたいに、Enter押す前から書き込まれてる分で検索を始めるやつです。

wrapscan

最後の検索結果から次に行くと最初の検索結果に飛びます。

以上

サクッと書くつもりが結構多くて、
しかもとりあえず書いてた的なの多すぎてこんな冗長で中身のない記事を書く結果となってしまいました。反省していま…せん。忘備録なので!笑

次回はプラグイン編ですかね!

vimをカスタマイズしてやったわ[初期設定編]

vimと私

読み飛ばしてくれて結構です。

vimについて超適当な感想

  • かっこいい
  • バカ早い,かつクソ早い
  • 初心者には敷居が高い(ゆえにかっこいい)
  • エディタ戦争でEmacsと殴り合っていたが現在優勢?
  • IDEに引けを取らない高機能(にできる)
  • 自分色に染められて楽しい
  • 使っていたら最もそれっぽい気がするエディタ
  • サーバをいじるなら、どうせ使わねばならぬ日が来ると言われた
  • 超かっこいい

vimと出会うまで

筆者は1年前まで助教授に勧められるままにEmacsを使っておりました。全くカスタマイズしていないありのままのイーマックスです。
そのような時にプログラミングの師匠と再開し、エディタは何を使っているか尋ねたところ、「最近はAtomがイカしてる」と言われました。早速使ってみたものの、筆者のPCが弱すぎて動作がもっさりしていたこと、卒論時期のコーディングはssh接続したLinux PCで行っていたことから、Atomを使うことをしばらく放棄していました。
卒論期を終え、本格的にプログラミングを始めることを決め、環境構築を始めました。その折、師匠にずっと相談していたのですが、「基本はAtomがオススメだけど、本気出すなら、iTerm + tmux + vimもあつい」と言われました。そんなんやるしかないやん。
vimって当時、gitで遊んでた時に突然出てきて、パニックにさせられてから多少嫌煙したんですけど、調べてみたら情報の嵐。こんなに使ってる人おるねんなと思ったら、勇気が出てきました。それから四苦八苦しながら設定して使ってみたらあら不思議、なんていうんですかね、「」ですかね。自分で作ったものだから使ってるだけで楽しくなってきて、現在vimmerとして生きてます

vimの導入

homebrewでインストー

ここからは忘備録、いや自分もほとんど忘れてるんですけど笑 次やるときのために最初から書いておこうかと

  • Mac OSX ElCapitan
  • Homebrew 1.2.4

macにはデフォルトでvim入ってるんですけど、何かいろいろちゃんとインストールしてきた方が都合いいらしいので、homebrew使って新しく入れました!

$ brew install lua
$ brew install vim --with-lua

PATHを通す

インストールした後、デフォルトのvimではなく、インストールしたvimを使うためにPATHを通す必要があるらしいです。まずはデフォルトのvimのPATHを確認

$ which vim
$ /usr/bin/vim

なんかシステム系の実際に使うやつとかはbinディレクトリーにだいたい入ってますよね。バイナリーの略らしいですね!(最近調べた)
うんちくは置いておいて、~/.bashrcに以下を追記します

export PATH=/usr/local/bin:/usr/bin

で、更新します

$ source ~/.bashrc
$ which vim
/usr/local/bin/vim

これでとりあえず味付け0のvimなら使えるようになりました

NeoBundle

NeoBundleとは

プラグイン管理ツールです。Pythonのpip、Rubyのgem、Macのhomebrew的な感じの理解で大丈夫なはずです!

NeoBundleダウンロード

まずはNeoBundleをダウンロードしてきす。…その前に忘れずにダウンロード先を設定しておきましょう。~/.vim配下にbundleディレクトリを作ってgitでどーんです!

$ mkdir -p ~/.vim/bundle
$ git clone git://github.com/Shougo/neobundle.vim ~/.vim/bundle/neobundle.vim

vimrcの設定

設定ファイルをいじっていきます。それっぽいです。
~.vimrcファイルに

set nocompatible
filetype plugin indent off

if has('vim_starting')
    set runtimepath+=~/.vim/bundle/neobundle.vim
endif

"""""""""""""""""""""""
" NeoBundle begin
"""""""""""""""""""""""
let g:neobundle_default_git_protocol='https'
call neobundle#begin(expand('~/.vim/bundle')) 
NeoBundleFetch 'Shougo/neobundle.vim'

" ここからプラグイン
NeoBundle 'Shougo/unite.vim'
" ここまで

call neobundle#end()
""""""""""""""""""""""
"NeoBundle end
""""""""""""""""""""""

filetype plugin indent on

まるまるコピペしちゃってください! 筆者が設定した時に世に溢れていた記述が少し昔のものだったので散々ここでエラー吐かれた記憶があります。もしかしたらすでに上記の設定も古い可能性があるのでその時はすみません。笑

[試しに] プラグイン「unite.vim」のインストー

さて、一旦 .vimrcを閉じましょう。
(vimで開いていて閉じ方がわからない!ってなったあなたへ(少し前の自分)【esc】 or 【Ctrl + [ 】でノーマルモードに入って、【:wq】で保存して閉じます。)
そして再起動、再び

$ vim

で起動してください。ここからNeoBundleを使います。

:NeoBundleInstall

はい、これでunite.vimインストール完了です!おめでとうございます!上記のインストールコマンドを打つと .vimrcに書き込んだプラグインの中から新しく書き込まれたものを見つけ、インストールしてくれます!

:NeoBundleUpdate

これでアップデートもできちゃいます!
いろいろな記事で

:NeoBundleClean

ってコマンドも見かけると思うんですけど、これは亡くなったらしいです。.vimrcから消したいプラグインの行を消去すれば、vim開始する時に読み込まれないらしいので、そのまま放置で良いと思われます。どうしても消したければ、NeoBundleがプラグインを溜め込んでるディレクトリまで潜って削除してこいとのことです!

お疲れ様でした!!

近日中に[set編]を公開します

公開しました

went-went-takkun135.hatenablog.com

よろしくお願いいたします!

GitHubが賢くて助かった話

dotfiles管理

dotfiles管理ってかっこいいなと思って、結構前にgithubにdotfilesレポジトリを作っていました。dotfiles管理が何かと言うと、各種設定ファイルをgitで一括管理してしまおう!というやつですね!設定ファイルのほとんどが.(ドット)から始まるのでこの呼び名というのは誰しもがそりゃそうだろという名ネーミングだと思います。メリットは

  • 設定ファイルをいじったけど昔の状態に戻したい時
  • 新しいパソコンでの環境構築を一発で終わらせたい時

これらのことがささっとできてしまうことですね!あとは友達にこの設定どうなってるん?って聞かれた時にURLをはっつけておけばいいのは楽かもしれないです!(初心者なのでそんなこと聞かれたことない笑)

筆者の愚行をGitHubが救ってくれた話

ここからがメインストーリーです。今回、awsのアクセスキーを環境変数に入れておいてという指令が私のインターン先からくだされ、教えに忠実に、

export ~~~

と.zshrcに直接書き込んだわけですね。そして、そのまま何も考えずに

$ git add .
$ git commit -m "~~~"
$ git push origin master

かましてやりましたね。全世界にawsのアクセスキー大公開ですよ。。。そしたらgithubさんから何やらメール!

Aws apikey exposed on Github message by GitGurdian

なんだなんだ。何かのスカウトか??全くーー!と思って読んでみて2秒で青ざめる顔。速攻でexportした場所消して平静を装いました。そんなに長いこと公開してないし、そもそも筆者のレポジトリに人が来ることあると思えないし、大丈夫だったと信じたいですね。
何にも大丈夫でなかったですね。awsのアクセスキーがロックされてしまったので多大なる迷惑をおかけしました。鍵の扱い本当に注意しなければ。。

みなさん!githubにパスワードとか絶対ダメですからね!!(いや、誰もせんやろ。。)

とはいえ、毎回awsキー打ち込むのは不便なので、~/.zshrc.awsというファイルを作成し、.zshrcないで

source ~/.zshrc.aws

とすることでその場をしのぎました。

TensorFlow Object Detection API の環境構築やってみたわ

巷で有名なtenso…..を使ってみたい!

完全なる環境構築の忘備録です。くだんのライブラリが何かと言うと、

developers-jp.googleblog.com

これですね!物体検出です!!強い!!すごい!!これはなんか使える環境だけ整えておいてドヤ顔したいですね!ということで、以下簡単な忘備録です

インストール手順

ここを参照しながら進めました!

github.com

Pythonのバージョン(pyenv)

機械学習なので当然のようにPythonなのですが、バージョンが3系だと3.5でないとダメらしいので、新しくpyenvからインストールしてきました。

$ pyenv install --list
$ pyenv install 3.5.3

とりあえず3.5で一番新しいのぶちこんどけばええやろ!と。

Protocol Bufferのインストー

これがなんなのかはよく調べてないですが、googleが提供している何かしのファイルと展開するやつかなと。すみません、めっちゃ間違ってそうです。インストールはhomebrewで一発!これは間違いない!

$ brew install protobuf

brewは基本的に最新版しか入らないので、3.3くらいが入ります。参照リンクによると2.6を入れろとのことなのですが、今の所3.3でも動いているのでよしとしています。やっぱり2.6が入れたいという方は、GithubやらGoogleのホームページからバイナリーファイルを拾ってきてコンパイルするか、homebrewでダウングレードするかですね!

Homebrewで旧バージョンをインストールする方法(brew verionsはもう使えない) - Qiita

依存ライブラリのインストー

筆者は使ってみたかったので、

$ pyenv virtualenv 3.5.3 tf_obj_det

で新しい環境を作ることにしました。とりあえず、Python3.5に依存ライブラリが入ればなんでもオッケーです。

$ pip install pillow
$ pip install lxml
$ pip install jupyter
$ pip install matplotlib

これで準備はあらかた整いました!いよいよ本体ダウンロード!

GithubからPull

github.com

このgithubアカウントからダウンロードしてきましょう。

$ mkdir tf_obj_det
$ cd tf_obj_det
$ git init
$ git pull https://github.com/tensorflow/models

あとは環境変数を整えてあげればオッケーです!

これはなんだろう…

# From tensorflow/models/
protoc object_detection/protos/*.proto --python_out=.

最初に言い訳していた、Protocol Bufferを使って何かをしています!笑

Python環境変数

$ export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim

シェルを立ち上げるたびに打ち込まなければダメらしいので、嫌だったら

~/.bash_profile
or
~/.zshrc

あたりに打ち込んでおけとのことです!

テスト

$ python object_detection/builders/model_builder_test.py

お疲れ様でした!これを使って何をするのか。オーライリーのDeep Learningを一読しただけの筆者にはまだあまりわかっていませんが、忘備録として残しておきます!!

Face API & Emotion API + Python 試してみた

巷で有名, Face API とは

Microsoftが提供しているMicrosoft Azure
その中のCognitive ServiceにあるFace APIが今回のターゲットです!

azure.microsoft.com

端的にいうと顔認識のweb APIですね。画像を渡すと、顔のある位置や年齢、顔のパーツの場所などをJSONファイルで返してくれるというものです。筆者、初めてAPIに触ったため多少ワクワクしておりました。それでは導入から行ってみましょう!

Face API導入

Microsoft Azure アカウント作成

Face API - 顔認識 | Microsoft Azure

とりあえず、このページの[無料アカウント]からAzureアカウント作成しました。クレジットカード情報記入とか結構めんどくさかった

Face APIAPI KEYを取得

Microsoft Azure

上記Azure Portalにて

  1. 左サイドメニューの[その他のサービス]
  2. 割と下までスクロールして[インテリジェンス+分析]グループ
  3. [Cognitive Service accounts]をクリック→[Face API]
  4. フォームはかなり適当に記入しました
  5. ダッシュボードに戻るなどして、先ほど自分が作成したリソースに飛ぶ
  6. 左から二番目のメニューバーのキーをクリックしたらジャーン

使ってみる

公式スタートアップ

Face API Python quick start | Microsoft Docs

最初に述べたように、自分がキーを取得した地域のurlにPOSTすることでJSONが返ってきます。APIってこういう感じなのだな。ふむふむ。

このQuick Startsの注意点
python2系とpython3系でかき分けているように見えるが罠です。 自分が使っている方だけ読めばいいわけではなく、

  • python2: urlを用いた画像の受け渡し方法
  • python3: バイト列を用いた画像の受け渡し方法

としれっと画像の渡し方を変えています。両方読みましょう笑

別の注意

https://docs.microsoft.com/ja-jp/azure/cognitive-services/face/quickstarts/python

上記ページは公式スタートアップに類似しているというか、本質的には同じはずだが、日本のページで(ja-jp)、なぜか必要なコードが消されているため要注意

公式リファレンス

Microsoft Cognitive Services

ここに詳細なデータの渡し方や返ってくる値が書いてある Face APIにある機能は大きく分けると

  • Detect: 顔の位置, パーツの位置など
  • Find Similar: 二つ画像を渡すと顔がどれだけ似ているかがスコアとして返される
  • Group: グループ分けしてくれる(まだ勉強不足)
  • Identify: (まだ勉強していない)
  • Verify: 顔認証, Detectと併用するらしい

cognitive_faceライブラリ

これ使うと、urllibとかrequestとかを勝手に使ってくれてて楽そう。 (日本語ドキュメントほぼ見つからないから英語か。。。) →Emotionの方で使えなさそうというか、これのライブラリの使い方で時間取られそうで本末転倒なのでこの子はスルー

Emotion APIについて

基本的にFace APIとほとんど同じことをすれば良い 違い

  • urlとAPIキーを変える必要がある
  • paramを空で渡す
  • cognitive_faceが使いない(ないし筆者が使い方わからない、ドキュメント不足)

くらいと思われます。

コード

Face API with local image file

import requests


url = 'https://westus.api.cognitive.microsoft.com/face/v1.0/detect'
headers = {
    'Content-Type': 'application/octet-stream',
    'Ocp-Apim-Subscription-Key': 'c1d3ab4f6c2j40ao4k1813bf24c8a7f',
}
params = {
    'returnFaceId': 'true',  # The default value is true.
    'returnFaceLandmarks': 'false', # The default value is false.
    'returnFaceAttributes': 'age,gender', # age, gender, headPose, smile, facialHair, and glasses.
}
if __name__ == '__main__':

    r = requests.post(url ,headers = headers,params = params,data = open("1643_fukada_kyoko.jpg",'rb'))

    print(r.text)

result

[{"faceId":"c43a79cd-6bb6-424d-91ef-2e143cf61444","faceRectangle":{"top":133,"left":198,"width":191,"height":191},"faceAttributes":{"gender":"female","age":27.2}}]

Emotion API with image url

import requests
import json

url = 'https://westus.api.cognitive.microsoft.com/emotion/v1.0/recognize'
image_url = "http://img.horipro.co.jp/wp-content/uploads/sites/17/2014/09/4efa1206c3ddde742caafee8af2a531e.jpg"
headers = {
    'Content-Type': 'application/json',
    'Ocp-Apim-Subscription-Key': '3c8a635a9b849dc2a5a72926222e25fd',
}

params = {}

payload = {
    "url": image_url,
}

if __name__ == '__main__':

    r = requests.post(url ,headers = headers,params = params,data = json.dumps(payload))

    print(r.text)

result

[{"faceRectangle":{"height":783,"left":339,"top":708,"width":783},"scores":{"anger":4.83580443E-05,"contempt":0.0011530855,"disgust":7.445373E-05,"fear":0.00015271669,"happiness":0.0037932964,"neutral":0.98582983,"sadness":0.00710687134,"surprise":0.00184137118}}]

こんな感じになります。 気をつけるところはurlで画像を送る時は

"Content-Type": "application/json"

localの画像を送る時は

"Content-Type": "application/octet-stream"

とすることと、urlの中のwestusの部分を自分がAPIキーを取得した地域に変えることですかね。 楽しそうなのでしばらくこれで遊んでます。

参考資料

azure-recipe.kc-cloud.jp

Python3 + ImageMagick

ImageMagick

画像処理を行う用事があり、それにこれを使うと良いと言われました。何かで見たことあると思ったらlatexをインストールした時についてきた気がする。使ったことなかったけど!

メリット

簡単に画像処理ができる!シェルコマンドでできる!つまりプログラミングと相性が良い!多分こんな感じです。

インストー

homebrewをインストールしていればこれで!

$ brew install imagemagick

Python + ImageMagick

基本

ImageMagickのコマンドをPython

subprocess.call(cmd, shell=True)

で実行させるだけです。
shell=Trueはsubprocessが行うコマンドをshell上で実行するというオプションなのですが、これが必要です。筆者はこれが必要であるということを調べるのに30分以上費やしました。cmdにコマンド文字列を作成していきます。
ImageMagickのコマンドは下記リンクを見て勉強しましたー!

imagemagick.rulez.jp

サイズ変更

def changeSize(image, scale):
    """
    画像のサイズを変更
    縦横比は変えずにパーセンテージで指定
    """
    cmd = "convert {} ".format(image)
    o_resize = "-resize {}% ".format(scale)
    o_out = "{}".format(image)

    cmd = cmd + o_resize + o_out

    res = subprocess.call(cmd, shell=True)

イメージとしてはこんな感じでやっていきます。

二つの画像の合成

def overlayImage(bottom_img, top_img, gravity="center", geometry=(5, 5)):
    """
    2つの画像の合成
    bottom_imgの上にtop_imgを乗せる
    """
    cmd = "convert " + bottom_img + " " + top_img + " "
    o_gravity = "-gravity {} ".format(gravity)
    o_geometry = "-geometry +{0[0]}+{0[1]} ".format(geometry)
    o_compose = "-compose over "
    o_composite = "-composite {}".format(bottom_img)

    cmd += o_gravity + o_geometry + o_compose + o_composite

    res = subprocess.call(cmd, shell=True)

二つの画像を合成しています。gravityが基準点を決めるオプションで、geometryが基準点からの位置決めオプションです。めんどくさかったらgravity northwest にしておけばgeometryで左上からの位置を決められます。

ダミー画像生成

def makeBackground(name="muji", color="DodgerBlue"):
    name = name + ".png"

    res = subprocess.call("convert -size 1200x810 xc:white {}".format(name), shell=True)

このコマンドで無地のダミー画像が作れます。地味に使うこと多そう

ライン描画

def drawStroke(image, coords=(0, 0, 0, 0), color="black", width=1):
    """
    幅と色指定のできる線描画関数
    """
    cmd = "convert "
    o_color = "-stroke {} ".format(color)
    o_width = "-strokewidth {} ".format(width)
    o_draw = '-draw "line {0[0]},{0[1]} {0[2]},{0[3]}" '.format(coords)

    cmd = cmd + image + " " + o_color + o_width + o_draw  + image

    res = subprocess.call(cmd, shell=True)

これでラインが描けます。coordsで座標を決めていますが、

-draw "line (X1),(Y1) (X2),(Y2)"

の順で座標をとり2点間に直線を引きます。
図形は他にもいろいろあったけど、これしか使っていない。。

横並びに結合

def appendImage(img_list):
    """
    画像を横並びに結合する
    しばらく使わないので放置
    """
    cmd = "convert +append "

    for img in img_list:
        in_file = "{}".format(i)
        cmd += inFile + " "

    cmd += "{}".format(img_list[0])

    res = subprocess.call(cmd, shell=True)

forループ!!プログラミング使ってる感出てきた!(これで終わり説)

+append

で横並びの結合

-append

で縦並びの結合(らしい)

文字の挿入

def insertWords(image, words, color="black", font="Meiryo", size="50"):
    """
    画像に文字を挿入
    色とフォントと文字サイズの指定可能
    挿入位置は画像下中央から10px上
    """
    cmd = "convert "
    o_point = "-pointsize {} ".format(size)
    o_font = "-font {} ".format(font)
    o_gravity = "-gravity south "
    o_annotate = '-annotate +0+10 "{}" '.format(words)
    o_fill = '-fill {} '.format(color)
    o_in = "{} ".format(image)
    o_out = "{}".format(image)

    cmd = cmd + o_point + o_gravity + o_font + o_annotate + o_fill + o_in + o_out

    res = subprocess.call(cmd, shell=True)

これは少し流派がありそうでした。label派とannotate派。先に見た方を選びました。

font-awesomeを使う

def makeFontAwesome(icon_name, color="black"):
    """
    font awesome のunicodeから画像生成
    色の指定可能
    生成画像サイズは400x400
    戻り値は画像の名前(相対パス名)
    """
    icon = 'printf "{}" | '.format(icon_name)
    cmd = "convert "
    o_size = "-size 400x400 "
    o_background = '-background "none" -fill {} '.format(color)
    o_font = "-font font-awesome-4.7.0/fonts/fontawesome-webfont.ttf "
    o_point = "-pointsize 200 "
    o_gravity = "-gravity center label:@- "
    o_out = "temp/{}.png".format(icon_name)

    cmd = icon + cmd + o_size + o_background + o_font + o_point + o_gravity + o_out

    res = subprocess.call(cmd, shell=True)

こいつはめちゃくちゃ苦労いたしました。基本的には下記リンク通り

www.nofuture.tv

とりあえずfont-awesomeのフォントをダウンロードしてきて、それを-fontで指定します。

font-awesome注意点

こいつを扱うときの注意点はズバリunicodeです。python3を使ってるから大丈夫と思っているみなさん、そんなこと言ってられなかった事案にぶち当たることもありました!何かと言うと、font-awesomeのunicodeを引数としてとってくる時に、標準入力などを用いると文字列がraw storingになっちゃうんですね。

\ufe03

これで地図の記号なのですが、標準入力まんま打ち込んでとってくるとpython上では

r"\ufe03"

という文字列になってしまいます。 何で困るって、この6文字で1文字を表すから画像表記できていたのに、6文字のまんま扱われたらfont-awesomeじゃないということです!(日本語が変)
これの解決策ですが、

fa = input()  #r"\ufe03"
fa = fa.encode("utf-8")  #b"\\ufe03"
fa = fa.decode("unicode-escape")  #"\ufe03" → □

一回バイト列に変換してから、decodeのunicode-escapeとかいうやつでもう一回unicode文字列(raw string でない)に戻しました。絶対もっとうまい方法あると思うので知ってる方いたら教えてください。。

まとめ

ここに書いた関数群をモジュール化したらのちにも使えそうだなぁ〜(どうするのかさっぱりわからんし、そんなことするくらいならもっと他に画像編集できるライブラリありそう)