QR code 생성 하기.
 2014/08/12 - [Android Study] - Android QR code

 이번에는 Scanner code 에 대해서 설명 해보도록 하겠음.
Camera preview 를 이용한 기법이므로 camera preview 정도는 가볍게 해결 해주셔야함.

 일단은 Camera preview callback 함수 부터.
     private Camera.PreviewCallback mPreviewCallback = new Camera.PreviewCallback() {
        // Frame 제한 시간
        private static final long FRAME_RATE_TIME = 200; // 200:5, 124:8, 100:10
        // Frame 체크용 시간 변수
        private long mCheckTime = 0;

        @Override
        public void onPreviewFrame(byte[] data, Camera camera) {
            boolean checkImage = false;
            // Frame 제한 시간을 넘는 경우에만 decode 작업을 수행
            if (mCheckTime == 0) {
                mCheckTime = System.currentTimeMillis();
                checkImage = true;
            } else {
                long current = System.currentTimeMillis();
                if (current - mCheckTime > FRAME_RATE_TIME) {
                    mCheckTime = current;
                    checkImage = true;
                }
            }

            if (checkImage == true) {
                mThread.insert(data, camera.getParameters().getPreviewSize());
            }
        }
    };


 코드 자체는 별 내용이 없고 Thread에 YUV 데이터를 전달 하는게 전부 인데, 시간 interval을 준 까닭은 Preview size가 너무 클 경우 YUV data 가 무지막지하게 커지는 경향이 있음.
 이럴 경우 decode에 과부하가 걸려서 Camera preview가 제대로 동작 안하고 버벅이는 현상이 발생함.

그다음 Thread 부분은.
    private class QRDecorderThread extends Thread {
        // Queue의 최대 값
        private static final int QUEUE_MAX = 3;
        // YUV data blocking queue
        private BlockingQueue<byte[]> mQueue;
        // UI 쪽에 data를 전달 할 Handler
        private Handler mHandler;
        // Preview size 변수
        private Camera.Size mSize;

        public QRDecorderThread(Handler handler) {
            mHandler = handler;
            mQueue = new ArrayBlockingQueue<byte[]>(QUEUE_MAX);
        }

        @Override
        public void run() {
            while (true) {
                try {
                    byte[] data = mQueue.take();

                    PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(
                            data, mSize.width, mSize.height, 0, 0, mSize.width,
                            mSize.height, false);

                    BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(
                            source));

                    QRCodeReader reader = new QRCodeReader();

                    try {
                        Result result = reader.decode(bitmap);
                        String resultData = result.getText();
                        // 결과물이 있을 경우 preview 정지 및 UI 쪽에 data 전달
                        if (resultData != null) {
                            mCamera.stopPreview();
                            mHandler.sendMessage(mHandler.obtainMessage(0,
                                    resultData));
                        }
                    } catch (Exception e) {
                    }
                } catch (InterruptedException e) {
                    break;
                }
            }
        }

        public void insert(byte[] data, Camera.Size size) {
            try {
                mSize = size;
                mQueue.put(data);
            } catch (InterruptedException e) {
            }
        }
    }

사실은 저기 Thread 내부에서 새로 생성하는 class 들도 어떻게 잘 조절하면 new를 안하고 재활용 할 수 있을 듯한데...
음 거기까진 잘 모르겠음.
그리고 하나더 Camera parameter를 setting 할때 분명 preview에 대한 FrameRate를 설정 할 수 있는 걸로 알고 있는데 이것 또한
시도 해보지 않음...
여하튼 이런식으로 하면 동작하긴 함. 

'Android' 카테고리의 다른 글

Android HTTPS SHA128 인증서 오류  (0) 2017.02.08
Sharedpreferences 에 관하여  (0) 2015.04.04
Android QR code  (0) 2014.08.12
Android AsyncTask 함정 카드  (1) 2014.08.03
Android Custom Widget 만들기 7편  (0) 2012.04.12
 이번 주제는 QR 코드.
요즘은 기본적으로 QR code를 인식하는 다양한 방법 혹은 어플들이 있으니까, 나도 해봐야지.

우리에게 필요한 준비물은 Android SDK, Eclipse, QR code library 정도.

그리 잘 만든 코드는 아니지만 일단 스타드~

우선 QR code library 수집을 위해서 위대하신 우리 Google 느님에게 검색, 검색~
그리고 zxing 이란 녀석을 사용하기로 결정!!
URL : https://github.com/zxing

근데 이거 까보니 너무 많음 바코드도 있고... 기타 등등.. 그래서 귀찮으므로 QR 코드만 따로 빼서 새로 만듬
그리고 생각해보니 code 위주로 작성하는데 복사를 못하게 하면 난감해서 복사방지 풀음...


QR 코드 생성해서 ImageView에 보이도록 하는 부분.

    private class CreateQRCodeAsyncTask extends AsyncTask<String, Void, Bitmap> {
        // QR code 색상
        private static final int WHITE = 0xFFFFFFFF;
        private static final int BLACK = 0xFF000000;

        // QR code bitmap 크기 비율
        private static final float REDUCE_RATIO = 0.8f;

        // 타겟 image view
        private ImageView mTagetView;

        // 화면 크기
        private Point mDisplaySize;

        public CreateQRCodeAsyncTask (Imageview taget, Point displaySize) {
            mTagetView = taget;
            mDisplaySize = displaySize;
        }

        @Override
        protected Bitmap doInBackground(String... params) {
            // zxing library class (QR code writer)
            QRCodeWriter qrCodeWriter = new QRCodeWriter();

            try {
                // 화면 비율 대비 QR 코드 이미지 크기 조정
                int temp = mDisplaySize.x;

                if (temp > mDisplaySize.y) {
                    temp = mDisplaySize.y;
                }

                int dWidth = (int) ((float) temp * REDUCE_RATIO);
                int dHeight = (int) ((float) temp * REDUCE_RATIO);

                // QR code로 인코딩해서 비트맵 array 정보를 얻어옴 zxing 자체 class임
                BitMatrix result = qrCodeWriter.encode(params[0],
                        BarcodeFormat.QR_CODE, dWidth, dHeight);
                int width = result.getWidth();
                int height = result.getHeight();

                // Bitmap pixel array
                int[] pixels = new int[width * height];

                // BitMatrix 정보를 바탕으로 bitmap 픽셀 array 에 color 입력
                // All are 0, or black, by default
                for (int y = 0; y < height; y++) {
                    int offset = y * width;
                    for (int x = 0; x < width; x++) {
                        pixels[offset + x] = result.get(x, y) ? BLACK : WHITE;
                    }
                }

                // pixel array 크기의 bitmap 생성
                Bitmap bitmap = Bitmap.createBitmap(width, height,
                        Bitmap.Config.ARGB_8888);

                // bitmap에 pixel 정보 입력
                bitmap.setPixels(pixels, 0, width, 0, 0, width, height);

                return bitmap;
            } catch (Exception e) {
                return null;
            }
        }

        @Override
        protected void onPostExecute(Bitmap result) {
            if (result != null && mTagetView != null) {
                // image view 에 QR code 업데이트
                mTagetView.setImageBitmap(result );
                mTagetView.invalidate();
            }
        }
    }   

다음편에 스캔하는 code 설명을 이어가 겠음...





'Android' 카테고리의 다른 글

Sharedpreferences 에 관하여  (0) 2015.04.04
Android QR code scan 부분  (0) 2014.09.21
Android AsyncTask 함정 카드  (1) 2014.08.03
Android Custom Widget 만들기 7편  (0) 2012.04.12
Android Custom Widget 만들기 6편  (0) 2012.04.12

+ Recent posts