: O. Yuanying

Delicious Libraryの作り方

ネタフルの最も美しいMacアプリケーションのトップ10で1位として紹介されたDelicious Library。非常に興味深い。

要するに「iSightのようなカメラを使い自宅のライブラリ(本、DVD、CD)のバーコードを撮影し、それをカタログしてブラウズできるようにするソフト。」なのですが、このバーコードを撮影しってのが手軽そうで良いですね。

一度自宅の本(漫画)を整理するcgiでも作ろうかと考えたのですがいちいち本の題名やら著者名、もしくはISBNコードを入力するのがめんどそうなので止めた私には丁度よさそうです。

ただ問題として$40ってのがいただけない!さらに払うのもめんどくさい。

ということで自分で同じようなアプリケーションを作れるかどうか以下を調べてみた。

  1. Cocoaを利用してiSightから画像を取得する方法。
  2. 取得した画像からバーコードを認識して番号を取得する方法。
  3. 取得した番号をISBNコードに変換する方法。
  4. Amazon Web Serviceを利用してISBNコードから書籍情報を取得する方法。

1.Cocoaを利用してiSightから画像を取得する方法

まずMacアプリケーションということでCocoaを学ばなくてはならない。まあこれは一般の書籍で我慢することにする。

つぎにiSightから画像を取得する方法だが、ちょっと調べてたらCocoa Barcode Recognitionというプロジェクトを発見。

Cocoa Barcode Scanner Software. The software is an Xcode project written in Cocoa and Carbon that detects barcodes from images streaming from a firewire camera. Mac OS X only.

うへ、いきなりiSightからバーコード情報を取得する方法をみつけてしまった。とりあえずオープンソースなのでソースを読んでみる。

2.取得した画像からバーコードを認識して番号を取得する方法

1.で画像からバーコードを取得する方法がいきなりみつかってしまったけど、念のためバーコードの仕様を調査してみる。

また、Javaで画像からバーコードを取得するライブラリも発見。

3.取得した番号をISBNコードに変換する方法

バーコードから取得した数値をISBNコードに変換するサンプルソースをRubyで書いているブログを発見。

sub barcode_to_isbn {
    my $jan1 = shift;

    my @num = split //, $jan1;
    my $chk_digit = pop @num;
    if (scalar(@num) != 12 || $jan1 !~ /^97[89]/) {
        return undef;
    }

    ## validate JAN
    my $chk_sum = 0;
    map {$chk_sum += $_} @num[1,3,5,7,9,11];
    $chk_sum *= 3;
    map {$chk_sum += $_} @num[0,2,4,6,8,10];
    $chk_sum %= 10;
    if ($chk_digit != (10 - $chk_sum) % 10) {
        return undef;
    }

    splice @num, 0, 3;

    ## calculate ISBN check digit
    $chk_sum = 0;
    my $i = 0;
    map {$chk_sum += $_ * (10 - $i++)} @num;
    $chk_digit = 11 - ($chk_sum % 11);
    $chk_digit = 'X' if $chk_digit == 10;

    return join('', @num) . $chk_digit;
}

なんかこの人はバーコードリーダーを買ってきて、それで自分ちの本を管理しようとしてるみたいだなー。なんかバーコードリーダーも実は安いみたいだしわざわざ画像解析してやる必要もないきがしてきた。

ところでMacに対応したバーコードリーダーってあるのかしらん。

4.Amazon Web Serviceを利用してISBNコードから書籍情報を取得する方法

実はまだAmazon Web Serviceって利用したことないんだよね。とりあえずまとめページがあったので読んでみる。

なんか試すだけなら簡単そうなので、JAX-WSを利用してクライアントコードを生成してみる。

なんかロケールごとにwsdlファイルが用意されているようで、とりあえずUSを使ってみると日本語の書籍が全然ヒットしなかったのでJPを使ってみる。

[yuanying@kiriko amazon]$/usr/local/jaxws-ri/bin/wsimport.sh -s src -d bin http://webservices.amazon.com/AWSECommerceService/JP/AWSECommerceService.wsdl
[yuanying@kiriko amazon]$

実を言うとJAX-WSを使うのもこれが初めてだったりするヽ(´-`)丿

public static void main(String[] args) {
		AWSECommerceService service = new AWSECommerceService();
		AWSECommerceServicePortType type = service.getAWSECommerceServicePort();
		
		List<ItemLookupRequest> requests = new ArrayList<ItemLookupRequest>();
		ItemLookupRequest request = new ItemLookupRequest();
		requests.add(request);
		request.setIdType("ASIN");
		request.getItemId().add("1590596455");

		Holder<OperationRequest> operationRequest = new Holder<OperationRequest>();
		Holder<List<Items>> items = new Holder<List<Items>>();
		
		type.itemLookup(null, "17CXTSDKPH0MF0NFP982", null, "bonnohfract00-22", null, null, null, requests, operationRequest, items);
		
		Item item = items.value.get(0).getItem().get(0);
		System.out.println(item.getDetailPageURL());
		System.out.println(item.getItemAttributes().getTitle());
	}

なんか、、取得できるデータが色々あってよくわからないですね…ちゃんとAPIリファレンス読めと言うことか。