RMagickでカレンダー壁紙をつくる
2G 時代ステーション(ソフトバンクモバイル、というよりもやはり J-Phone といいたいところかな、の自動配信とウェブ連動のサービス)で楽しみにしていた「キャラふぁくとりー」というのがあって、近年はそこで提供されるカレンダー壁紙を毎月張り替えて使っていた。常にカレンダーが見えるというだけでなく、オリジナルのキャラクターによる季節のイラストも愛らしくてよかったのだった。
ところがそろそろ新しいものをと見に行った 6 月末のこと、「6/26 でサービスを終了しました」といった内容のページだけが存在する状態に。
そういえばステーションはほとんどが 6 月一杯で終了するという話だった。
もっとも遠からずそうなることは予測できたので、無地の壁紙を事前にダウンロードしておいた。それを使ってカレンダーを作ることに。
さっそくにフォトショップエレメントあたりでやろうとしたが、なんだか面倒そうなので RMagick を使うことにする。
RMagick は ImageMagick という画像処理のためのツールを Ruby から使うためのもの。テキストを貼り付けていくこともできるようなので、さっそくもろもろインストール。Windows 用の RMagick のパッケージには、ImageMagick のバイナリーのインストーラーもセットされているので面倒は少ない。とはいえ、大量のメモリを必要とするようで、バイオノートへの RMagick のインストールの際になんどか NoMemoryERROR がでて失敗。やむなく仮想メモリを無茶な数値にしてなんとか完了。
ドキュメントやウェブの情報などを参考に、あれこれしていたらわりとあっさりとなんとか形になった。ただ、バージョンが古いものでは日本語がきちんと処理されていたようなのだが、現在のバージョンではうまく処理されない様子。どうやっても日本語は表示されない。フォント名の指定などでも全角文字があるとうまくいかなかったりする。
RMagick の FAQ によれば、「覚えておいて欲しいんだけれど、だいたいのトラブルは ImageMagick に起因するものなんだからね」といった感じのことが書かれていた(のだと思う)。
カレンダーを作成するにあたってはどうしても日本語(あるいは全角文字)が使えないと困る、ということではないので、ひとまずはシンプルに作ってみる。
プログラムで想定しているのは、無地(カレンダーがないという意味で)の壁紙画像( 240 * 320 )にカレンダーを重ねる。日付と月数。祝祭日は色分けする。といったところ。祝祭日を判定させるために date2/holiday をインストール。というか date2 そのもの。るりまによれば、現在は date2 は date に統合されたというのだが、さすがに日本固有の祝日判定部分は除外されているようで、標準添付にはなっていない様子。
実際にはカレンダー用ではないので、キャラクターの表情に重なってしまってくやしいところなどを調整するようにしたので、完成画像にするためには多少の細工が必要だけれど、基本はこれでいけるし、気にしなければこれで十分。なによりもいろいろ手間をかけずに毎月カレンダーを作成できるのが楽。その分、多少の調整はしようかとも思えるわけでもある。
難をいえば、元はイラストによる PNG 画像なので 8bit カラーで十分なのだが、ImageMagick で生成される PNG 画像は 24bit 固定の様子。ドキュメントを少しみた限りでは画像情報として取得することはできるが、生成するときに指定することはできない。ゆえにファイルサイズが大きくなってしまうのが難。まあ、大きいといっても程度の問題で、扱いに困るようなものではないのでよしとしているけれど。
遅ればせながら RMagick 面白いなあ、と思っているところ。
それにしても Ruby会議2007 でそんな講演があったのだなと今更ながら知ったけれど、頭のどこかですぐに RMagick が浮かんだのを思うと、案外そのときの刷り込みが効いていたのかもしれない。ありがたいことだ。
# == calkg.rb ==
require "rubygems"
require "rmagick"
require "date"
require "date/holiday"
def usage
print "usage: ruby calkg.rb base_picture_filename yyyy mm\n"
exit()
end
usage if ARGV.size < 3
base_picture = ARGV.shift
year = ARGV.shift.to_i
month = ARGV.shift.to_i
days_of_month = Date.new(year, month, -1).day
cal_img = Magick::ImageList.new(base_picture)
@cal = Magick::Draw.new
year_month = Date.new(year, month)
# xpos, ypos : 横方向の初期値, 縦方向の初期値
# xpitch, ypitch : 横・縦方向の文字間隔
# month_fig_xx : 月数の色、文字サイズ
# month_name_xx : 月名の色、文字サイズ
# date_fig_xx : 日付の文字サイズ
xpos = 35
ypos = 100
xpitch = Integer((240 - xpos * 2) / 6)
ypitch = Integer(160 / 4)
month_fig_color = "red"
month_name_color = "red"
month_fig_point = 50
month_name_point = 20
date_fig_point = 20
@cal.font("Times-New-Roman")
def text_print(cal, xpitch, w_day, xpos, ypos, text, text_color, text_point)
cal.pointsize(text_point)
cal.fill("white")
cal.stroke("white")
cal.stroke_width(6)
cal.text(xpitch * w_day + xpos, ypos, text)
cal.fill(text_color)
cal.stroke("none")
cal.text(xpitch * w_day + xpos, ypos, text)
end
# 月数を作成
text_print(@cal, 0, 0, 50, 60, "#{month}", month_fig_color, month_fig_point)
# 月英名を作成
month_name = year_month.strftime("%B")
text_print(@cal, 0, 0, 90, 40, month_name, month_name_color, month_name_point)
#
# 日付を作成
(1..days_of_month).each do |d|
w_day = Date.new(year, month, d).wday
#
# 日曜・祝日は赤色に、土曜は青色に、平日は黒色に
if Date.new(year, month, d).national_holiday?
text_color = "red"
elsif w_day == 0
text_color = "red"
elsif w_day == 6
text_color = "blue"
else
text_color = "black"
end
@cal.text_align(Magick::CenterAlign)
text_print(@cal, xpitch, w_day, xpos, ypos, d.to_s, text_color, date_fig_point)
#
# 日曜になったら改行する
ypos += ypitch if w_day == 6
end
# カレンダーを描画
@cal.draw(cal_img)
f_name = "cal" + year_month.strftime("%y%m") + ".jpg"
# 画像を保存
cal_img.write(f_name)
| 固定リンク
コメント