2011년 3월 9일 수요일

Android ZXing을 이용한 QR코드 인식하기.

QR코드를 인식하는 기능을 넣을 일이 있어서 알아보았다.

엄청난 삽질!!

ZXing으로 검색하면 대부분 공개해놓은것 들은 Intent로 바코드 스캐너를 호출한다음에
이미지를 캡쳐 받아 결과를 리턴 받는 식의 예제가 많다.

편하긴 한데 바코드스캐너가 설치되어 있지 않다면 골치아프고
직접 앱에서 찍고 해석하는것을 하려 한다면 위의 방법은 필요없다.?;


먼저 QR코드를 해석해주는
ZXing이라는 프로젝트가 있다.

오픈소스이며. ZXing을 검색하면 쉽게 찾을 수 있다.

아이폰, 안드로이드, 블랙베리 등.. 다방면으로 지원되는 고마운 프로젝트!!



안드로이드에서 QR코드를 사용하려면 먼저 ZXing에서
ZXing~~ .zip 파일을 다운 받는다.

폴더를 보면 안드로이드, 아이폰 등의 여러 폴더로 구성되어 있는데
그중에 필요한 것은 core폴더에 있는

com폴더 이하 모든 소스. 직접 소스를 포함해도 되고 jar로 묶어서 포함시켜도 된다.

바코드스캐너의 소스가 공개되어 있는데 그 모든 소스를 분석하면 더 좋다.



카메라를 이용하는 소스는 검색하면 쉽게 구할 수 있다.


Camera에 보면 setPreviewCallback이라는 메서드가 있다.
말 그대로 프리뷰상태의 이미지를 계속 캡쳐해서 데이터를 보내주는 메서드이다.

Camera.PreviewCallback에는
public void onPreviewFrame(byte[] data, Camera camera) {

위의 메서드가 있다. data는 이미지데이터이다.
위의 데이터를 이미지로 변환하여 QRCodeReader에 decode시켜주면 해결.
이지만 byte[] data를 단순 비트맵이 아닌
BinaryBimap으로 변환 시켜야 한다.

아래의 소스처럼 변경하면 된다.

카메라가 캡쳐하여 보내준 byte[] data의 경우는
일반 이미지가 아닌 YUV라는 포멧으로 데이터를 보내준다고 한다.

안드로이드펍 질문에서 본 내용인데 어디인지 기억이 안난다..링크걸고 싶엇는데..


어쨋든 byte[] data를 변환하기 위해서는 일련의 과정을 거쳐야 한다.
검색해면 각종 소스가 잇는데

ZXing자체에 그 변환소스가 포함되어 있다...( 많이 삽질... )

ZXing 받은 소스중에
Android 폴더에 들어가면 하단의 클래스파일이 존재한다.
PlanarYUVLuminanceSource <-- 바로 이놈.

src/com/google/zxing/client/android 밑에 있다.
해당파일은 다른 파일을 참조 안하기 떄문에 그 파일 하나만 딸랑 가져오면된다.

그 이후에는 하단의 소스와 같이 넣어면된다.

밑의 소스가 되기전에 해야할일이 Autofocus를 호출해줘야 한다.
Autofocus는

Camera.AutofocusCallback 을 implements 한 클래스를 하나 만들고.

camera.setAutofocus( 이곳에 계속 생성해서 넣어주면 된다. )
그럼 카메라가 알아서 줌인 줌아웃 밝기조절등을 한다.

그래서 정상적으로 코드가 인식되면 Log에 데이터를 뿌리는걸 볼수 있을 것이다

PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(data, c.getParameters().getPreviewSize().widthc.getParameters().getPreviewSize().height, 0, 0, c.getParameters().getPreviewSize().widthc.getParameters().getPreviewSize().height);

BinaryBitmap b = new BinaryBitmap(new HybridBinarizer(source));
QRCodeReader reader = new QRCodeReader();
try {
    Result result = reader.decode(b);
    if( result.getText() != null ) {
        Log.i("QR"">>" + result.getText());
    }
}catch(Exception e) {
//Log.i("QR", e.getMessage());
}







적당한 거리를 둬야 코드가 인식하므로
다른 어플들 처럼 카메라위에 코드가 인식될만한 크기의
그림등을 표시해주면 괜찮은 코드인식프로그램을 만들 수 있지 않을까 생각한다..

위의 코드는 지금 막 풀려서 올린 소스이고.
좀더 다듬에서 자연스레 인식하는 소스를 만드시면 된다~!

끝.






댓글 없음:

댓글 쓰기