Android ZXingを使ったバーコードリーダのコーディング

昨日はずっと、フリーライブラリZXingを使ったバーコードリーダの作成に関して試行錯誤してました。
忘れないようにメモ書きも兼ねてアップしておきます。

画像



木南さんの著書「GoogleAndroidアプリケーション開発入門」にカメラとバーコードリーダのサンプルがあるのでこれをベースに作業しました。

バーコードリーダはZXingを使用、以下からダウンロードが出来ます。
http://code.google.com/p/zxing/downloads/list
最新は1.3

1、まずはビルド
GettingStartedに手順が書いてあります。
http://code.google.com/p/zxing/wiki/GettingStarted

Antが必要です。
http://ant.apache.org/bindownload.cgi
あたりから落として展開、AntのBINにパスを通しておきます

ダウンロードしたZXingを解凍してcore.jarをビルドします。
cd core
ant
とANTを実行すれば、coreの下にcore.jarが出来ます。これをコピーして使えば良いでしょう。

2、コーディング
DeveloperNotesによれば
http://code.google.com/p/zxing/wiki/DeveloperNotes

Reader reader = new MultiFormatReader();
BufferedImage myImage = ...;
MonochromeBitmapSource source = new BufferedImageMonochromeBitmapSource(myImage);
Result result = reader.decode(source);

となっています。
カメラで取り込んだ画像をbyte型からBufferedImage型に変換して、MonochromeBitmapSourceをオブジェクトを生成して、MultiFormatReaderのdecodeメソッドを呼べば結果が得られるところまで分かりました。
しかしこっからが大変でした。
一般的なJavaのコーディングだと
byte[] buf;→カメラから取り込んだ画像
BufferedImage image = ImageIO.read(new ByteArrayInputStream(buf));
とすれば良いようですが
BufferedImageがAndrodでは使えません。
以下の情報をMLで見つけました。
-------------------------
http://groups.google.co.jp/group/android-group-japan/browse_thread/thread/cc67e0fb48c8c3fc
JDKに含まれていて、Android-SDKに含まれないクラスがjar内に使われている場合、 当該箇所をAndroid-SDKで表現するように置き換える必要があるという意味です。
例えば、jar内にjava.awt.image.BufferedImageクラスが使われている場合、 Android-SDKではこのクラスを含んでいませんので、このクラスを使わないようにパッチをあてる必要があります。
-------------------------
JDKの全てがAndroid-SDKの全てで使えるわけではないようです。
ここでは例としてjava.awt.image.BufferedImageが挙げられていますが、まさにこれです。
なので、BufferedImageを使わないで実装しないといけないです。

色々探した結果、ZXingのフォルダの配下
zxing\androidtest\src\com\google\zxing\client\androidtestRGBMonochromeBitmapSource.javaを見つけました。
これを使えばBitmapはAndoridでもサポートされているのでいけそうです。
ということで、

BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inSampleSize = 8;

//カメラ画像からBitmapを作成する
Bitmap bitmap = BitmapFactory.decodeByteArray(image_data, 0, image_data.length,opts);
//BitmapからMonochromeBitmapSourceを生成する
MonochromeBitmapSource source = new RGBMonochromeBitmapSource(bitmap);
//画像を分析してバーコードを取得する
bardode = mMultiFormatReader.decode(source);

として、何とかバーコードを取得できました。
注意点としては
1、AutoFocusの使用
AutoFocusを使わないとピントが合ってない画像になるため正しく分析が出来ずにmMultiFormatReader.decodeからのリターンがNULLになる。

2、Bitmap生成時に間引き作業を行う
カメラからの画像をそのままBitMapにしてdecodeを呼び出すとOutofMemoryが発生しました。特に画像処理はメモリを消費します。opts.inSampleSize = 8;で間引き処理しています。

とうことで、バーコード画像の取り込みと画像分析でバーコードを値として取り込むところまで出来ました。

今まではテストプログラムのレベルだったので、本番用のプロジェクトを作成して、検証結果を取り込みながら取り込んだバーコードから検索するような処理を追加していく予定です。

この記事へのコメント

hoge君
2009年08月14日 22:46
>coreの下にcore.jarが出来ます。これをコピーして使えば良いでしょう。

オリジナルアプリからzxingを使ってバーコード読み込みたい場合は、core.jarをどこにコピーすんですか?

パクチー
2009年08月14日 23:06
>hoge君さん
>オリジナルアプリからzxingを使ってバーコード読み込みたい場合は、core.jarをどこにコピーすんですか?

Ecliseで開発する場合でしたら、プロジェクトファイルの下に適当なフォルダ、例えば「lib」を作成します。
その下にcore.jarをコピーします。
プロジェクトからcore.jarを参照するようにします。
Eclipseの設定でJARの追加すれば、オリジナルアプリから
import com.google.zxing.xxx
とすれば使えます。Eclipseが勝手にimportしてくれるはずです。
hoge君
2009年08月15日 02:16
>パクチー
なるほど。
勝手にフォルダー作っていいんや?
しならなかった。
明日、実際にlibフォルダを作ってコピーしてみます。
まだ、本体もってないからエミュレータで試すだけだけね!?

また、結果報告します、アドバイスありがとうございます。

この記事へのトラックバック