文字によるセルフィー
🎨 AA(アスキーアート)を生成する
自分はアスキーアートに詳しいわけじゃないけど、アスキーアート自体は結構好きだ。
AA職人の手による芸術的なアスキーアートというのもあるのだと思うが、 これはもっと単純なやつ。
実際の画像をアスキーアートに変換するのは、超具体的に言うと以下のような仕組み。
- まず、使用する文字をリストアップして、「視覚的ピクセル密度」順にソートする。
- 視覚的ピクセル密度というのは、今テキトーに考えた言葉だけど、半角1文字空間に文字がレンダリングされたときのピクセルの数というか、例えば、黒背景に白い文字だった場合、遠くからみて白に近いもの
#とか$とかは密度が高い。 逆に,や.は密度が低い、というようなもの。 - 厳密にいうと、フォントによってかなり変わるので、ある程度は想定フォントを決める必要はある。
- 文字をこの密度が薄い -> 濃い の順で並べておく。
- 視覚的ピクセル密度というのは、今テキトーに考えた言葉だけど、半角1文字空間に文字がレンダリングされたときのピクセルの数というか、例えば、黒背景に白い文字だった場合、遠くからみて白に近いもの
- その文字の濃淡が何段階か数える。
# たとえばこれは 0-13 の14段階 [' ', '.', ':', ';', '+', '-', '=', 'c', 'o', 'w', 'O', '$', '8', '@'] - 画像を加工する
- 最初に、グレースケールに変換する。
- そしてできれば、境界線がわかりやすいように、いい感じにコントラストのカーブを調整する。
- 最後にそれを、先程の「視覚的ピクセル密度」順に並べた文字数分の階調に変換する。
- プログラムで画像のピクセルを読み込んで計算しても良いし、ffmpegコマンドでもできる。
#!/bin/bash set -e # convert video to grayscale with specified number of tones and resolution # usage: to_gray.sh input.mp4 output.mp4 [N] [WIDTH] [HEIGHT] INPUT="$1" # 入力ファイル OUTPUT="$2" # 出力ファイル N="${3:-24}" # 階調数(省略時 24) WIDTH="${4:-320}" # 出力横幅(省略時 320) HEIGHT="${5:-240}" # 出力縦幅(省略時 240) # 256 ÷ N(グレースケールの間隔)を計算 STEP=$(awk "BEGIN { printf \"%.6f\", 256 / $N }") # 実行 ffmpeg -i "$INPUT" \ -vf "format=gray,lut=y='floor(val/$STEP)*$STEP',scale=${WIDTH}:${HEIGHT}:force_original_aspect_ratio=disable" \ -y "$OUTPUT"
- グレースケール画像を文字に変換する
- 1ピクセルずつ読みこんで、対応する文字に変換する。
- 画像の右端まで来たら改行する。
- 等幅フォント( fixed width )で書く
- プロポーショナルフォントで書くと、1文字あたりの幅が違うので、当然、ぐっちゃぐちゃになる。
- HTMLだと、
<pre>...</pre>タグを使うのが良いと思う。 - ただ、スタイルに変な設定が入っていてうまくいかなかったり、文字サイズとか細かく指定したい場合は、直接スタイル指定する。
<!-- こんなふうにするとか --> <pre style="font-size: 0.6rem; letter-spacing: 0.01em; line-height: 1.01em;"> .:;+-=cowO$8@ .:;+-=cowO$8@ .:;+-=cowO$8@ </pre>
作成したセルフポートレート
88888$$$$$$$$$$OOOOOOOOOwc- :=owooooooooooooooooo=;++++=c=c 88888$$$$$$$$$$$OOOOOOw=. -=owooooooooooooooo=;++++=ccc 888888$$$$$$$$$$$OOOOw- +oooooooooooooooo=;++++=ccc 8888888$$$$$$$$$$$$OO; =woooooooooooooo=;+++==ccc 8888888$$$$$$$$$$$$$c -ooooooooooooooo=;+++==ccc 888888888$$$$$$$$$$w. cwwoooooooooooo=;++===ccc 8888888888$$$$$$$$$+ -wwoooooooooooo=;++===ccc 8888888888$$$$$$$$O: owwooooooooooo=;++===ccc 88888888888$$$$$$$w. cwwwoooooooooo=;++===ccc 888888888888$$$$$$o: =wwwoooooooooo=;=+===ccc 8888888888888$$$$$o :. =wwwwwoooooooo=;=+==cccc @888888888888$$$$$o .-;;:. cwwwwwoooooooo=;====cccc @@888888888888$$$$w. .==+;: :.. owwwwwwooooooo=;====ccco @@888888888888$$$$O: =wc=-: ::. . :wwwwwwwwoooooo=;====ccco @@@888888888888$$$O-:-owo=;:.:;;... ...=wwwwwwwwoooooo=;===cccco @@@888888888888$$$O+;+owc+-:-;c=:...::;owwwwwwwwwooooo=+==ccccco @@@@88888888888$$$$o-+wo=+;--;o=:..:::cwwwwwwwwwwooooo=+==ccccco @@@8888888888888$$$O+cwoc++-:-+;:..::-cwwwwwwwwwwooooo=+==ccccco @@@8888888888888$$$$wwwoc=+-:-:.. .::;owwwwwwwwwoooooo=+==ccccoo @@@8888888888888$$$$$wooc=+-;;;-....:;owwwwwwwwooooooo=+==cccooo @@88888888888888$$$$$Owoc=;+;+;:....:+wwwwwwwwwooooooo=+==ccccoo @@@8888888888888$$$$$$Owc=+-::. ..:=wwwwwwwwwooooooo=+==cccooo @@@8888888888888$$$$$$Owc=+::-:. ..-owwwwwwwwoooooooo=+c=cccooo @888888888888888$$$$$$OOo=+;-::....:.cowwwwwwooooooooo=+==ccccoo 888888888888888$$$$$$$O$Oc=+;;-..... =coooooooooooo=+c=ccccoo 888888888888888$$$$$$$$O+cc+;-::.... ;;+ccooooooooo=+==ccccoo 888888888888888$$88888O- +o=;-:::... :-;;++==ccooooo=+=cccccoo 88888888888888$$8@@@@$: =oc;-:::... .-;;;+++++==cooc=+=cccccoo 8888888888888$$$8@@@@O. woc+--:::. :-;;;+++++++++=oc=+=cccccoo 8888888888888$$$@@@@@O+ :ooo=;-:::..-;;;++++++++++++=c=+=cccccoo 888888888888$$$8@@888$w+-=oo=;--:::-;;+++++++++++++++=++=cccccoo 88888888888$$$8@@888$$Owc=cc=+;:-;-;++++++++++++++++++++=cccccco 8888888888$$$$888$$$$$$wwowwoc=cc=;+++++++++++;+++++++++=cccccco 888888888$$$$$$$$$OOOOOOOowwwocc=++=ccccc=++++;++++++++++=ccccco 8888888$$$$$$$OwwOOOOOOOOwooc=====coooooOo===+;==++++++;+=ccccco 888888$$$$$$$$OoowwOwO$OOwwwocoooowoowoOOocwo++c==+=++;;++===cco 888$$$$$$$$$$$$ooowO$$$$OOOOwwwowowoowwOOccOo;=ooc+=+;;;;++==cco 88$$$$$$$$$$$$$OoowO88$$OOwOOwwwwwwooww$w=oOc;cwwc+++;;;;;;+=cco $$$$$$$$$$$$$$$$Ooow88$$OOOOOOwwwwwowwOOo=wO=;oOo=;+;;;+;;;;+ccc $$$$$$$$$$$$$$$$$OO$@8$$OOOwOOwwwwwowO$Oo=wO++Owc+;;;;++;;;++=cc $$$$$$$$$$$$$$$OOOO8@8$$OOOwOOOwOwwowO$Oc=ww;=Oo=++;;;;;;;+==+=c $$$$$$$$$$$$$$OOOOO88$$$OOOwOOOwwwwowO$w==wo-owcc=+;;;+;;;+=c=+c $$$$$$$$$$$$OOOOOOO$8$$OOOOOwOOwwwwwO$Oo==wo-o=oc=;;;;+;;++co=;+ $$$$$$$$$$OOOOOOOOOO88$$OOOOwOOOwOwwO$Oo++wo-=;oc+;-;;+;;++co=;; $$$$$$$$OOOOOOOOOOOO$8$OOOOOwOOOwOwwO$Oc++oo-;:wo+;-;;;;;+=ow=;; $$$$$$OOOOOOOOOOwwwwO8$OOOOOOOOOOOOw$Owc++oo-:.oo+;-;;;;+=owo+;- $$$$$OOOOOOOOwwwwwwww$$OOOO$$OOwOOOwOOw=;;co-. co+;-;;;;=cwwc;-; $$$$OOOOOOOwwwwoccowwwwOO$$$$OOOOOwOOwo+;;=o;. oo+;-;;;+cowwc;;;