d.sunnyone.org
sunnyone.org

ページ

2012-07-29

ImageMagickで「本文ボールド化」っぽいことをする

スキャンした本達を加工しているのだが、バッチ的に加工したいので、ImageMagickで加工する方法を模索している。

概ね自分に必要なことはImageMagickでできそうなのだが、ChainLPについている「本文ボールド化」というのに相当するのが見当たらない。ImageMagickなら適当に操作すればできるだろうということでやってみた。

結論のコマンドは、以下のとおり。


どうしてこうなったのかがわからないと思うので、詳しいことは以下に書く。

方針
本文ボールド化の設定画面を見ると、XとかYがあって、それぞれ値を増やすと画像の黒い部分がそれぞれの方向に伸びる。 ということは、黒い部分を検出して、XとYに伸ばしているに違いないと読んだ。

これは、以下の方法でできそうなので、それをコマンドでやることにする。
  1. 画像をコピーする
  2. 黒検出する
  3. 1pixel移動する
  4. 元の画像に重ねる
実装
上述の方法を、ImageMagickのコマンドで実現するとこうなる。
convert input.jpg # input.jpgをロード
   '('                   # スタックの次の画像として処理開始
      +clone                   # 最後の画像をコピー
      -threshold 50%           # 50%を境に、白黒にする
      -alpha Copy              # 白黒の値(Value大=白なので、白っぽさ)をアルファチャンネルにコピーする
      -channel alpha -negate   # アルファチャンネルの値を、逆転させる(黒っぽさにする)
      -geometry +0+1           # 縦に1pixelずらす
        '('                    # スタックの次の画像として処理開始
            +clone             # 前の画像をコピーして
            -geometry +1-1     # 縦の1pixelを戻し、横に1pixelずらす
        ')'                    # スタックの現在の画像の処理完了
      +composite               # ひとつ前の画像を、その前の画像に結合
    ')'                        # スタックの現在の画像の処理完了
   +composite                  # ひとつ前の画像を、その前に画像に結合 
   output.jpg                  # output.jpgに出力

-threshold 50%は、結構悩んだ。最適解には思えないので、-levelとか、-black-thresholdとかをうまくあてこむともっとよくなると思う。

参考
さらっと書いているが、ここまでたどりつくのにだいぶ苦労した。いろいろなところを読んだのだが、一番近くなったのはここ。
ImageMagick 透過PNGを非透過な画像に変換する

まぁ、なんといっても公式が大事。-fxまで使えれば、特殊なアルゴリズムを必要としない、バッチ的な画像加工は概ねできるんじゃないかと思っているが、まだ使いこなせていない。
ImageMagick: Command-line Options

2012-07-12

片付けの基本方針とコンピュータのデータ管理

片付けについてTipsはよくあれど、原則というか、もっと基本方針的なものがあるに違いない、ということで、ちょっと片付けについて勉強してみた。

Tips集ではなく、片付け方針が書いてありそうな本ということで、この本をチョイス。

この本[もう片づけで疲れない収納法]には、概ねこんなことが書いてある(もっと書いてあるけど、自分に都合のいいところだけピックアップ)
  •  片付けをするのは、使うため(使いやすくするため)。
  •  身の丈にあった片付け方をする(人によって、家の広さも、片付けにかけられる時間も、収納にかけられるお金も異なる)
  •  収納指数(歩数+アクション数)を最小に(よく使うものほど近く)
このあたりから、これって、こんぴゅーたにおけるデータの管理の仕方の話じゃね?ということに思い当たる。
  • 保存しなければいけないのは、後で使うデータ。それ以外、さっさと解放したほうがいい。
  • indexをつけると検索(取り出し)は早くなるが、書き込み(収納)は遅くなる(=手間がかかる)。
  •  アクセスコストの低い装置(L1, L2, メインメモリ…)には、よく使うものを配置したほうが効率が良い。

とりあえずの基本方針として、以下を選定。
  •  不要なものは、きちんと捨てる(Garbage Collectionする)。
  •  人/場所/物に合わせた、検索効率と書込効率のバランスのとれた収納手段を選ぶ。
  •  アクセスコストの低い場所には、利用頻度が高いものを収納する。

何をもって必要と判断するか、というとても大きな問題が残っているけど、とりあえずは。継続性を考えるのが最優先課題である。

昔は「メモリは、机の広さみたいなもので、広い方がいい」なんていう話をよく聞いたけど、今は逆の発想で、「机の上(memory)は限度があるから、使っていない(recentにuseしていない)ものはしまう(page outする)」とか、そういった方向性で考えたい。

2012-07-05

vimでテキストを横に並べて同期スクロールする

二つのテキストファイルがあり、WinMergeのような比較ツールが役に立たない場合に、並べて比較したい場合がある。

そんなときは、gvimを使って、垂直ウィンドウ分割をした後、それぞれにファイルをロードし、それぞれで以下のコマンドを打つと、左右のウィンドウでスクロールが同期されて便利。
:set scb

中身が全然違っていて、ずれちゃったような場合は、テキストを入力してずらしてもいいし、以下のコマンドを打てば、スクロール同期が解除される。
:set noscb

本当はもっと汎用的な方法(エディタに依存しないとか)がありそう、というかそうしたいのだけど、とりあえず。

参考:http://edo.tumblr.com/post/10388828485/vim

2012-06-20

Gitで失敗コミット+修正コミットをひとつのコミットにする(git rebase -i)

gitを使っていて、間違ってコミットしたファイルを修正したコミットを、後からくっつける(正しく作ってコミットしたときと同じにする)方法。

概要としては、git rebase -iを使い、特定のコミットに戻した後、interactiveにコミットを操作する。

以下、手順。
1) 状態確認
git logで、状態を確認する。
$ git log --oneline
68af727 Write CCC                →でも他のコミットをしてしまった
719560b Write BBB (Retry)        →間違いに気づいてまたコミットした
92746af Write BBB                →ここでコミットしちゃったんだけど
585c5d6 Write AAA
84041cf Created initial files.

「Write BBB」で誤って、「Write BBB (Retry)」で修正をして、コミットしたのを、「Write BBB」に統合する。(Retry)の時点でうっかりamendを忘れた感じ。

2) rebase -iで「Write AAA」の時点に戻す
git rebase -iをすると、指定したコミットから後の処理をeditorで指定してリプレイできる。

$ git rebase -i 585c5d6

エディタが開くので、(Retry)の「pick」の部分を「f」に変更する。

pick 585c5d6 Write AAA
pick 92746af Write BBB
pickf 719560b Write BBB (Retry)  ←修正
pick 68af727 Write CCC

# Rebase 84041cf..68af727 onto 84041cf
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message ←fはfixup
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
「f」でなく、「s」にすると、コミットログを修正できる。

保存してエディタを終了すると、修正される。
[detached HEAD a7fb63f] Write BBB
 1 files changed, 1 insertions(+), 1 deletions(-)
Successfully rebased and updated detached HEAD.

3) 確認
くっついている。
$ git log --oneline
d519a6c Write CCC
a7fb63f Write BBB
585c5d6 Write AAA
84041cf Created initial files.

git本当に難しい...






ScanWebにスマートフォンUIとプレビュー機能を追加


前に「SheevaPlugを使ってScanSnap fi-5110EOXをネットワーク対応スキャナにする」という話で、簡単なWebUI (scanweb)を作ったが、以下の点が不便だったので、改良を加えた。思想はそのまま、作りはごっそり変更という形。

  •  スマートフォンからボタンが操作しにくい
    →jQuery Mobileを利用したスマートフォンインタフェースを実装
  • 結果がわからないので、裏表が間違っていたりしてもわからない
    →プレビュー機能を実装
launchpadのjunkに置いてあったが、launchpadのprojectを作るほどでもないので、githubに置いた。必要であれば、zipで落とすなりgit cloneするなりお願いします。
https://github.com/sunnyone/scanweb

操作イメージは、以下のような形。
スキャンを押してしばらくすると...↓
 プレビューとログが出力される。

生のWEBrickはしんどくなってきたので、Sinatraを使った。プレビューはどうしているかというと、pdfを作るときに、サムネイルの入ったzipファイルを作るようにして、Webから呼び出されたら中身のファイルを抽出して表示するようにしている。

jQuery Mobileは使いやすくて、↑の画面には装飾されたボタンなんかがあるけど、CSSやJSは全然書いてない。マークアップのルールにしたがっただけ。こういう適当なアプリでは、見た目は何も考えなくてよくなってすばらしい。

問題は、SheevaPlugが遅くて、スキャン後の後処理にかなりの時間がかかること。これは想定外だった...

2012-06-12

PowerShellをMSBuildから呼び出す

MSBuildは、MSの世界のAntのようなもの。そのMSBuildから、PowerShellのスクリプトブロックを呼び出す方法。

きれいな方法を目指すのであれば、PowerShell MSBuild Taskというものがあり、そのTaskを呼び出してPowerShellを実行すればよいのであるが、入っているdllが32bitであった。

32bit版MSBuildから呼べばいい話なのだと思うが、他のツールとの関連が面倒なので、本エントリでは安直にpowershellコマンドを呼ぶ方法を紹介する。

単純に書けば簡単で、Execタスクを利用して、powershell -Command "& { }" を呼び出せばよい(この表記については、PowerShell.exe コンソールのヘルプを参照。)

ただし、生で記述するとごちゃごちゃするので、MSBuildのPropertyGroupの中に、コマンドの始まりと終わりの文字列をPSBegin, PSEndなどとして定義し、ExecのCommand属性で$(PSBegin) $(PSEnd)などのように使うことで、ちょっときれいに書ける。
 
 例は以下のとおり。


上述のように、Invoke-Commandを使ってのリモートの呼び出しを塊にしておけば、リモート呼び出しもさっくり書ける。(リモートからPowerShellを呼ぶ環境を作るのが難しいのはまた別の話。)

参考:http://blog.brianhartsock.com/2009/10/20/using-powershell-scripts-from-msbuild-scheduled-tasks-etc/


まったく余談だが、勝手な要素をどんどん作っていくのがキモチワルイ...


2012-06-11

Javaっぽいスクリプト言語BeanShell クイックスタート

前のエントリとは打って変わって、今度はJava世界のお話。

BeanShellは、JavaVM上で動くスクリプト言語。Javaっぽい文法で、Javaのライブラリを利用することができる。簡単な説明はこちら:http://news.mynavi.jp/column/jsr/031/index.html

どうしてこれを使いたかったかというと、JMeterからBeanShellのスクリプトを実行することができるため、前処理等で好きな処理を実行することができる(らしい)ためである。
(ctxやvarsなど、JMeterからBeanShell側に渡ってくる変数から、JMeterのデータを操作することができる。らしい。これはまだ試してない。)

基本

マニュアルのQuick Startにある通り、bshのjarにクラスパスを通し、"bsh.Console"か"bsh.Interpreter"のクラスを動作させることで、実行することができる。
http://www.beanshell.org/manual/quickstart.html#Quick_Start

C:\temp> java -cp c:\opt\bsh\bsh-2.0b2.jar bsh.Interpreter
BeanShell 2.0b2 - by Pat Niemeyer (pat@pat.net)
bsh % System.out.println("Hello, World");
Hello, World
bsh %

bsh.Interpreterは、ふつうのインタプリタで、/bin/bashみたいなものだと思えばOK.
bsh.Consoleは、GUIつきのコンソールを出してくれる。そのため、Windowsでは、以下のようなバッチファイルを準備しておくと便利。



ファイルを実行

ファイルに書いたスクリプトを実行するには、bsh.Interpreterにファイル名を渡せばよい。ファイル名のあとにさらに引数を書くと、プログラム側のbsh.argsから取得できる。

c:\temp\sample.bsh




C:\temp> java -cp c:\opt\bsh\bsh-2.0b2.jar bsh.Interpreter c:\temp\sample.bsh FIRST-ARGUMENT
args[0]: FIRST-ARGUMENT

編集環境を作る

Eclipse上で動くEclipseShellを試してみたが、なにやらいまいちだったので、安直にサクラエディタを使うことにした。サクラエディタの設定 > タイプ別設定一覧からJavaを選択し、設定変更で「ファイル拡張子」にbshを加えれば、色づけはそれっぽく使える。

ツール>外部コマンド実行(Ctrl+F5)で実行できると便利なので、以下のようなバッチファイルを作成して実行できるようにする(~%4とかは適当。$@的に書く方法もあると思うが調べていない。)



あとは「外部コマンド実行」ダイアログから以下のように指定すればOK
C:\opt\bsh\bsh-interpreter.bat $F FIRST-ARGUMENT

ここまでわかれば、あとはJVMの世界なので、適当に使えると思う。