写真

2010年03月29日

前に公開した「Jpegファイルを撮影日時で一括renameするスクリプト」を、RAW撮影したJPEGではない画像ファイルでも対象にできるように修正した。

CanonのRAWデータ.CR2という拡張子のファイルは、メタデータをTIFFと同じ構造で持っているらしい。
rubyのexifrライブラリは、TIFFとJPEGの両方に対応している。
そのためTIFFファイルとしてCanon RAW(CR2)ファイルを開くことで、メタ情報を読み込むことができた。

使い方も、以前のバージョンでは、対象とする画像ファイルの拡張子をプログラム内に手で埋め込んでいたが、今回、JPGとCR2の両方に対応するために、自動識別にした。
なので、整理したいファイルがあるディレクトリをカレントとして、下記のプログラムを動かすだけで、対象ファイル全てをrenameする。

imagefile_rename.rb

#!/usr/bin/ruby
#
# ファイルを撮影日毎にファイル名を変更する
#                               2010/03/04 Yasuki
#                               2010/10/05 Yasuki
#
require 'rubygems'
require 'exifr'
require 'date'

Dir::glob("*.jpg\0*.JPG\0*.cr2\0*.CR2").each { |orgfile|

  if orgfile.rindex( /jpg|JPG/ )
    @E=EXIFR::JPEG.new(orgfile)
    target_extension="jpg"
  else
    if orgfile.rindex( /CR2|cr2/ )
      @E=EXIFR::TIFF.new(orgfile)
      target_extension="cr2"
    else
      exit 1
    end
  end

  datestr = @E.date_time_original.to_s
  subsec  = @E.subsec_time_orginal.to_s

  if (datestr != "") then
    p datestr
    ary=DateTime.parse(datestr)

    directoryname=ary.strftime("%Y_%m_%d")

    if subsec.to_s=="" then
      newfilename="IMG_"+ary.strftime("%Y%m%d_%H%M%S")+
        "."+target_extension
    else
      newfilename="IMG_"+ary.strftime("%Y%m%d_%H%M%S")+
        "_"+subsec.to_s+"."+target_extension
    end

# Directory の作成
    if FileTest::directory?(directoryname) then
      newfilename=directoryname+"/"+newfilename
    else
      printf("creating directory %s.\n",directoryname)
      r=Dir::mkdir(directoryname) rescue 
        printf("don't create dir %s\n",directoryname)
      if r==0 then
        newfilename=directoryname+"/"+newfilename
      end
    end


    printf("mv %s %s\n", orgfile, newfilename)
    File.rename(orgfile, newfilename)

  end
}




sylphide_ffr31mr at 22:27コメント(2)トラックバック(0) 

2010年03月28日

今日は、野川公園に自転車を持ち込んで、二番目ちゃんの補助輪外し練習。
寒かったし、ちょっとだけ。
その後は、丘の湯へ。

 
EOS50D SP AF 90mm F/2.8 Macro 1:1 (1/125 f/4.0 ISO 125)

寒かったけど、春はしくしくと近づいてきていますね。

sylphide_ffr31mr at 22:29コメント(0)トラックバック(0) 

2010年03月25日

今日はネタもないので、過去の写真から。

IMG_2010_01_03_7235_500
EOS50D  EF28mm F1.8 USM  (1/40 f/2.8 ISO200)

こんなに大きいクマ、どれだけ売れるのだろう・・・。



sylphide_ffr31mr at 23:14コメント(0)トラックバック(0) 

2010年03月23日

川崎市の生田緑地の日本民家園を家族みんなで散歩してきた。

藁葺き屋根の古い民家を保存・展示している広い公園だ。



なんとも郷愁を感じる風景。日本人だな、と思う一時でした。



併設している科学館の屋外に展示されている蒸気機関車。
間近で見れるので、かっちょいいです。


sylphide_ffr31mr at 23:18コメント(0)トラックバック(0) 

2010年03月13日

久しぶりに天気のいい休日。
子供たちと、いつも行く公園に。
桜の木はまだまだでしたが、梅の木は三分咲きくらいか。

 

蜂も元気に働いておりました。

二番目ちゃんの自転車の補助輪を取って自転車の練習。
一番目ちゃんがよく教えておりました。


sylphide_ffr31mr at 20:23コメント(0)トラックバック(0) 

2010年03月12日

RMagickを使った画像処理プログラムシリーズ第3弾。
画像を指定した長さで切り取るプログラムを作った。

長さの指定は、ピクセル指定、原画像からの百分率(%)、得たい画像のアスペクト比(縦横比)の三種類が使える。
切り取りの基準となる場所は、中心か、四つ角のいずれかしか指定できない。もっと厳密に調整したいときは、画像処理ソフトを使うこと。(笑)



切り取る画像のピクセル長を指定する場合は、基点からの長さになる。

切り取る画像を原画像の縦横それぞれの辺の長さの比率を指示する場合は、以下のような指定となる。
 

縦と横の整数比を指定した場合、指定した整数比での長方形が原画像に内接し、かつ最大となる大きさを基点から算出する。
わかりにくいので、以下の図を見ていただきたい。

原画像が3:2であり、そこから4:3の画像を得たい場合、4:3のほうが正方形に近いため横幅が小い。そのため、横を一部削除することとなる。
最大の大きさの長方形を取るため、どのような比率を入力しても、縦か横のいずれかの辺は保持され、その辺を基準に得たいもう一方の辺の長さが決まる。
アスペクト比を気にするのは、印刷する場合が多い。紙と画像のアスペクト比が違うと、空白ができたり、思わぬところが切れたりする。
代表的な紙のサイズのアスペクト比を、ソースの末尾につけてあるので参照して欲しい。

SYNOPSIS
  rmk_trim.rb [OPTION] [FILE]
DESCRIPTION
-o結果を出力するファイル名(必須)
-l範囲指定の起点となる座標を示す。省略時は0(=中央)。
0:中心。切り抜く長方形の中心が、元画像の中心と一致する。
1:左上角
2:右上角
3:左下角
4:右下角
-p-x,-yで指定した値がピクセル数であることを示す。
-r-x,-yで指定した値がオリジナル画像の辺に対する百分率であることを示す。
x=yであれば、アスペクト比はオリジナル画像と同じになる。
-a-x,-yで指定した値が整数比であることを示す。(省略時は-a)
指定したアスペクト比の長方形が、オリジナル画像に内接する最大の大きさで切り抜かれる。
x=yであれば、アスペクト比は1:1となり、正方形の画像を得る。
-x n切り取りたい範囲の水平方向の長さを入力する。
単位は、上記オプション(-a,-p,-r)のいずれかで指定する。(必須)
-y n切り取りたい範囲の垂直方向の長さを入力する。
単位は、上記オプション(-a,-p,-r)のいずれかで指定する。(必須)

rmk_trim.rb
#!/usr/bin/ruby
# Image Triming
#   using RMagick
#               ver.0.1  2010/03/12 Yasuki
#
require 'RMagick'
require 'optparse'
require 'pp'
include Magick

class CommandLine
  attr_accessor:x, :y, :point
  attr_accessor:switch
  attr_accessor:inputfile, :outputfile

  def initialize
    @x=0
    @y=0
    @outputfile=""
    @switch="a"
    @point=0
  end

  def getPoint  # 数字で指定した場所から、gravityを返すメソッド
    case self.point
      when 0 then return Magick::CenterGravity     # 中心
      when 1 then return Magick::NorthWestGravity  # 左上
      when 2 then return Magick::NorthEastGravity  # 右上
      when 3 then return Magick::SouthWestGravity  # 左下
      when 4 then return Magick::SouthEastGravity  # 右下
    end
  end

end     # of Class CommandLine

#--------------------------------------------------
#
optionStruct=CommandLine.new

opt=OptionParser.new
  opt.banner="This program is triming cutter of a Image file."
  opt.version="0.1"

  opt.on("-x n","--width", "Width of a new image.") { |v|
    optionStruct.x=v.to_i
  }
  opt.on("-y n", "--height","Height of a new image.") { |v|
    optionStruct.y=v.to_i
  }
  opt.on("-o FILENAME", "--output", "Output file name.") { |v|
    optionStruct.outputfile=v
  }
  opt.on("-l n", "--point", /[0-4]/, "Stating point.") { |v|
    optionStruct.point=v.to_i
  }
  opt.on("-a", "--aspect", "The value is the Aspect ratio. ") { |v|
    optionStruct.switch="a"
  }
  opt.on("-r", "--ratio", "The value is the ratio. ") { |v|
    optionStruct.switch="r"
  }
  opt.on("-p", "--pixel", "The value is the pixels. ") { |v|
    optionStruct.switch="p"
  }
  opt.on_tail("-h", "--help", "Show this message.") { |v|
    puts opt
    exit 1
  }
  opt.on_tail("-v", "--version", "Show version.") { |v|
    puts opt.version
    exit 1
  }

opt.parse!(ARGV)
if ARGV[0]==nil then
  puts "The input file is not specified."
  exit 1
else
  optionStruct.inputfile=ARGV[0]
end

if optionStruct.outputfile=="" then
  puts "The output file is not specified."
  puts opt
  exit 1
end

if FileTest::exist?(optionStruct.outputfile) then
  puts "The output file is exist."
  exit 1
end

if optionStruct.x==0 || optionStruct.y==0 then
  puts "x and y is zero."
  exit 1
end

#puts "Option Parse..."
#pp optionStruct
#pp optionStruct.getPoint
#puts ""

#------------------------------------------------
#
# 画像ファイルの読み込み
img = Magick::ImageList.new(optionStruct.inputfile)
img.strip!                # EXIF情報の消去
originalx=img.columns
originaly=img.rows
puts "Input img: x=#{originalx}, y=#{originaly}, x/y=#{
 originalx/originaly.to_f}"
if optionStruct.switch=="a" then
  puts "requiment: #{optionStruct.x}:#{optionStruct.y} = #{
   optionStruct.x/optionStruct.y.to_f}"
end
if optionStruct.switch=="p" then
  puts "requiment: #{optionStruct.x}pt : #{optionStruct.y
    }pt = #{optionStruct.x/optionStruct.y.to_f}"
end
if optionStruct.switch=="r" then
  puts "requiment: #{optionStruct.x}%:#{optionStruct.y
    }% = #{(optionStruct.x/100.0)*originalx}pt:#{
    (optionStruct.y / 100.0)*originaly}pt = #{
    (optionStruct.x / 100.0)*originalx/
     ((optionStruct.y/100.0)*originaly)}"
end

# 計算開始時刻の取得
st=Time.now

# 切り抜き画像のサイズ決定
case optionStruct.switch
  # 整数比を与えられたときの、完成サイズの算出
  when "a" then
    originalAR=originalx/originaly.to_f
    cutAR=optionStruct.x/optionStruct.y.to_f
    if originalAR < 1 then
      if cutAR <1 then
        if originalAR < cutAR then
          width  = originaly * cutAR
          height = originaly
        else
          width  = originalx
          height = originalx * cutAR
        end
      else
        width  = originalx
        height = originalx * cutAR
      end
    else
      if cutAR >= 1 then
        if originalAR < cutAR then
          width  = originalx
          height = originalx * cutAR
        else
          width  = originaly * cutAR
          height = originaly
        end
      else
        width  = originaly * cutAR
        height = originaly
      end
    end

  # 辺に対する比率を与えられたときのサイズの算出
  when "r" then
    width=originalx*optionStruct.x/100
    height=originaly*optionStruct.y/100

  # 辺のピクセル長を与えられたとき
  when "p" then
    width=optionStruct.x
    height=optionStruct.y
end

# 切り抜きの実施
img.crop!( optionStruct.getPoint, 0, 0, width, height)

# 画像ファイルの出力
img.write(optionStruct.outputfile)

# 出力した画像の確認
img = Magick::ImageList.new(optionStruct.outputfile)
x=img.columns
y=img.rows
puts "Output img: x=#{x}, y=#{y}, x/y=#{x/y.to_f}"

# 計算時間の表示
puts "time=#{Time.now - st}sec"

exit 0

# 代表的なアスペクト比
#
# プリントサイズ  縦横比
# L              5:7
# DSC          3:4
# KG (はがき)   2:3
# ハイビジョン    9:16
# P (パノラマ)  1:2.85
# 2L            5:7
# DSCW        3:4
# 六切            4:5
# A5            1:√2
# 六切ワイド      2:3
# A4            1:√2
# 四切            5:6
# 四切ワイド      2:3
# 自分のデジカメ  2:3


sylphide_ffr31mr at 23:44コメント(0)トラックバック(0) 

2010年03月11日

RMagickを使った画像処理プログラムシリーズ第2弾
画像に文字を描くrubyプログラムを作った。

いや~難しかった。一週間くらいかかってしまった。(rubyを勉強しながら、一週間でできたのは、RMagickがよくできている証拠か・・・)

描くことのできる文字列は、画像のタイトルを想定したものと、作者のサインを想定したシグニチャの二種類。
タイトルについては、コマンドオプションで、フォントサイズ、色、縁取り色を指定できる。
シグニチャについては、毎回換えるものではないので、プログラムの初期値に埋め込む。
また、どちらも飾り付けとして、透明文字や影付き文字の指定もできる。

また、公開用画像を想定しているので、EXIF情報は消去している。

詳しい使い方は、以下のオプションの組み合わせを試してほしい。

しかし、オプション名がセンスなさすぎ・・・

例として、以下のコマンドを発行した結果。

$ rmk_text.rb -o korobotup.jpg -s 1 -t Corobot -d 2 korobot500.jpg

例の説明

-o korobotup.jpg 結果を出力するファイル名
-s 1 シグニチャの飾りを1(=透明文字)にする
-t Corobot タイトル文字列
-d 2 タイトルの飾りタイプは2(=影付き文字)
korobot500.jpg 元になる読み込む画像ファイル

オプション詳細

SYNOPSIS
rmk_text.rb [OPTION] [FILE]
DESCRIPTION
-o filename --output 出力ファイル名 (必須)
-s n --signature n 予め登録してあるシグニチャを付与する。nは装飾タイプ。nを省略した場合0。
0:通常の文字
1:浮き出た透明な文字
2:影付き文字
-c name --sigfill name シグニチャ文字の色名を指定する。装飾タイプが1のときは無視される。
-t strings --title strings タイトル文字列。-sを付けたときは省略可能。
-f name  --titlefill name
タトル文字の色。省略時Darkred。
-k name  --titlestroke name
タイトル文字の縁取り色。省略時縁取りなし。
-d n  --titledecoration n
タイトル文字の装飾タイプ。
0:通常の文字
1:浮き出た透明な文字
2:影付き文字
-p n --titlesize n
タイトルの文字の大きさ(pt) 省略時は40pt。
-l z --titleplace タイトルを表示する場所を表す。省略時は1(左上)。
0:中央  5:上
1:左上  6:左
2:右上  7:右
3:左下  8:下
4:右下

ソース

rmk_text.rb
#!/usr/bin/ruby
# Text paster
# using RMagick Ver.0.1
# 2010/03/05 Yasuki
#
require 'RMagick'
require 'optparse'
require 'pp'
include Magick

# 組み込み初期値
SIGNATURE = "まぁるいしっぽ\n http://www.maarui.doorblog.jp"
SIGNATURESIZE = 18
SIGSTROKE = "none"
SIGPLACE = 4
SIGNATUREFONT = "/usr/share/fonts/truetype/ttf-japanese-gothic.ttf"
#TITLEFONT = "/usr/share/fonts/truetype/ttf-japanese-gothic.ttf"
TITLEFONT = "/usr/share/fonts/truetype/thai/Purisa-BoldOblique.ttf"
TITLESIZE = 40
TITLEFILL = "Darkred"
TITLEPLACE = 1

# 文字列を画像化するために必要な属性クラス
# decoの意味 0:普通 1:透明色 2:影付き
#
class TextToImgProperty
attr_accessor :text, :pointsize
attr_accessor :stroke, :fill, :font
attr_accessor :place, :deco

def get_place # 数字で指定した場所から、gravityを返すメソッド
case self.place
when 0 then return Magick::CenterGravity # 中心
when 1 then return Magick::NorthWestGravity # 左上
when 2 then return Magick::NorthEastGravity # 右上
when 3 then return Magick::SouthWestGravity # 左下
when 4 then return Magick::SouthEastGravity # 右下
when 5 then return Magick::NorthGravity # 上
when 6 then return Magick::WestGravity # 左
when 7 then return Magick::EastGravity # 右
when 8 then return Magick::SouthGravity # 下
end
end
end

# TextToImgPropertyクラスの情報を使って、画像に文字列を貼り付ける手順
#
module TextPaste
def textpaste( i, s )
draw_obj = Magick::Draw.new
draw_obj.font = s.font #フォント指定
draw_obj.pointsize = s.pointsize #フォントサイズ
draw_obj.stroke = s.stroke #文字の縁取り色
draw_obj.fill = s.fill #文字色
draw_obj.gravity = s.get_place

case s.deco
when 0 then
draw_obj.annotate(i, 0, 0, 0, 0, s.text)

when 1 then
#透明文字の作成
draw_obj.fill = "black"
tempimg = Magick::Image.new( i.columns, i.rows )
draw_obj.annotate(tempimg, 0, 0, 0, 0, s.text)
tempimg = tempimg.shade( true, 310, 30 )
i.composite!( tempimg, 0, 0, Magick::HardLightCompositeOp)

when 2 then
# 影付き文字の作成
# 文字のフロント部分描画
imgSize = draw_obj.get_multiline_type_metrics(s.text)
frontImg = Magick::Image.new(imgSize.width+10, imgSize.height+10){
self.background_color = "none"
}
draw_obj.annotate(frontImg, 0, 0, 0, 0, s.text) {
self.gravity = CenterGravity
}

# 影の描画
draw_obj.fill = "#20202090"
shadowImg = Magick::Image.new(imgSize.width+10, imgSize.height+10){
self.background_color = "#ffffff00"
}
draw_obj.annotate(shadowImg, 0, 0, 4+s.pointsize*0.05, 4+s.pointsize*0.05, s.text) {
self.gravity = CenterGravity
}

# 影をぼかす
shadowImg = shadowImg.blur_channel(0, 1, AllChannels)

# 重ね合わせ
frontImg = shadowImg.composite(frontImg, Magick::CenterGravity, 0, 0, Magick::OverCompositeOp)

# 元の画像と重ね合わせ
i.composite!(frontImg, s.get_place, 10, 0, Magick::OverCompositeOp)
end

end
module_function :textpaste
end

# コマンドラインからのオプションを記録し整理するクラス
class CommandLineOption
attr_accessor :inputfile, :outputfile
attr_accessor :sigflag, :s_deco, :s_fill
attr_accessor :title, :t_fill, :t_stroke
attr_accessor :t_pointsize, :t_place, :t_deco

def initialize()
@inputfile=""
@outputfile=""
@sigflag=0
@s_deco=1
@s_fill="black"
@title=""
@t_stroke="none"
@t_pointsize=TITLESIZE
@t_place=TITLEPLACE
@t_deco=0
@t_fill=TITLEFILL
end
end

# オプションの解析の開始
optionStruct=CommandLineOption.new

opt=OptionParser.new
opt.banner="This program copies the text message and signature onto the image file."
opt.version="0.1"

opt.on("-o FILENAME", "--output", "Output file name.") { |v|
optionStruct.outputfile=v
}
opt.on("-s [n]", "--signature", /[0-2]/, "The registered signature is put.\n\t\t\t\t\tn is decoration type.") { |v|
optionStruct.sigflag=1
optionStruct.s_deco=v.to_i
}
opt.on("-c colorname","--sigfill", "The color name of the signature letters." ) { |v|
optionStruct.s_fill=v.to_s
}
opt.on("-t title","--title", "The title strings.") { |v|
optionStruct.title=v.to_s
}
opt.on("-f colorname", "--titlefill","The color name of the title letters.") { |v|
optionStruct.t_fill=v.to_s
}
opt.on("-k colorname", "--titlestroke","The color name of the title stroke.") { |v|
optionStruct.t_stroke=v.to_s
}
opt.on("-d n", "--titledecoration", /[0-2]/, "A decoration type of The title.") { |v|
optionStruct.t_deco=v.to_i
}
opt.on("-p pointsize", "--titlesize","The pointsize of the text letters.") { |v|
optionStruct.t_pointsize=v.to_i
}
opt.on("-l n", "--titleplace", /[0-8]/ , "Where is the message put? 0 is Center.") { |v|
optionStruct.t_place=v.to_i
}
opt.on_tail("-h", "--help", "Show this message.") { |v|
puts opt
exit 1
}
opt.on_tail("-v", "--version", "Show version.") { |v|
puts opt.version
exit 1
}

opt.parse!(ARGV)

# オプションとファイルのチェック
if ARGV[0]==nil then
puts "The input file is not specified."
exit 1
else
optionStruct.inputfile=ARGV[0]
end

if optionStruct.outputfile=="" then
puts opt
puts "The output file is not specified."
exit 1
end

if FileTest::exist?(optionStruct.outputfile) then
puts "The output file is exist."
exit 1
end

if (optionStruct.sigflag==0) && (optionStruct.title=="") then
puts opt
puts "No text."
exit 1
end

#puts "Option Parse..."
#pp optionStruct
#puts ""

#------------------------------------------------
#
# 計算開始時刻の取得
st=Time.now

# 画像ファイルの読み込み
img = Magick::ImageList.new(optionStruct.inputfile)
img.strip! # EXIF情報の消去

# titleの画像生成
if (optionStruct.title != "") then
titleProperty = TextToImgProperty.new
titleProperty.text = optionStruct.title
titleProperty.pointsize = optionStruct.t_pointsize
titleProperty.stroke = optionStruct.t_stroke
titleProperty.fill = optionStruct.t_fill
titleProperty.font = TITLEFONT
titleProperty.place = optionStruct.t_place
titleProperty.deco = optionStruct.t_deco

TextPaste::textpaste( img, titleProperty )
end

# Signitureの画像生成
if (optionStruct.sigflag==1) then
sigProperty = TextToImgProperty.new
sigProperty.text = SIGNATURE
sigProperty.pointsize = SIGNATURESIZE
sigProperty.stroke = SIGSTROKE
sigProperty.fill = optionStruct.s_fill
sigProperty.font = SIGNATUREFONT
sigProperty.deco = optionStruct.s_deco
sigProperty.place = SIGPLACE

# シグニチャとタイトルが重なった場合、シグニチャをずらす
if (optionStruct.t_place==sigProperty.place) then
sigProperty.place -= 1
if (sigProperty.place<=0) then
sigProperty.place=4
end
end

TextPaste::textpaste( img, sigProperty )
end

# 画像ファイルの出力
img.write(optionStruct.outputfile)
puts "created #{optionStruct.outputfile}"

# 計算時間の表示
puts "time=#{Time.now - st}sec"

exit 0



sylphide_ffr31mr at 22:52コメント(0)トラックバック(0) 

2010年03月06日

RMagickを使った画像処理プログラムシリーズ第1弾

指定した画像 を、回転もしくはリサイズして、指定したファイル名で保存するプログラムである。また、ブログ等への公開を想定しているので、EXIF情報を全消去する。

RMagickがよくできているので、実際の処理を記述しているのは、極わずか。はじめから2/3ほどは、オプションの解析やエラー処理ばかりである・・・。

 SYNOPSIS
rmk_resize.rb [OPTION] [FILE]

DESCRIPTION
-h 説明を表示。
-o 出力ファイル名を指定する。 (必須)
-x n 幅を(n)ピクセルに指定する。
-y n 高さを(n)ピクセルに指定する。
-f 縦横比を保持しない。
このオプションを指定せずに、-xと-yを共に指定した場合、アスペクト比を
    保持するために、-yは無視される。
-r r|l #<= RかLのどちらか
画像を90度回転させる。rは時計周り、lは反時計周り。
このオプションを指定した場合、-xと-yの意味は回転した後のサイズを意味する。
つまり、画像の回転はresizeより先に適用される。
また、-xや-yが指定されずに-rだけ指定された場合は、回転変換のみ行う。
rmk_resize.rb
#!/usr/bin/ruby
# Image File Resizer
#   using RMagick
#               ver.0.4  2010/03/11 Yasuki
#
require 'RMagick'
require 'optparse'
require 'pp'
include Magick

class CommandLine
  attr_accessor:height, :width
  attr_accessor:inputfile, :outputfile
  attr_accessor:rotate, :check

  def initialize
    @height=0
    @width=0
    @outputfile=""
    @rotate=""
    @check=0
  end
end     # of Class CommandLine

#--------------------------------------------------
# Do
option_struct=CommandLine.new

opt=OptionParser.new
  opt.banner="This program is resizer and rotater of a Image file."
  opt.version="0.4"

  opt.on("-x width(px)","--width", "Width px of a new image.") { |v|
    option_struct.width=v.to_i
  }
  opt.on("-y height(px)", "--height","Height px of a new image.") { |v|
    option_struct.height=v.to_i
  }
  opt.on("-o FILENAME", "--output", "Output file name.") { |v|
    option_struct.outputfile=v
  }
  opt.on("-r WAY", "--rotate", ["r","l"], "Image rotatate right or left.") { |v|
    option_struct.rotate=v
  }
  opt.on("-f", "--free", "The aspect ratio is made free. ") { |v|
    option_struct.check=1
  }
  opt.on_tail("-h", "--help", "Show this message.") { |v|
    puts opt
    exit 1
  }
  opt.on_tail("-v", "--version", "Show version.") { |v|
    puts opt.version
    exit 1
  }

opt.parse!(ARGV)
if ARGV[0]==nil then
  puts "The input file is not specified."
  exit 1
else
  option_struct.inputfile=ARGV[0]
end

if option_struct.outputfile=="" then
  puts "The output file is not specified."
  puts opt
  exit 1
end

if FileTest::exist?(option_struct.outputfile) then
  puts "The output file is exist."
  exit 1
end

puts "Option Parse..."
pp option_struct
puts ""

#------------------------------------------------
#
# 画像ファイルの読み込み
img = Magick::ImageList.new(option_struct.inputfile)
img.strip!                # EXIF情報の消去
x=img.columns
y=img.rows
p "Input img: x=#{x}, y=#{y}"

# 計算開始時刻の取得
st=Time.now

# 回転の実施
case option_struct.rotate
when "r" then
  img=img.rotate!(90)
when "l" then
  img=img.rotate!(-90)
end

# リサイズの実施
if (option_struct.width!=0) || (option_struct.height!=0) then 
  if option_struct.check==1 then
    img.resize!(option_struct.width,option_struct.height)
  else
    img.resize_to_fit!(option_struct.width, option_struct.height)
  end
end

# 画像ファイルの出力
img.write(option_struct.outputfile)

# 出力した画像の確認
img = Magick::ImageList.new(option_struct.outputfile)
x=img.columns
y=img.rows
p "Output img: x=#{x}, y=#{y}"

# 計算時間の表示
p "time=#{Time.now - st}sec"

exit 0




sylphide_ffr31mr at 00:42コメント(0)トラックバック(0) 

blogに投稿したりする画像を処理することは、ほとんど決まっている。 サイズの変更や、回転などだ。
その定型処理のために、いちいち画像編集ソフトを立ち上げるのは面倒だな、とか思ってみた。

rubyのライブラリ"RMagick"という、すばらしい画像編集ライブラリがある。 コマンドラインで画像処理をするプログラムImageMagickをrubyから扱うことができるライブラリのようだ。 それを使って、rubyで簡単に定型的な画像処理をするプログラムを作っていこうと思う。

# imagemagickをコマンドラインから直接たたけばいいじゃん、というツッコミは却下です。

rubyの勉強のための意味合いが強いので、わかりやすさを心がけて、単機能のプログラムを、複数作成することにする。 作るプログラムは、以下の3つ。

現時点で、リサイズツールができたので、次の記事で使い方とソースを示す。
残りは、出来次第、公開していく。

Rmagickのインストールには、いろいろトラブルが多いようだ。
ubuntu10.04に入れる手順は、以下。

% sudo apt-get install libmagick++-dev
% sudo gem install rmagick

 



2010/10/23 追記
上記3つのソースを、githubで公開しました。
http://github.com/yasuki/rmagick-tools

2010/03/12 追記

トリミングするプログラム完成。

2010/03/11追記
画像に文字を描くプログラム完成。


 



sylphide_ffr31mr at 00:38コメント(0)トラックバック(0) 

2010年03月04日

最終版は、以下のURLです。
http://maarui.doorblog.jp/archives/2963486.html


前に公開した「Jpegファイルを撮影日時で一括renameするスクリプト」を、iPhoneなどのデジカメに対応できるように、若干調整した。

変更点は、”subsec_time_orginal”がない場合でも、エラーにせず通過できるようにしたこと。 1秒以下の時刻が記録されていないiPhoneや他のデジカメでも使えるはずだ。 詳しい使い方は、前の記事と同じである。


imagefile_rename.rb
#!/usr/bin/ruby
#
# ファイルを撮影日毎にファイル名を変更する
# 2010/03/04 Yasuki
#
require 'exifr'
require 'date'

# ターゲット拡張子の指定
#target_extension="jpg"
target_extension="JPG"

# カレントディレクトリ内の対象ファイル毎にループ開始
Dir::glob("*."+target_extension).each { |orgfile|

# 画像ファイルの読み込みとオブジェクトの作成
@E=EXIFR::JPEG.new(orgfile)

# EXIFから日時の読み取り
# EXIF項目名を変えるのは、以下。
datestr = @E.date_time_original.to_s
subsec = @E.subsec_time_orginal.to_s

if (datestr != "") then
# 英語表記の日付文字列を数字表記に変える
p datestr
ary=DateTime.parse(datestr)

# 日毎ディレクトリ名の取得
directoryname=ary.strftime("%Y_%m_%d")

# 新しいファイル名の作成
if subsec.to_s=="" then
newfilename="IMG_"+ary.strftime("%Y%m%d_%H%M%S")+
"."+target_extension
else
newfilename="IMG_"+ary.strftime("%Y%m%d_%H%M%S")+
"_"+subsec.to_s+"."+target_extension
end

# 日毎Directoryの存在チェックと作成
if FileTest::directory?(directoryname) then
newfilename=directoryname+"/"+newfilename
else
printf("creating directory %s.\n",directoryname)
r=Dir::mkdir(directoryname) rescue
printf("don't create dir %s\n",directoryname)
if r==0 then
newfilename=directoryname+"/"+newfilename
end
end

# renameの実行
printf("mv %s %s\n", orgfile, newfilename)
File.rename(orgfile, newfilename)

end
}


sylphide_ffr31mr at 19:20コメント(0)トラックバック(0) 
記事検索
最新コメント
プロフィール

やすき

月別アーカイブ
  • ライブドアブログ