Merge pull request #792 from ziegenberg/790-qr-code-not-found-in-image-file

fix QR code not found in image file
This commit is contained in:
Jakob Nixdorf 2021-03-17 06:36:58 +01:00 committed by GitHub
commit 780b880c9d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 90 additions and 24 deletions

View file

@ -72,12 +72,7 @@ dependencies {
implementation "com.github.aakira:expandable-layout:1.6.0"
implementation "com.heinrichreimersoftware:material-intro:2.0.0"
implementation("com.journeyapps:zxing-android-embedded:4.1.0") { transitive = false }
implementation('com.google.zxing:core') {
version {
strictly '[3.3, 3.4[' // Keep pinned below 3.4 to support SDK versions below 24
prefer '3.3.0'
}
}
implementation('com.google.zxing:core:3.4.1')
implementation "com.vanniktech:vntnumberpickerpreference:1.0.0"
implementation "me.zhanghai.android.materialprogressbar:library:1.6.1"
implementation "org.sufficientlysecure:openpgp-api:12.0"

View file

@ -1,3 +1,26 @@
/*
* Copyright (C) 2017-2020 Jakob Nixdorf
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.shadowice.flocke.andotp.Utilities;
import android.content.Context;
@ -6,21 +29,44 @@ import android.graphics.BitmapFactory;
import android.net.Uri;
import android.widget.Toast;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.ChecksumException;
import com.google.zxing.DecodeHintType;
import com.google.zxing.FormatException;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.NotFoundException;
import com.google.zxing.RGBLuminanceSource;
import com.google.zxing.Reader;
import com.google.zxing.ReaderException;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.QRCodeReader;
import org.shadowice.flocke.andotp.R;
import java.io.IOException;
import java.util.EnumMap;
import java.util.Map;
import java.util.Vector;
public class ScanQRCodeFromFile {
private static final Map<DecodeHintType, Object> HINTS;
private static final Map<DecodeHintType, Object> HINTS_HARDER;
static {
Vector<BarcodeFormat> barcodeFormats = new Vector<>();
barcodeFormats.add(BarcodeFormat.QR_CODE);
HINTS = new EnumMap<>(DecodeHintType.class);
HINTS.put(DecodeHintType.POSSIBLE_FORMATS, barcodeFormats);
HINTS_HARDER = new EnumMap<>(HINTS);
HINTS_HARDER.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
}
public static String scanQRImage(Context context, Uri uri) {
//Check if external storage is accessible
if (!Tools.isExternalStorageReadable()) {
@ -30,35 +76,60 @@ public class ScanQRCodeFromFile {
//Get image in bytes
byte[] imageInBytes;
try {
imageInBytes = StorageAccessHelper.loadFile(context,uri);
imageInBytes = StorageAccessHelper.loadFile(context, uri);
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(context,R.string.toast_file_load_error,Toast.LENGTH_LONG).show();
Toast.makeText(context, R.string.toast_file_load_error, Toast.LENGTH_LONG).show();
return null;
}
Bitmap bMap = BitmapFactory.decodeByteArray(imageInBytes,0,imageInBytes.length);
Bitmap bMap = BitmapFactory.decodeByteArray(imageInBytes, 0, imageInBytes.length);
String contents = null;
int[] intArray = new int[bMap.getWidth()*bMap.getHeight()];
int[] intArray = new int[bMap.getWidth() * bMap.getHeight()];
bMap.getPixels(intArray, 0, bMap.getWidth(), 0, 0, bMap.getWidth(), bMap.getHeight());
LuminanceSource source = new RGBLuminanceSource(bMap.getWidth(), bMap.getHeight(), intArray);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Reader reader = new MultiFormatReader();
//Try finding QR code
Result result = null;
QRCodeReader reader = new QRCodeReader();
ReaderException savedException = null;
try {
Result result = reader.decode(bitmap);
//Try finding QR code
result = reader.decode(bitmap, HINTS);
contents = result.getText();
} catch (NotFoundException e) {
e.printStackTrace();
Toast.makeText(context,R.string.toast_qr_error,Toast.LENGTH_LONG).show();
} catch (ChecksumException e) {
e.printStackTrace();
Toast.makeText(context,R.string.toast_qr_checksum_exception,Toast.LENGTH_LONG).show();
} catch (FormatException e) {
e.printStackTrace();
Toast.makeText(context,R.string.toast_qr_format_error,Toast.LENGTH_LONG).show();
} catch (ReaderException re) {
savedException = re;
}
if (contents == null) {
try {
//Try finding QR code really hard
result = reader.decode(bitmap, HINTS_HARDER);
contents = result.getText();
} catch (ReaderException re) {
savedException = re;
}
}
if (contents == null) {
try {
throw savedException == null ? NotFoundException.getNotFoundInstance() : savedException;
} catch (ChecksumException e) {
e.printStackTrace();
Toast.makeText(context, R.string.toast_qr_checksum_exception, Toast.LENGTH_LONG).show();
} catch (FormatException e) {
e.printStackTrace();
Toast.makeText(context, R.string.toast_qr_format_error, Toast.LENGTH_LONG).show();
} catch (ReaderException e) { // Including NotFoundException
e.printStackTrace();
Toast.makeText(context, R.string.toast_qr_error, Toast.LENGTH_LONG).show();
}
}
//Return QR code (if found)
return contents;
}