ImageMagickコマンドで画像ファイルを「座標+RGB値」のテキストに変換、またその逆もできる事を知ったのでその時のメモです。
これを使うメリットとしては、GDライブラリやRmagick、nodejsのcanvasパッケージといったライブラリをインストールしたり準備したりしなくても良いところと、簡単な画像処理ならテキスト処理するプログラムできてしまうところでしょうか。
##環境
試したのはLubuntu16.04です。LubuntuはOSをインストールしただけでデフォルトでImageMagickがインストールされますので、それをそのまま使っています。<2018/7/11追記>改めてみてみたらImageMagickはデフォルトではインストールされていませんでした。 sudo apt install imagemagick
でインストールする必要があります。
$ convert -version
Version: ImageMagick 6.8.9-9 Q16 x86_64 2017-05-26 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2014 ImageMagick Studio LLC
Features: DPC Modules OpenMP
Delegates: bzlib cairo djvu fftw fontconfig freetype jbig jng jpeg lcms lqr ltdl lzma openexr pangocairo png rsvg tiff wmf x xml zlib
##画像をテキストに変換
画像ファイルをテキストファイルに変換するように書くだけで座標とカラー値のテキストに変換できます。
$ convert test.png test.txt
###変換後のファイルの中身は?
変換されたファイルの中身は以下のような感じになります。見るとなんとなく分かるんですが、2行め以降にX座標,Y座標: (R,G,B) ...
という形式で保存されている事が確認できると思います。
$ cat test.txt
# ImageMagick pixel enumeration: 360,32,255,srgb
0,0: (255,1,1) #FF0101 srgb(255,1,1)
1,0: (255,7,1) #FF0701 srgb(255,7,1)
2,0: (255,7,1) #FF0701 srgb(255,7,1)
3,0: (255,13,1) #FF0D01 srgb(255,13,1)
4,0: (255,19,1) #FF1301 srgb(255,19,1)
5,0: (255,25,1) #FF1901 srgb(255,25,1)
6,0: (255,25,1) #FF1901 srgb(255,25,1)
7,0: (255,31,1) #FF1F01 srgb(255,31,1)
8,0: (255,37,1) #FF2501 srgb(255,37,1)
(以下省略)
###ファイルではなく標準出力に書き出す
ファイルに書き出さずに標準出力したい時は以下のようにします。この方法を使うと一時ファイルを作ることなくプログラムで処理することができます。例)f = open('|convert test.png txt:', 'r')
$ convert test.png txt:
###CMYKで取り出す
-colorspace
でカラースペースで変換することもできますので、以下のようにすればRGBではなくCMYKに変換した結果を取り出すことができます。
$ convert test.png -colorspace CMYK txt:
# ImageMagick pixel enumeration: 360,32,255,cmyk
0,0: (0,254,254,0) #00FEFE00 cmyk(0,254,254,0)
1,0: (0,248,254,0) #00F8FE00 cmyk(0,248,254,0)
2,0: (0,248,254,0) #00F8FE00 cmyk(0,248,254,0)
3,0: (0,242,254,0) #00F2FE00 cmyk(0,242,254,0)
4,0: (0,236,254,0) #00ECFE00 cmyk(0,236,254,0)
5,0: (0,230,254,0) #00E6FE00 cmyk(0,230,254,0)
6,0: (0,230,254,0) #00E6FE00 cmyk(0,230,254,0)
7,0: (0,224,254,0) #00E0FE00 cmyk(0,224,254,0)
8,0: (0,218,254,0) #00DAFE00 cmyk(0,218,254,0)
(以下省略)
###必要なところだけ切り出す
-crop
を使えば一部だけ取り出すこともできます。以下の例は(9,0)から2x2だけ取り出します。
$ convert color.png -crop 2x2+9+0 txt:
# ImageMagick pixel enumeration: 2,2,255,srgb
0,0: (255,37,1) #FF2501 srgb(255,37,1)
1,0: (255,43,1) #FF2B01 srgb(255,43,1)
0,1: (255,37,1) #FF2501 srgb(255,37,1)
1,1: (255,43,1) #FF2B01 srgb(255,43,1)
##テキストから画像に変換
今度は逆の座標とカラー値の書かれたテキストファイルを画像への変換を行ってみます。これも使い方は簡単でテキストファイルを画像ファイルへと変換するように書くだけです。
$ convert test2.txt test2.png
###テキストファイルの書き方
元となるテキストファイルは以下のような感じで書きます。1行目は注釈ですが必須となり# ImageMagick pixel enumeration:
の後の256,256,255,srgb
で横の長さ、縦の長さ、色数、カラースペースを指定します。
$ cat test2.txt
# ImageMagick pixel enumeration: 256,256,255,srgb
0,0: (0,0,0)
1,0: (0,0,0)
2,0: (1,0,0)
3,0: (1,0,0)
4,0: (1,0,0)
5,0: (1,0,0)
6,0: (2,0,0)
7,0: (2,0,0)
8,0: (2,0,0)
(以下省略)
###標準入力からもOK
標準入力から変換することもできます。
$ cat test2.txt | convert txt: test2.png
###カラーサンプルを描画してみる
この方法を使えばプログラムで画像ファイルを生成するといったこともできます。試しに以下のようなカラーサンプルを作るプログラムを書いてみました。
このサンプルは色相(Hue)0度から359度まで描いているだけのものです。簡単なサンプルなんですが、これをRGBで描こうとすると色相をRGBに変換する必要があったりしてちょい面倒な話となります。しかしImageMagickならカラースペースにHSVやHSL等が指定できるため、比較的簡単に作成することができます。
f = open("|convert txt: color.png", "w")
f.puts "# ImageMagick pixel enumeration: 360,32,255,hsl"
(0...360).each do |x|
(0...32).each do |y|
f.puts "#{x},#{y}: (#{x*100.0/360}%,100%,50%)"
end
end
f.close
Ruby じゃなくて bash + awk を使うなら以下のような感じかな。
seq 0 359 | awk 'BEGIN{print "# ImageMagick pixel enumeration: 360,32,255,hsl"}{for(y=0; y<32; y++) printf("%d,%d: (%4.1f%%,100%%,50%%)\n", $1,y,$1*100/360)}' | convert txt: color.png
##おまけ
ImageMagickでサポートされているカラースペースの一覧を取得する
$ convert -list colorspace
CIELab
CMY
CMYK
Gray
HCL
HCLp
HSB
HSI
(以下省略)
ImageMagickでサポートされているファイルフォーマットの一覧を取得する
$ convert -list format
Format Module Mode Description
-------------------------------------------------------------------------------
3FR DNG r-- Hasselblad CFV/H3D39II
AAI* AAI rw+ AAI Dune image
AI PDF rw- Adobe Illustrator CS2
ART* ART rw- PFS: 1st Publisher Clip Art
ARW DNG r-- Sony Alpha Raw Image Format
AVI MPEG r-- Microsoft Audio/Visual Interleaved
AVS* AVS rw+ AVS X image
BGR* BGR rw+ Raw blue, green, and red samples
(以下省略)
画像ファイルの情報を得る
$ convert test.png info:
test.png PNG 360x32 360x32+0+0 8-bit sRGB 869B 0.000u 0:00.050