-
Notifications
You must be signed in to change notification settings - Fork 29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added ability to import a barcode from a local image #317
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,9 +4,11 @@ | |
import android.content.DialogInterface; | ||
import android.content.Intent; | ||
import android.content.res.TypedArray; | ||
import android.graphics.Bitmap; | ||
import android.graphics.Color; | ||
import android.os.Build; | ||
import android.os.Bundle; | ||
import android.provider.MediaStore; | ||
import android.support.design.widget.Snackbar; | ||
import android.support.v7.app.ActionBar; | ||
import android.support.v7.app.AlertDialog; | ||
|
@@ -24,16 +26,26 @@ | |
import android.widget.Toast; | ||
|
||
import com.google.zxing.BarcodeFormat; | ||
import com.google.zxing.BinaryBitmap; | ||
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.common.HybridBinarizer; | ||
import com.google.zxing.integration.android.IntentIntegrator; | ||
import com.google.zxing.integration.android.IntentResult; | ||
import com.jaredrummler.android.colorpicker.ColorPickerDialog; | ||
import com.jaredrummler.android.colorpicker.ColorPickerDialogListener; | ||
|
||
import java.io.IOException; | ||
|
||
public class LoyaltyCardEditActivity extends AppCompatActivity | ||
{ | ||
private static final String TAG = "CardLocker"; | ||
|
||
private static final int SELECT_BARCODE_REQUEST = 1; | ||
private static final int SELECT_IMAGE_REQUEST = 2; | ||
|
||
EditText storeFieldEdit; | ||
EditText noteFieldEdit; | ||
|
@@ -50,6 +62,7 @@ public class LoyaltyCardEditActivity extends AppCompatActivity | |
View barcodeCaptureLayout; | ||
|
||
Button captureButton; | ||
Button importImageButton; | ||
Button enterButton; | ||
|
||
int loyaltyCardId; | ||
|
@@ -102,6 +115,7 @@ protected void onCreate(Bundle savedInstanceState) | |
barcodeCaptureLayout = findViewById(R.id.barcodeCaptureLayout); | ||
|
||
captureButton = findViewById(R.id.captureButton); | ||
importImageButton = findViewById(R.id.importImageButton); | ||
enterButton = findViewById(R.id.enterButton); | ||
} | ||
|
||
|
@@ -260,6 +274,20 @@ public void onClick(View v) | |
|
||
captureButton.setOnClickListener(captureCallback); | ||
|
||
View.OnClickListener importImageCallback = new View.OnClickListener() | ||
{ | ||
@Override | ||
public void onClick(View v) | ||
{ | ||
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK); | ||
photoPickerIntent.setType("image/*"); | ||
photoPickerIntent.putExtra(Intent.EXTRA_LOCAL_ONLY, true); | ||
startActivityForResult(photoPickerIntent, SELECT_IMAGE_REQUEST); | ||
} | ||
}; | ||
|
||
importImageButton.setOnClickListener(importImageCallback); | ||
|
||
enterButton.setOnClickListener(new View.OnClickListener() | ||
{ | ||
@Override | ||
|
@@ -449,12 +477,46 @@ public void onActivityResult(int requestCode, int resultCode, Intent intent) | |
format = result.getFormatName(); | ||
} | ||
|
||
if(requestCode == SELECT_BARCODE_REQUEST && resultCode == Activity.RESULT_OK) | ||
if (resultCode == Activity.RESULT_OK) | ||
{ | ||
Log.i(TAG, "Received barcode information from typing it"); | ||
if(requestCode == SELECT_BARCODE_REQUEST) | ||
{ | ||
Log.i(TAG, "Received barcode information from typing it"); | ||
|
||
contents = intent.getStringExtra(BarcodeSelectorActivity.BARCODE_CONTENTS); | ||
format = intent.getStringExtra(BarcodeSelectorActivity.BARCODE_FORMAT); | ||
contents = intent.getStringExtra(BarcodeSelectorActivity.BARCODE_CONTENTS); | ||
format = intent.getStringExtra(BarcodeSelectorActivity.BARCODE_FORMAT); | ||
} | ||
else if (requestCode == SELECT_IMAGE_REQUEST) | ||
{ | ||
Log.i(TAG, "Received barcode image"); | ||
|
||
Bitmap bitmap = null; | ||
try { | ||
bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), intent.getData()); | ||
} catch (IOException e) { | ||
Log.e(TAG, "Error getting the image data"); | ||
e.printStackTrace(); | ||
return; | ||
} | ||
|
||
// In order to decode it, the Bitmap must first be converted into a pixel array... | ||
int[] intArray = new int[bitmap.getWidth()*bitmap.getHeight()]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you know what the failure mode is if a user selects an image which "is too big"? For example, in generating the barcode for display I've sometimes encountered issues with memory: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't actually know... I looked around and I'm still not sure about an OOM exception, however I did stumble upon people having issues with codes in huge images not being recognized. I'll do some more testing and maybe add a downscale step before processing. |
||
bitmap.getPixels(intArray, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight()); | ||
|
||
// ...and then turned into a binary bitmap from its luminance | ||
LuminanceSource source = new RGBLuminanceSource(bitmap.getWidth(), bitmap.getHeight(), intArray); | ||
BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(source)); | ||
|
||
try { | ||
Result qrCodeResult = new MultiFormatReader().decode(binaryBitmap); | ||
|
||
contents = qrCodeResult.getText(); | ||
format = qrCodeResult.getBarcodeFormat().name(); | ||
} catch (NotFoundException e) { | ||
Log.i(TAG, "No barcode was found"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this exception be logged? The e.printStackTrace() would not be captured, right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, I don't believe it should be. All it says is that there was no barcode in the image - which isn't truly an exception. The printStacktrace() was left there accidentally. I'll remove it. |
||
e.printStackTrace(); | ||
} | ||
} | ||
} | ||
|
||
if(contents != null && contents.isEmpty() == false && | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -368,12 +368,21 @@ | |
android:padding="10.0dip" | ||
android:layout_width="fill_parent" | ||
android:layout_height="wrap_content" | ||
android:id="@+id/barcodeCaptureLayout"> | ||
android:id="@+id/barcodeCaptureLayout" | ||
android:baselineAligned="false"> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If I understand correctly from this was likely necessary to get the buttons to align up correctly, correct? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. The new button spans two lines on narrower devices and the default is to align by text, not by their bounding boxes. |
||
|
||
<Button android:id="@+id/captureButton" | ||
android:layout_width="0dp" | ||
android:layout_height="wrap_content" | ||
android:text="@string/capture" | ||
android:layout_weight="1.0"/> | ||
|
||
<Button android:id="@+id/importImageButton" | ||
android:layout_width="0dp" | ||
android:layout_height="wrap_content" | ||
android:text="@string/importImage" | ||
android:layout_weight="1.0"/> | ||
|
||
<Button android:id="@+id/enterButton" | ||
android:layout_width="0dp" | ||
android:layout_height="wrap_content" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, should this be logged instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, printStacktrace() is, in fact, logged, but without the TAG. I'll move it into the Log.e call.