RMagickで画像の色情報をテキストデータに変換する

「手元に数千枚の画像ファイル(10×10ピクセル)があり、この画像のカラーコードをピクセル単位でテキスト化したい」
というググってもなかなか出てこなそうなことをやったので、メモしておこう。

こういうグレースケール化された画像から #CCCCCC みたいなカラーコードを取得したい

ImageMagickをインストールして、

~/rgb via 💎 v2.5.1 took 17m31s 
❯ convert A1516.jpg txt:
# ImageMagick pixel enumeration: 10,10,65535,gray
0,0: (257,257,257)  #010101  gray(1)
1,0: (514,514,514)  #020202  gray(2)
2,0: (771,771,771)  #030303  gray(3)
3,0: (771,771,771)  #030303  gray(3)
4,0: (771,771,771)  #030303  gray(3)
・
・
(略)
・
・
9,9: (257,257,257)  #010101  gray(1)

使い方あってるか知らないけど convert ファイル名 txt というのをやると、↑のようにピクセルごとの色情報が1行ごとに出力された。

とりあえず1ファイルを対象にして欲しい情報が取れることは分かったが、手元には数千ファイルあるので繰り返し処理したい。

しかしシェルスクリプトはよくわからない

Rubyで書けないかなー?

お、RMagickというのがある。ということで以下のスクリプトを書いて実行してみた。

require 'RMagick'

files = Dir.glob('*.jpg')
for file in files do
  file_name = file
  image = Magick::Image.read(file_name)
  image[0].write(file_name + ".txt")
end
実行すると画像ごとにtxtファイルが作成される
テキストの中身には欲しい情報がある

大量のテキストファイルができたので、今度はテキストファイルから欲しい部分を取得し、一つのテキストファイルに保存するスクリプトを書く。

files = Dir.glob('*.txt')
logfile = File.open('logfile.csv','a')
for file in files do
  File.open(file){|f|
    aaa = []
    aaa.push(f)
    f.each_line{|line|
      #カラーコード部分だけ抜き出す
      aaa.push(line.slice(/\#.*/).slice(1..2))
    }
    logfile.puts "#{aaa} \n"
  }
end

カラーコードのRGBのRだけ取得できればよかったので line.slice(/#.*/).slice(1..2) と書いた。

テキストファイルに

ファイル名 1ピクセル目のR値、2ピクセル目のR値、・・・100ピクセル目のR値

というフォーマットで記録していった。ここまでくればお得意のスプレッドシートの出番である。

これで必要なデータが並んだ表ができた。

ひとまずやりたいことは実現できたので良かったが、他に色々やり方ありそうなので今度同僚に聞いてみよう。

  • GASでできるかな?
  • javascriptのcanvasはどうだろう?
  • シェルスクリプトでやるには?

2019年最後のエントリがこれになるとは。

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください