Android zxing(下)

来源:互联网 发布:淘宝绑定银行卡 编辑:程序博客网 时间:2024/06/05 10:06

官方zxing例子学习

如果代码涉及core-3.2.1,就不在研究,有兴趣可自行深入去学习。

扫描二维码

代码调用顺序CaptureActivity → CaptureActivityHandler → CameraManager → PreviewCallback → DecodeHandler → CaptureActivityHandler  → CaptureActivity。下面一一分析。

CaptureActivity

CaptureActivity入口类,主要做了Camera,Beep,AmbientLight等初始化。CaptureActivityHandler初始化是在initCamera方法里:

 private void initCamera(SurfaceHolder surfaceHolder) {        ……            // Creating the handler starts the preview, which can also throw a RuntimeException.            if (handler == null) {                handler = new CaptureActivityHandler(this, decodeFormats, decodeHints, characterSet, cameraManager);       ……    }

CaptureActivityHandler

CaptureActivityHandler构造方法做了DecodeThread初始化,DecodeThread run方法做了DecodeHandler初始化,然后Camera开始扫码工作。

  public CaptureActivityHandler(CaptureActivity activity,                                  Collection<BarcodeFormat> decodeFormats,                                  Map<DecodeHintType, ?> baseHints,                                  String characterSet,                                  CameraManager cameraManager) {        this.activity = activity;        decodeThread = new DecodeThread(activity, decodeFormats, baseHints, characterSet,                new ViewfinderResultPointCallback(activity.getViewfinderView()));        decodeThread.start();        state = State.SUCCESS;        // Start ourselves capturing previews and decoding.        this.cameraManager = cameraManager;        cameraManager.startPreview();        restartPreviewAndDecode();    } private void restartPreviewAndDecode() {        if (state == State.SUCCESS) {            state = State.PREVIEW;            //decodeThread.getHandler()拿到DecodeHandler            cameraManager.requestPreviewFrame(decodeThread.getHandler(), R.id.decode);            activity.drawViewfinder();        }    }

CameraManager

public synchronized void requestPreviewFrame(Handler handler, int message) {        OpenCamera theCamera = camera;        if (theCamera != null && previewing) {            previewCallback.setHandler(handler, message);            theCamera.getCamera().setOneShotPreviewCallback(previewCallback);        }    }

PreviewCallback

 void setHandler(Handler previewHandler, int previewMessage) {    this.previewHandler = previewHandler;    this.previewMessage = previewMessage;  }  @Override  public void onPreviewFrame(byte[] data, Camera camera) {    Point cameraResolution = configManager.getCameraResolution();    Handler thePreviewHandler = previewHandler;    if (cameraResolution != null && thePreviewHandler != null) {      //给DecodeHandler发消息      Message message = thePreviewHandler.obtainMessage(previewMessage, cameraResolution.x,          cameraResolution.y, data);      message.sendToTarget();      previewHandler = null;    } else {      Log.d(TAG, "Got preview callback, but no handler or resolution available");    }  }

DecodeHandler

扫码结果,反馈给CaptureActivityHandler

@Override    public void handleMessage(Message message) {        if (!running) {            return;        }        int what = message.what;        if (what == R.id.decode) {            decode((byte[]) message.obj, message.arg1, message.arg2);        } else if (what == R.id.quit) {            running = false;            Looper.myLooper().quit();        }} private void decode(byte[] data, int width, int height) {        long start = System.currentTimeMillis();        Result rawResult = null;        PlanarYUVLuminanceSource source = activity.getCameraManager().buildLuminanceSource(data, width, height);        if (source != null) {            BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));            try {                rawResult = multiFormatReader.decodeWithState(bitmap);            } catch (ReaderException re) {                // continue            } finally {                multiFormatReader.reset();            }        }        Handler handler = activity.getHandler();//拿到CaptureActivityHandler        if (rawResult != null) {            // Don't log the barcode contents for security.            long end = System.currentTimeMillis();            Log.d(TAG, "Found barcode in " + (end - start) + " ms");            if (handler != null) {                //给CaptureActivityHandler发消息                Message message = Message.obtain(handler, R.id.decode_succeeded, rawResult);                Bundle bundle = new Bundle();                bundleThumbnail(source, bundle);                message.setData(bundle);                message.sendToTarget();            }        } else {            if (handler != null) {                Message message = Message.obtain(handler, R.id.decode_failed);                message.sendToTarget();            }        }    }

CaptureActivityHandler

扫码结果,再反馈给CaptureActivity,这样就走完了扫码过程。

 @Override    public void handleMessage(Message message) {        int what = message.what;        if (what == R.id.restart_preview) {            restartPreviewAndDecode();        } else if (what == R.id.decode_succeeded) {            state = State.SUCCESS;            Bundle bundle = message.getData();            Bitmap barcode = null;            float scaleFactor = 1.0f;            if (bundle != null) {                byte[] compressedBitmap = bundle.getByteArray(DecodeThread.BARCODE_BITMAP);                if (compressedBitmap != null) {                    barcode = BitmapFactory.decodeByteArray(compressedBitmap, 0, compressedBitmap.length, null);                    // Mutable copy:                    barcode = barcode.copy(Bitmap.Config.ARGB_8888, true);                }                scaleFactor = bundle.getFloat(DecodeThread.BARCODE_SCALED_FACTOR);            }            activity.handleDecode((Result) message.obj, barcode, scaleFactor);        } }

生成二维码

只需要以下核心代码:

public static Bitmap encodeAsBitmap(String contents, int dimension) throws WriterException {        String contentsToEncode = contents;        if (contentsToEncode == null) {            return null;        }        Map<EncodeHintType, Object> hints = null;        String encoding = guessAppropriateEncoding(contentsToEncode);        if (encoding != null) {            hints = new EnumMap<>(EncodeHintType.class);            hints.put(EncodeHintType.CHARACTER_SET, encoding);        }        BitMatrix result;        try {            result = new MultiFormatWriter().encode(contentsToEncode, BarcodeFormat.QR_CODE, dimension, dimension, hints);        } catch (IllegalArgumentException iae) {            // Unsupported format            return null;        }        int width = result.getWidth();        int height = result.getHeight();        int[] pixels = new int[width * height];        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;            }        }        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);        bitmap.setPixels(pixels, 0, width, 0, 0, width, height);        return bitmap;    }    private static String guessAppropriateEncoding(CharSequence contents) {        // Very crude at the moment        for (int i = 0; i < contents.length(); i++) {            if (contents.charAt(i) > 0xFF) {                return "UTF-8";            }        }        return null;    }

源码

官方的例子和我自己的抽离出的代码都上传github了,地址:https://github.com/WuXiaolong/zxingSample

0 0
原创粉丝点击