X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=android%2Fsrc%2Fcom%2Fgoogle%2Fzxing%2Fclient%2Fandroid%2FDecodeThread.java;h=b383b4760024b99c0479ee43151bd5b5b9c4110b;hb=608fe313d82bb79f0f5a96856697bdfb4a6305d3;hp=85c0a5585e8e74c192a6d03a047dc563814579d5;hpb=85520988ce383472fdf99da36ca3935570a2af80;p=zxing.git diff --git a/android/src/com/google/zxing/client/android/DecodeThread.java b/android/src/com/google/zxing/client/android/DecodeThread.java index 85c0a558..b383b476 100755 --- a/android/src/com/google/zxing/client/android/DecodeThread.java +++ b/android/src/com/google/zxing/client/android/DecodeThread.java @@ -16,42 +16,50 @@ package com.google.zxing.client.android; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.BinaryBitmap; +import com.google.zxing.DecodeHintType; +import com.google.zxing.MultiFormatReader; +import com.google.zxing.ReaderException; +import com.google.zxing.Result; +import com.google.zxing.ResultPointCallback; +import com.google.zxing.common.HybridBinarizer; + import android.content.SharedPreferences; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.preference.PreferenceManager; -import com.google.zxing.BarcodeFormat; -import com.google.zxing.DecodeHintType; -import com.google.zxing.MultiFormatReader; -import com.google.zxing.ReaderException; -import com.google.zxing.Result; +import android.util.Log; -import java.util.Date; import java.util.Hashtable; import java.util.Vector; /** * This thread does all the heavy lifting of decoding the images. + * + * @author dswitkin@google.com (Daniel Switkin) */ final class DecodeThread extends Thread { - public static final String BARCODE_BITMAP = "barcode_bitmap"; + private static final String TAG = "DecodeThread"; - public Handler mHandler; - private BarcodesCaptureActivity mActivity; - private MultiFormatReader mMultiFormatReader; + private Handler handler; + private final CaptureActivity activity; + private final MultiFormatReader multiFormatReader; + private final ResultPointCallback resultPointCallback; - DecodeThread(BarcodesCaptureActivity activity, String mode) { - mActivity = activity; - mMultiFormatReader = new MultiFormatReader(); + DecodeThread(CaptureActivity activity, String mode, ResultPointCallback resultPointCallback) { + this.activity = activity; + multiFormatReader = new MultiFormatReader(); + this.resultPointCallback = resultPointCallback; // The prefs can't change while the thread is running, so pick them up once here. if (mode == null || mode.length() == 0) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); - boolean decode1D = prefs.getBoolean(BarcodesPreferenceActivity.KEY_DECODE_1D, true); - boolean decodeQR = prefs.getBoolean(BarcodesPreferenceActivity.KEY_DECODE_QR, true); + boolean decode1D = prefs.getBoolean(PreferencesActivity.KEY_DECODE_1D, true); + boolean decodeQR = prefs.getBoolean(PreferencesActivity.KEY_DECODE_QR, true); if (decode1D && decodeQR) { setDecodeAllMode(); } else if (decode1D) { @@ -72,10 +80,15 @@ final class DecodeThread extends Thread { } } + Handler getHandler() { + return handler; + } + @Override public void run() { Looper.prepare(); - mHandler = new Handler() { + handler = new Handler() { + @Override public void handleMessage(Message message) { switch (message.what) { case R.id.decode: @@ -91,41 +104,53 @@ final class DecodeThread extends Thread { } private void setDecodeProductMode() { - Hashtable hints = new Hashtable(3); - Vector vector = new Vector(); - vector.addElement(BarcodeFormat.UPC_A); - vector.addElement(BarcodeFormat.UPC_E); - vector.addElement(BarcodeFormat.EAN_13); - vector.addElement(BarcodeFormat.EAN_8); - hints.put(DecodeHintType.POSSIBLE_FORMATS, vector); - mMultiFormatReader.setHints(hints); + doSetDecodeMode(BarcodeFormat.UPC_A, + BarcodeFormat.UPC_E, + BarcodeFormat.EAN_13, + BarcodeFormat.EAN_8); } - // TODO: This is fragile in case we add new formats. It would be better to have a new enum - // value which represented all 1D formats. + /** + * Select the 1D formats we want this client to decode by hand. + */ private void setDecode1DMode() { - Hashtable hints = new Hashtable(3); - Vector vector = new Vector(); - vector.addElement(BarcodeFormat.UPC_A); - vector.addElement(BarcodeFormat.UPC_E); - vector.addElement(BarcodeFormat.EAN_13); - vector.addElement(BarcodeFormat.EAN_8); - vector.addElement(BarcodeFormat.CODE_39); - vector.addElement(BarcodeFormat.CODE_128); - hints.put(DecodeHintType.POSSIBLE_FORMATS, vector); - mMultiFormatReader.setHints(hints); + doSetDecodeMode(BarcodeFormat.UPC_A, + BarcodeFormat.UPC_E, + BarcodeFormat.EAN_13, + BarcodeFormat.EAN_8, + BarcodeFormat.CODE_39, + BarcodeFormat.CODE_128, + BarcodeFormat.ITF); } private void setDecodeQRMode() { - Hashtable hints = new Hashtable(3); - Vector vector = new Vector(); - vector.addElement(BarcodeFormat.QR_CODE); - hints.put(DecodeHintType.POSSIBLE_FORMATS, vector); - mMultiFormatReader.setHints(hints); + doSetDecodeMode(BarcodeFormat.QR_CODE); } + /** + * Instead of calling setHints(null), which would allow new formats to sneak in, we + * explicitly set which formats are available. + */ private void setDecodeAllMode() { - mMultiFormatReader.setHints(null); + doSetDecodeMode(BarcodeFormat.UPC_A, + BarcodeFormat.UPC_E, + BarcodeFormat.EAN_13, + BarcodeFormat.EAN_8, + BarcodeFormat.CODE_39, + BarcodeFormat.CODE_128, + BarcodeFormat.ITF, + BarcodeFormat.QR_CODE); + } + + private void doSetDecodeMode(BarcodeFormat... formats) { + Hashtable hints = new Hashtable(3); + Vector vector = new Vector(formats.length); + for (BarcodeFormat format : formats) { + vector.addElement(format); + } + hints.put(DecodeHintType.POSSIBLE_FORMATS, vector); + hints.put(DecodeHintType.NEED_RESULT_POINT_CALLBACK, resultPointCallback); + multiFormatReader.setHints(hints); } /** @@ -137,31 +162,27 @@ final class DecodeThread extends Thread { * @param height The height of the preview frame. */ private void decode(byte[] data, int width, int height) { - Date startDate = new Date(); - boolean success; + long start = System.currentTimeMillis(); Result rawResult = null; - YUVMonochromeBitmapSource source = new YUVMonochromeBitmapSource(data, width, height, - CameraManager.get().getFramingRect()); + PlanarYUVLuminanceSource source = CameraManager.get().buildLuminanceSource(data, width, height); + BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); try { - rawResult = mMultiFormatReader.decodeWithState(source); - success = true; - } catch (ReaderException e) { - success = false; + rawResult = multiFormatReader.decodeWithState(bitmap); + } catch (ReaderException re) { + // continue } - Date endDate = new Date(); - if (success) { - Message message = Message.obtain(mActivity.mHandler, R.id.decode_succeeded, rawResult); - message.arg1 = (int) (endDate.getTime() - startDate.getTime()); + if (rawResult != null) { + long end = System.currentTimeMillis(); + Log.v(TAG, "Found barcode (" + (end - start) + " ms):\n" + rawResult.toString()); + Message message = Message.obtain(activity.getHandler(), R.id.decode_succeeded, rawResult); Bundle bundle = new Bundle(); - bundle.putParcelable(BARCODE_BITMAP, source.renderToBitmap()); + bundle.putParcelable(BARCODE_BITMAP, source.renderCroppedGreyscaleBitmap()); message.setData(bundle); message.sendToTarget(); } else { - Message message = Message.obtain(mActivity.mHandler, R.id.decode_failed); - message.arg1 = (int) (endDate.getTime() - startDate.getTime()); + Message message = Message.obtain(activity.getHandler(), R.id.decode_failed); message.sendToTarget(); } } - }