クレーンゲームでとったトイデジからの写真取り込みとか
小学生の娘が自分用のデジカメが欲しいというので、そう言えば昔クレーンゲームでとったのがあるよと出してきたはいいけど、 PC に接続して写真を取り出すためのアプリが入ってた CD を処分してしまっていたので何とかしたメモ。
デジカメ本体はこんな感じ。本体には D:X DIGITAL とか DIGITAL CAMERA とか USB とか(笑)しか表示がなくて、ネットを色々探してみたけれど使えそうなアプリは見つけられず。 USB ケーブルを接続する端子も特殊?な感じだけどケーブルは奇跡的に発見。
Linux に繋げて lsusb してみると…
Bus 001 Device 006: ID 0979:0227 Jeilin Technology Corp., Ltd JL2005B/C/D Toy Cameraという表示。更にこれを手掛かりに探してみると、 gphoto を使うとカメラ内の写真を取り出せるっぽい!
早速 MacPorts で gphoto2 をインストールするけど、どうも最近 MacPorts でのインストールやアップグレードが失敗するなぁと少し調べてみると、どうもこういうことみたい。確かに Mavericks にしてから鴨。これまでバータリーに対処してきたのは無駄だったのね。 Homebrew だとこんなことないのかな? 取り敢えず手順通りに実行すると確かにエラーは出なくなったけど、やたらと時間がかかる。かかり過ぎる。カペルスキーインターネットセキュリティって奴を入れてから色々かなり重たくなってる実感があったので、試しにこれを無効にしてみると100倍速くなりますた。あくまで体感(笑)。 Parallels にバンドルされてたから使ってみてたけど、これを機会にサイナラします…。
gphoto2 を使ってコマンドラインから写真の取出しや削除ができる事は確認できたけど、さすがに小学生の娘にターミナルからコマンド入力させるのもアレなので簡単な GUI を Ruby/Tk でテキトーにこんな感じに。やっぱりマルチスレッドにするべきかなぁと直しかけたけど、使えないこともなさげなのでそのままに。やっつけなコードを恥ずかしながら置いときます。プログレスバーつけようとして志半ばな残骸もそのままに。あ、 gphoto2 と ppmtojpeg を内部で呼び出してます。あとは Automator を使ってアプリっぽく起動できるようにして出来上がり。
#!/usr/bin/env ruby # -*- coding: utf-8 -*- # tiny script to get all files from a JL2005B based toy camera require "tk" require "tkextlib/bwidget" require "fileutils" require "open3" CmdDetectCamera = "/opt/local/bin/gphoto2 --auto-detect" ValidCameraRegexp = /^ JL2005B/ CmdListFiles = "/opt/local/bin/gphoto2 -L" FileListRegexp = /^#(\d+)\s+(jl_\d+)\.ppm/ CmdCountFiles = "/opt/local/bin/gphoto2 -n" FileCountRegexp = /^Number of files.+:\s*(\d+)$/ CmdDelAllFiles = "/opt/local/bin/gphoto2 -D" # the camera does not support indivisual file deletion CmdGetPicAsJpg = "/opt/local/bin/gphoto2 --stdout -p %d | /opt/local/bin/ppmtojpeg > %s.jpg" ENV["LC_ALL"] = "C" HomeDir = ENV["HOME"] CameraDir = "#{HomeDir}/Documents/Camera" TkOption.add '*font', 'Wawati\ SC 18' class MainView def initialize @root = TkRoot.new do title "写真取り込み" minsize 300, 20 attributes "topmost", 1 end # build GUI @btnChk = TkButton.new(@root) do text "カメラチェック" pack("side" => "top", "padx" => "2", "pady" => "2", "fill" => "both") focus end @btnGet = TkButton.new(@root) do text "全部取り込む" state "disabled" end @btnDel = TkButton.new(@root) do text "全部消す" state "disabled" end @stsLabel = TkLabel.new(@root) do text "" state "normal" end # @pgsVar = TkVariable.new # @pgsBar = Tk::BWidget::ProgressBar.new(@root) do # variable @pgsVar # end @btnChk.command( proc {self.checkCamera} ) @btnGet.command( proc {self.getAllPix} ) @btnDel.command( proc {self.delAllPix} ) self.centerWindow() @btnChk.focus() Tk.update end def packChild(child) child.pack("side" => "top", "padx" => "2", "pady" => "2", "fill" => "both") end def unpackChild(child) child.unpack() end def centerWindow x = @root.winfo_screenwidth()/2 - @root.winfo_width()/2 y = @root.winfo_screenheight()/2 - @root.winfo_height()/2 @root.geometry("+%d+%d" % [x, y]) end def messageBox(type, icon, title, message) Tk.messageBox( "type" => type, "icon" => icon, "title" => title, "message" => message ) end def checkCamera # self.unpackChild(@pgsBar) self.unpackChild(@stsLabel) self.unpackChild(@btnDel) self.unpackChild(@btnGet) stdin, stdout, stderr, thread = Open3.popen3(CmdDetectCamera) stdin.close stdout.each { |line| if line =~ ValidCameraRegexp self.messageBox( "ok", "info", "OK", "サポートしているカメラが見つかりました。" ) self.packChild(@btnGet) self.packChild(@btnDel) self.packChild(@stsLabel) # self.packChild(@pgsBar) self.toggleButtons("normal") @stsLabel.text("処理を選んでください。") Tk.update return end } self.messageBox( "ok", "error", "エラー", "サポートしているカメラが見つかりませんでした。" ) end # # http://stackoverflow.com/questions/5781286/tkinter-how-do-widgets-update # def doPrintLabelSlowly(label, message) # text = label.text # text << message[0] # label.text(text) # if message.length > 1 # self.doPrintLabelSlowly(label, message[1 .. message.length]) # end # end # def setLabel(label, message) # label.text = "" # self.doPrintLabelSlowly(label, message) if message.length > 0 # end def getAllPix self.toggleButtons("disabled") @stsLabel.text("カメラ内の写真をチェック中…") Tk.update stdin, stdout, stderr, thread = Open3.popen3(CmdListFiles) stdin.close files = Array.new stdout.each { |line| if line =~ FileListRegexp num, file = [Regexp.last_match(1), Regexp.last_match(2)] # puts "#{num} #{file}" files << [num, file] end } stdin, stdout, stderr, thread = Open3.popen3(CmdCountFiles) stdin.close count = 0 stdout.each {|line| count = Regexp.last_match(1).to_i if line =~ FileCountRegexp } if count == files.length if count > 0 @stsLabel.text("%d 枚の写真が見つかりました。" % [count]) Tk.update dateTime = Time.now.strftime("%Y%m%d-%H%M%S") picDir = "#{CameraDir}/#{dateTime}" dir = FileUtils.mkpath(picDir).shift Dir.chdir(dir) { |dir| files.each {|file| stdin, stdout, stderr, thread = Open3.popen3(CmdGetPicAsJpg % file) stdin.close if thread.value.exitstatus != 0 self.messageBox( "ok", "error", "エラー", "#{file[0]} 枚目の写真の取得に失敗しました。\n全ての処理が終わってからもう一度試してみてください。" ) count -= 1 # failed else @stsLabel.text("#{file[0]} 枚目の写真を取り込みました。") Tk.update end } } self.messageBox( "ok", "info", "OK", "写真 #{count} 枚の取り込みに成功しました。" ) self.toggleButtons("normal") @stsLabel.text("#{count} 枚の写真を取り込みました。") Tk.update return else self.messageBox( "ok", "info", "OK", "写真が一枚もありませんでした。" ) self.toggleButtons("normal") @stsLabel.text("写真が一枚もありませんでした。") Tk.update return end end self.messageBox( "ok", "error", "エラー", "カメラ内の写真の確認に失敗しました。\nもう一度やり直してみてください。" ) self.toggleButtons("normal") Tk.update return end def delAllPix @stsLabel.text("全ての写真を削除します。") self.toggleButtons("disabled") Tk.update stdin, stdout, stderr, thread = Open3.popen3(CmdDelAllFiles) stdin.close if thread.value.exitstatus != 0 self.messageBox( "ok", "error", "エラー", "写真の削除に失敗しました。\nもう一度試してみてください。" ) else self.messageBox( "ok", "info", "OK", "全ての写真を削除しました。" ) @stsLabel.text("全ての写真を削除しました。") end self.toggleButtons("normal") Tk.update end def toggleButtons(state) @btnChk.state(state) @btnGet.state(state) @btnDel.state(state) end def mainloop @root.mainloop end end view = MainView.new view.mainloop()
2014年5月23日 (金曜日) パソコン・インターネット, 携帯・デジカメ, Mac 関係 | 固定リンク
| コメント (2)
| トラックバック (0)
Tweet




最近のコメント