#android #zxing
#Android #zxing
Вопрос:
Редактировать:
Поиграв с ним несколько часов, я пришел к выводу, что проблема в качестве изображения. Например, первое изображение — это то, как оно появилось с камеры. Декодер не может его прочитать. Второе изображение превращается в черно-белое с регулируемой контрастностью, и декодер отлично его считывает.
Поскольку демонстрационное приложение, поставляемое с zxing, способно считывать первое изображение с монитора за несколько секунд, я думаю, что проблема может быть в какой-то настройке глубоко в библиотеке zxing. Он не ждет достаточно долго, чтобы обработать изображение, но выдает NotFound почти мгновенно.
Я создаю простое приложение для чтения QR-кодов. Вот скриншот. Верхняя черная область — это surfaceview, который показывает кадры с камеры. Он работает нормально, только вы не видите его на скриншоте.
Затем, когда я нажимаю кнопку, растровое изображение берется из этого surfaceview, помещается в ImageView ниже и пытается быть прочитанным библиотекой zxing.
Тем не менее, он выдаст NotFoundException. :/
**10-17 19:53:15.382: WARN/System.err(2238): com.google.zxing.NotFoundException
10-17 19:53:15.382: WARN/dalvikvm(2238): getStackTrace() called but no trace available**
С другой стороны, если я обрезаю qr-изображение с этого снимка экрана, помещаю его в imageview (вместо ленты с камеры) и пытаюсь его декодировать, все работает нормально. Поэтому само QR-изображение и его качество в порядке… но тогда почему он не декодируется в первом сценарии?
Спасибо!
public void dec(View v)
{
ImageView ivCam2 = (ImageView)findViewById(R.id.imageView2);
ivCam2.setImageBitmap(bm);
BitmapDrawable drawable = (BitmapDrawable) ivCam2.getDrawable();
Bitmap bMap = drawable.getBitmap();
TextView textv = (TextView) findViewById(R.id.mytext);
LuminanceSource source = new RGBLuminanceSource(bMap);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Reader reader = new MultiFormatReader();
try {
Result result = reader.decode(bitmap);
Global.text = result.getText();
byte[] rawBytes = result.getRawBytes();
BarcodeFormat format = result.getBarcodeFormat();
ResultPoint[] points = result.getResultPoints();
textv.setText(Global.text);
} catch (NotFoundException e) {
textv.setText("NotFoundException");
} catch (ChecksumException e) {
textv.setText("ChecksumException");
} catch (FormatException e) {
textv.setText("FormatException");
}
}
как создается растровое изображение:
@Override
public void surfaceCreated(SurfaceHolder holder)
{
try
{
this.camera = Camera.open();
this.camera.setPreviewDisplay(this.holder);
this.camera.setPreviewCallback(new PreviewCallback() {
public void onPreviewFrame(byte[] _data, Camera _camera) {
Camera.Parameters params = _camera.getParameters();
int w = params.getPreviewSize().width;
int h = params.getPreviewSize().height;
int format = params.getPreviewFormat();
YuvImage image = new YuvImage(_data, format, w, h, null);
ByteArrayOutputStream out = new ByteArrayOutputStream();
Rect area = new Rect(0, 0, w, h);
image.compressToJpeg(area, 50, out);
bm = BitmapFactory.decodeByteArray(out.toByteArray(), 0, out.size());
}
});
}
catch(IOException ioe)
{
ioe.printStackTrace(System.out);
}
}
Комментарии:
1. Как вы получаете растровое изображение из SurfaceView? Используете ли вы
SurfaceView.getDrawingCache()
?2. Нет, см. Выше. 🙂 Но я предполагаю, что с растровым изображением все в порядке, так как оно отображается в imageview.
3. можете ли вы добавить строку
e.printStackTrace()
в оператор catch, чтобы мы могли видеть, что происходит не так?
Ответ №1:
Я написал этот код. Быстрое возвращение не проблема. Декодирование происходит очень быстро на мобильном устройстве и очень быстро на рабочем столе.
Общий ответ на этот вопрос заключается в том, что некоторые изображения просто не будут декодироваться. Такова жизнь — эвристика не всегда все делает правильно. Но я не думаю, что это проблема здесь.
QR-коды не расшифровываются без минимальной белой «тихой зоны» вокруг них. Изображение за его границами считается белым для этой цели. Но на вашем необработанном изображении с камеры вокруг кода небольшая граница, и я бы поспорил, что бинаризатор не считает его белым.
Тем не менее, вы можете сделать еще больше. Например, установите подсказку TRY_HARDER для декодера, чтобы он тратил намного больше процессора на попытку декодирования. Вы также можете попробовать другую реализацию бинаризатора, чем HybridBinarizer по умолчанию.
(Остальное выглядит просто отлично. Я предполагаю, что RGBLuminanceSource
это получение данных в ожидаемом формате; это должно быть из Bitmap
)
Комментарии:
1. Спасибо за ответ! Не могли бы вы, пожалуйста, объяснить, куда я должен поместить этот TRY_HARDER и как мне попробовать разные реализации бинаризатора? Еще раз спасибо! 🙂
2.
decode()
содержит несколькоHashtable
подсказок. Установите значение keyDecodeHintType.TRY_HARDER
Boolean.TRUE
в этом аргументе. Вы видите, где вы используетеHybridBinarizer
? Попробуйте другую реализацию.3. Спасибо… Я установил для него значение TryHarder, теперь это занимает примерно 2 секунды, но все равно не дает результата. :/
4. Да, но это не то, что я думал, было проблемой. Вы выделили правильное пустое пространство вокруг изображения, как я упоминал выше?
5. Да, я сделал, все еще ничего. 🙂 Думаю, мне придется реализовать ZXING, как говорится в damianflannery.wordpress.com/2011/06/13 /… , надеюсь, я помогу. 🙂
Ответ №2:
Посмотрите на это: http://zxing.org/w/docs/javadoc/com/google/zxing/NotFoundException.html Исключение означает, что штрих-код не был найден на изображении. Мое предложение состояло бы в том, чтобы использовать вашу работу, которая работает, вместо того, чтобы пытаться декодировать не обрезанное изображение.
Комментарии:
1. Ну, чтобы заставить это работать, я вручную обрезал изображение в Photoshop из скриншота и загрузил его в декодер, просто чтобы убедиться, что это сработает, и это сработало. (для этого изображение в порядке) Вы предлагаете мне делать это каждый раз, когда я хочу что-то отсканировать ??? : P
2. В вашем описании вы ничего не сказали об обрезке изображения вручную. Я предположил, что вы обрезали его в программном обеспечении.