- PR -

QRコードクラスライブラリを使用したアプリケーションの開発について

1
投稿者投稿内容
実月
会議室デビュー日: 2003/10/26
投稿数: 11
投稿日時: 2005-01-11 16:03
投稿させていただきます。

QRコードクラスライブラリを使用してアプリケーションの開発をしようと思っております。
(ライブラリはこちらのものを使わせていただいています)
上に挙げたサイトの、アプレットデモで生成したQRコードでは、
ちゃんと読み取ることができます。

しかし、自分で作ってみたJPEGで出力するサンプルでは、
画像は生成されるのですが、携帯で読み取ることができません。
ソースコードは全く同じものなので、JPEGに出力する時点で何かが起こって
いるような気がしています。
以下にソースコードを添付いたしますので、どこかおかしいところがあれば
ご教授お願いします。

コード:
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import com.sun.image.codec.jpeg.ImageFormatException;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import com.swetake.util.Qrcode;

public class Test1 {
    static Graphics2D g;
    static int width = 500;
    static int height = 500;
    public static void main(String[] args) throws ImageFormatException, IOException {
        OutputStream out = new FileOutputStream("test.jpg");
        BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);        
        g = image.createGraphics();
        g.setBackground(Color.WHITE);
        g.clearRect(0,0,width,height);
        
        Qrcode qr = new Qrcode();
        qr.setQrcodeErrorCorrect('M');
        qr.setQrcodeEncodeMode('B');
        qr.setQrcodeVersion(7);

        String str = "01234567";
        byte[] tmp = str.getBytes();        
        boolean[][] b = qr.calQrcode(tmp);        
        for(int i=0;i<b.length;i++){
            for(int j=0;j<b.length;j++){
                if(b[i][j]){
                    g.setPaint(Color.BLACK);
                    g.fillRect(j*3,i*3,3,3);
                }else{
                    g.setPaint(Color.WHITE);
                    g.fillRect(j*3,i*3,3,3);
                }
            }
            
        }
        
        JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
        encoder.encode(image);
        out.close();
    }
}

soluna
ベテラン
会議室デビュー日: 2004/06/15
投稿数: 59
投稿日時: 2005-01-11 17:19
jpegの特徴を考えれば、QRには、jpegは向かないと思いますよ。
jpegについて調べてみて下さい。
たとえば、MSペイントでもofficeが入っていれば
jpegで保存できるので。128*128ぐらいのキャンバスに
赤色で、太いペン先でグリグリっと書いて、jpegで保存してみて下さい。
実月
会議室デビュー日: 2003/10/26
投稿数: 11
投稿日時: 2005-01-12 00:26
お返事ありがとうございます。
JPEGが向かないというのは、圧縮による劣化が原因、ということだと思いますが
生成されたイメージを見てみても、GIFとJPEGでは全く同じものが出力
されます。(ソースコードとイメージを添付いたします)

このライブラリを使ったPHPのデモではPNGで出力されていますが、
アプレットデモと同様、携帯で読み取ることができました。
ソースを見直してもアルゴリズム的には間違っているところは
無いように思いますので、何か足りないものがあると思うのですが、、、。

引き続きよろしくお願いします。

コード:
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import Acme.JPM.Encoders.GifEncoder;

import com.sun.image.codec.jpeg.ImageFormatException;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import com.swetake.util.Qrcode;

public class Test1 {
    static Graphics2D g;
    static int width = 500;
    static int height = 500;
    public static void main(String[] args) throws ImageFormatException, IOException {
        OutputStream out = new FileOutputStream("test.jpg");
        BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);        
        g = image.createGraphics();
        g.setBackground(Color.WHITE);
        g.clearRect(0,0,width,height);
        
        Qrcode qr = new Qrcode();
        qr.setQrcodeErrorCorrect('M');
        qr.setQrcodeEncodeMode('B');
        qr.setQrcodeVersion(7);

        String str = "01234567";
        byte[] tmp = str.getBytes();        
        boolean[][] b = qr.calQrcode(tmp);        
        for(int i=0;i<b.length;i++){
            for(int j=0;j<b.length;j++){
                if(b[i][j]){
                    g.setPaint(Color.BLACK);
                    g.fillRect(j*3,i*3,3,3);
                }else{
                    g.setPaint(Color.WHITE);
                    g.fillRect(j*3,i*3,3,3);
                }
            }
            
        }
        
        JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
        encoder.encode(image);
        
        out = new FileOutputStream("test2.gif");
        GifEncoder gEncoder = new GifEncoder(image,out);
        gEncoder.encode();
        
        out.close();
    }
}



soluna
ベテラン
会議室デビュー日: 2004/06/15
投稿数: 59
投稿日時: 2005-01-12 01:08
引用:
実月さんの書き込み (2005-01-12 00:26) より:
お返事ありがとうございます。
JPEGが向かないというのは、圧縮による劣化が原因、ということだと思いますが
生成されたイメージを見てみても、GIFとJPEGでは全く同じものが出力
されます。(ソースコードとイメージを添付いたします)


劣化の正体はノイズですよ?拡大表示して確認してみました?
どう見ても、全く同じものとはいえませんよ。
この手のものは、リーダーの精度にもよると思いますが、はっきり白黒のコントラストが
ついていないと、うまく読めないと思いますよ。
また、PNGで出力できるのならばPNGで出力した方がいいと思いますよ。
Kissinger
ぬし
会議室デビュー日: 2002/04/30
投稿数: 428
お住まい・勤務地: 愛知県
投稿日時: 2005-01-12 01:47
実月さんが肉眼でみても見分けが付かないのは
仕方ないですね。

でもペイントにコピー&ペーストして800倍に
してみたら、明らかに JPEGでは劣化してますね。

僅かな違いですが、ノイズが一様に分布すると
折角のQRコードのエラー訂正が効かなく
なります。

GIFか PNGがお勧め。
実月
会議室デビュー日: 2003/10/26
投稿数: 11
投稿日時: 2005-01-12 02:31
ご返信ありがとうございます。
フリーソフトで生成した画像と先ほどの画像(PNGにしてみました)を
ジーッと見ていて気がついたのですが、この画像を90度右回転
してから横反転すると反転すると、ちゃんとした画像に戻るようです。
実際やってみたところちゃんと読み取ることが出来ました。
上記の処理を施した画像を添付します。

どういういきさつでこうなったかは解明中ですが、原因が分かれば何とかなります。
solunaさん、Kissingerさん、ありがとうございました。
1

スキルアップ/キャリアアップ(JOB@IT)