この記事は、Clojure Advent Calendar 2011の5日目の記事です。
Clojure界隈では、というより他でもWeb系のいろいろが沢山なわけですが、仕事がそっち系でないのでそういう指向があまりないのです。
Clojureは今のところ趣味で、主にProject Eulerとか解くのに使っているわけですが、以前、デスクトップアプリ作ってみたのでその時のことを。
環境
---------------------------------------
- マシン
自宅ではLinux機メインでやってますけど、仕事ではWin機です。
- エディタ
いつもはエディタとしてxyzzyを使っているのですが、Clojureを使うには環境があまり整備されていないし(自分でなんとかしろ?ですよねぇ。)、ClojureBoxってのがあるようなので、入れちゃうことにしました。
でも、もうメンテされていないので、1.3.0にしたければ自分でやることになります。 あまり手間もかからないとは思いますけど、そろそろ自分で一から環境作ってもいいかなと思ってます。
- shell
Leiningen使うにはコマンドラインを使うのですが、Winのcommand.comはとても使えたものじゃありません。cygwinとかmsysとか入れたらいいんでしょうけど、それはちょっとだったので、PowerShell使うことにしました。PowerShellが入っていなかったので入れました。
emacsからPowerShellを使いたいので、PowerShell-modeをここを読んで入れました。
設定して起動したらと、"unrecognized shell program" って怒られます。特に問題無く動くんのでしばらく無視してたんですが、やっぱり気になって調べてみたら、ClojureBox/emacs/emacs/lisp/shell.el で出しているメッセージで、コーディングシステムを設定しているところでした。
command.comと同じ設定でいいだろうということで、PowerShell用の設定を追加して黙らせました。
587行目あたり
(cond
((w32-shell-dos-semantics)
(set-process-coding-system proc cp-out-dos cp-in-unix))
((string-match "/msys/" fullprog)
(message "think it is MSYS...")
(set-process-coding-system proc cp-locale-dos cp-locale-unix))
((string-match "/cygwin/" fullprog)
(message "think it is Cygwin...")
(set-process-coding-system proc cp-locale-dos cp-locale-unix))
;; 以下3行追加。
((string-match "powershell.exe" fullprog)
(message "think it is Powershell...")
(set-process-coding-system proc cp-out-dos cp-in-unix))
(t
(message "unrecognized shell program yosi: %s" fullprog)))))))
準備
---------------------------------------
- GUIツール
これまでJavaとか華麗にスルーして生きてきて、つい最近androidのアプリが作りたくて初めて触ったような人なので、awtとかswingとかちんぷんかんぷん。とてもそのままでは作れる気がしません。で、ちょっと調べてみたらよさそうなのがあるではないですか。
seesaw
Seesaw is a library/DSL for constructing user interfaces in Clojure. It happens to be built on Swing, but please don't hold that against it.
SeesawはUIを作るためのライブラリー/DSLで、Swingの上に構築されていますが、Swingがだめだというわけではありません。
メイン
https://github.com/daveray/seesaw
使いかた
https://github.com/daveray/seesaw/wiki
-プロジェクトの作成
1. Leiningenで新しいプロジェクトを作ります。
lein new guitest
cd guitest
2. project.cljを編集してseesawを追加します。
(defproject guitest "1.0"
:description "Seesaw test project, and more."
:dependencies [[org.clojure/clojure "1.2.1"]
[org.clojure/clojure-contrib "1.2.0"]
[seesaw "1.0.7"]] ;; 作ったときはこれが最新だった。
:main guitest.core) ;; スタンドアロンにするにはこれが要る。
これで準備は終り。
作成
---------------------------------------
「画像処理おもしろそう」と思って作ったアプリがあるのでこれについて。
GUIが目的ではないので見た目とか適当です(なんのこっちゃ)。
★★
って書いておいて、動かしてみたら動かない。
処理を早くしようとか、保存できるようにとかしてる途中だったみたいです。
次の番が回ってくるまでに動くようにしときます。*_*;;;;;;
動いていたときの画像。
- ソース (github)
https://github.com/ypsilon-takai/clojure-seesaw-test001
苦しまぎれに、解説なんかを。 いや、自分用に...
こうした方がいいんじゃない?ってなことがあれば、ご指摘いただけるとうれしいです。
core.clj
----------------------
UI部分。画像の読み込みと表示。
画像処理部分は、別ファイル (imagetool.clj)
14行目
* 元画像BufferedImage と 表示用画像BufferedImage と 画像処理用long-array など
書き換えるのでmutableなデータになってます。
23-38行目
* 入力画像の選択/結果の出力ダイアログ。
seesawのダイアログを使ってるだけ。
43-78行目
* 新しい画像を読み込んだときの処理関数たち。
下の2つが、新しいデータを作る関数と、データを再表示する関数。
81-87行目
* 画像を保存する関数たち。
91-140行目
* 画像処理関連
配列からBufferedImageを作る関数。
グレースケール化とエッジ検出の処理を呼ぶ関数。
141行目からGUI関連
147-216行目
* 各ボタンの定義。 actionはそのためのseesawの関数(マクロ?)です。
押されたときの関数を定義したり、ボタンに表示される文字列を設定したりします。
Clojure流に設定できるので、気持いいです。
218行目
* ウィンドウの定義です。
実行すると、ウィンドウのフレームを返します。
:content で中を定義します。
これもClojure流に設定できます。
248行目
* このクラスのメイン関数です。
projectファイルでこのファイルをmainとしているので、jarを実行したときに、この-main関数が呼ばれます。
native! を呼んでおくと、見た目がプラットフォームのものになるそうな。
上で定義したmain-windowに show!してやると表示されます。
imagetool.clj
----------------------
前半はたいしたことやっていないので割愛。
72行目からがエッジ検出のところです。
いくつかの種類のフィルタを使えるようにしてあります。
create-operationは、フィルタを与えると、どうすればいいかを返します。
transform-to-edge-imgは、画像のデータの入った配列と変換の種類を受け取って、変換後の配列を返します。
0 コメント:
コメントを投稿