Platform/Android

[Zxing]

개랭갱깽스타 2020. 6. 2. 11:31

DetectBarcodeInterface.java

import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.Point;
import android.os.Environment;
import android.util.Log;

import com.google.zxing.BinaryBitmap;
import com.google.zxing.EncodeHintType;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.NotFoundException;
import com.google.zxing.RGBLuminanceSource;
import com.google.zxing.Result;
import com.google.zxing.ResultPoint;
import com.google.zxing.common.HybridBinarizer;
import com.inzisoft.mobile.data.BarcodeRecognizeResult;
import com.inzisoft.mobile.data.MIDReaderProfile;
import com.inzisoft.mobile.util.CommonUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Hashtable;

/**
 * Barcode(QR, DataMatrix 등) 검출을 위한 Interface
 */
public class DetectBarcodeInterface {

    private BarcodeRecognizeResult detectedCodeResult;
    private DetectBarcodeCallbackListener mDetectCallbackListener;

    private final static float dataMatrixSize = 1.4f;
    private final static float hOffset = 0.9f;
    private final static float wOffset = 1.8f;
    private final static float a4Width = 21.0f;
    private final static float a4Height = 29.7f;

    /**
     * @param mDetectCallbackListener
     */
    public DetectBarcodeInterface(DetectBarcodeCallbackListener mDetectCallbackListener) {
        this.mDetectCallbackListener = mDetectCallbackListener;
    }

    /**
     * Barcode(QR, datamatrix...) 인식 코드
     *
     * @param bitmap 감지하려는 barcode가 포함된 문서 bitmap
     * @return Result
     * 감지된 barode 결과 객체
     */
    private Result detectBarcode(Bitmap bitmap) throws NotFoundException {

        Result result = null;

        boolean vertical = bitmap.getWidth() > bitmap.getHeight();

        if (vertical) {
            Matrix matrix = new Matrix();
            matrix.postRotate(90);
            bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        }

        int oriWidth = bitmap.getWidth();
        int oriHeight = bitmap.getHeight();

        float wRatio = (dataMatrixSize + wOffset * 2) / a4Width;
        float hRatio = (dataMatrixSize + hOffset * 2) / a4Height;

        int startX = (int) (oriWidth * (1 - wRatio));
        int width = (int) (oriWidth * wRatio);
        int height = (int) (oriHeight * hRatio);

        Bitmap detectedBitmap = Bitmap.createBitmap(bitmap, startX, 0, width, height);

        // saveImg(detectedBitmap);

        int dbWidth = detectedBitmap.getWidth();
        int dbHeigth = detectedBitmap.getHeight();

        Log.d("khji", "dbSize:" + dbWidth + "/" + dbHeigth);

        // dataMatrixSize 인식 시작
        Hashtable<EncodeHintType, String> hints = new Hashtable<>(2);
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");

        int[] intArray = new int[dbWidth * dbHeigth];

        // intArray 에 detectedBitmap 픽셀 복사
        detectedBitmap.getPixels(intArray, 0, dbWidth, 0, 0, dbWidth, dbHeigth);

        LuminanceSource source = new RGBLuminanceSource(dbWidth, dbHeigth, intArray);
        BinaryBitmap BinaryBitmap = new BinaryBitmap(new HybridBinarizer(source));

        // 인식된 Code 결과값
        result = new MultiFormatReader().decodeWithState(BinaryBitmap);


        return result;
    }

    public void saveImg(Bitmap detectedBitmap) {
        String ex_storage = Environment.getExternalStorageDirectory().getAbsolutePath();
        String foler_name = "/OcrDemo/";
        String file_name = "detetectedDM1" + ".jpg";
        String string_path = ex_storage + foler_name;


        File file_path = new File(string_path);
        if (!file_path.isDirectory()) {
            file_path.mkdirs();
        }
        try {
            FileOutputStream out = new FileOutputStream(string_path + file_name);
            detectedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
            out.close();
            Log.d("khji", "저장완료");
        } catch (IOException e) {
            Log.d("khji", "저장실패");
        }
    }

    public void getDetectBarcodeResult(Bitmap bitmap) {

        Result result;
        detectedCodeResult = BarcodeRecognizeResult.getInstance();

        try {
            result = detectBarcode(bitmap);

            detectedCodeResult.setData(result.getText());
            detectedCodeResult.setFormat(result.getBarcodeFormat().toString());
            detectedCodeResult.setNumBits(result.getNumBits());

            ResultPoint[] points = result.getResultPoints();

            Point[] ps = new Point[points.length];

            for (int i = 0; i < points.length; i++) {
                ps[i] = new Point((int) points[i].getX(), (int) points[i].getY());
            }

            detectedCodeResult.setmCroppedPoints(ps);
            detectedCodeResult.setTimestamp(result.getTimestamp());
            detectedCodeResult.setmRetValue(LibConstants.ERR_QR_CODE_RECOGNITION_SUCCESS);

        } catch (NotFoundException ne) {
            detectedCodeResult.setmRetValue(LibConstants.ERR_QR_CODE_RECOGNITION_FIND_EDGE_FAILD);
            ne.printStackTrace();
        } catch (NullPointerException pe) {
            detectedCodeResult.setmRetValue(LibConstants.ERR_QR_CODE_RECOGNITION_NO_IMAGE_FAILD);
            pe.printStackTrace();
        } catch (Exception e) {
            detectedCodeResult.setmRetValue(LibConstants.ERR_QR_CODE_RECOGNITION_FAILD);
            e.printStackTrace();
        }

        mDetectCallbackListener.callback(detectedCodeResult);

    }

    public interface DetectBarcodeCallbackListener {
        void callback(BarcodeRecognizeResult detectedCodeResult);
    }

}

 

BarcodeRecognizeResult.java

import android.graphics.Point;
import android.os.Parcel;
import android.os.Parcelable;

import com.google.zxing.Result;
import com.google.zxing.ResultPoint;
import com.inzisoft.mobile.recogdemolib.LibConstants;

import java.util.Arrays;

/**
 * 검출된 Barcode 결과 객체
 */
//TODO. RecognizeResult 와 연결
public class BarcodeRecognizeResult implements Parcelable {

    /**
     * 인식 결과 객체
     */
    private volatile static BarcodeRecognizeResult instance;

    /**
     * 디코딩 결과 text
     */
    private String data;
    /**
     * 바이트코드로 인코딩된 원시 바이트
     */
    private byte[] rawBytes;
    /**
     * 인식 포맷
     */
    private String format;
    /**
     * 유효 바이트
     */
    private int numBits;
    /**
     * 추출된 모서리
     */
    private Point[] mCroppedPoints;
    /**
     * 디코딩된 시간
     */
    private long timestamp;
    /**
     * 디코딩 결과
     */
    private int mRetValue = 0;

    private BarcodeRecognizeResult() { }

    /**
     * 결과 객체 생성
     * @return BarcodeRecognizeResult: 결과 객체 생성
     */
    public static BarcodeRecognizeResult getInstance() {
        if (instance == null) {
            synchronized (BarcodeRecognizeResult.class) {
                if (instance == null)
                    instance = new BarcodeRecognizeResult();
            }
        }
        return instance;
    }

    public void setBarcodeResult(Result result){
        this.data = result.getText();
        this.format = result.getBarcodeFormat().toString();
        this.numBits = result.getNumBits();

        this.mCroppedPoints = convertResultPointToPoint(result.getResultPoints());

        this.timestamp = result.getTimestamp();
        this.mRetValue = LibConstants.ERR_QR_CODE_RECOGNITION_SUCCESS;
    }

    public BarcodeRecognizeResult(Result result) {
        this.data = result.getText();
        this.format = result.getBarcodeFormat().toString();
        this.numBits = result.getNumBits();

        this.mCroppedPoints = convertResultPointToPoint(result.getResultPoints());

        this.timestamp = result.getTimestamp();
        this.mRetValue = LibConstants.ERR_QR_CODE_RECOGNITION_SUCCESS;
    }

    public Point[] convertResultPointToPoint(ResultPoint[] points) {

        Point[] ps = new Point[points.length];

        for (int i = 0; i < points.length; i++) {
            ps[i] = new Point((int) points[i].getX(), (int) points[i].getY());
        }

        return ps;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    public byte[] getRawBytes() {
        return rawBytes;
    }

    public void setRawBytes(byte[] rawBytes) {
        this.rawBytes = rawBytes;
    }

    public String getFormat() {
        return format;
    }

    public void setFormat(String format) {
        this.format = format;
    }

    public int getNumBits() {
        return numBits;
    }

    public void setNumBits(int numBits) {
        this.numBits = numBits;
    }

    public Point[] getmCroppedPoints() {
        return mCroppedPoints;
    }

    public void setmCroppedPoints(Point[] mCroppedPoints) {
        this.mCroppedPoints = mCroppedPoints;
    }

    public long getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(long timestamp) {
        this.timestamp = timestamp;
    }

    public int getmRetValue() {
        return mRetValue;
    }

    public void setmRetValue(int mRetValue) {
        this.mRetValue = mRetValue;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(data);
        dest.writeByteArray(rawBytes);
        dest.writeParcelableArray(mCroppedPoints, flags);
        dest.writeString(format);
        dest.writeInt(numBits);
        dest.writeLong(timestamp);
        dest.writeInt(mRetValue);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    protected BarcodeRecognizeResult(Parcel in) {
        this.data = in.readString();
        this.rawBytes = new byte[in.readInt()];
        in.readByteArray(this.rawBytes);
        Parcelable[] parcelableArray = in.readParcelableArray(BarcodeRecognizeResult.class.getClassLoader());
        if (parcelableArray != null) {
            this.mCroppedPoints = Arrays.copyOf(parcelableArray, parcelableArray.length, Point[].class);
        }
        this.format = in.readString();
        this.numBits = in.readInt();
        this.timestamp = in.readLong();
        this.mRetValue = in.readInt();
    }

    public static final Creator<BarcodeRecognizeResult> CREATOR = new Creator<BarcodeRecognizeResult>() {
        @Override
        public BarcodeRecognizeResult createFromParcel(Parcel source) {
            return new BarcodeRecognizeResult(source);
        }

        @Override
        public BarcodeRecognizeResult[] newArray(int size) {
            return new BarcodeRecognizeResult[size];
        }
    };
}
반응형

'Platform > Android' 카테고리의 다른 글

[Receiver]  (0) 2020.06.05
[다운로드]  (0) 2020.06.02
[ListView VS RecyclerView]  (0) 2020.05.19
[Android Studio/Eclipse] keymap-단축키  (0) 2020.05.13
[debug] Room Database / SharedPreferences 디버깅  (0) 2020.04.14