From c0a1e285ab98b28962b19f1d5673928b20a95bc1 Mon Sep 17 00:00:00 2001 From: Gerhard Date: Wed, 18 Mar 2020 14:03:30 +0100 Subject: [PATCH 1/6] add button to take picture manually --- example/RNExampleApp/config/DocumentConfig.js | 5 + .../reactnative/Document4Activity.java | 138 ++++++++++++++++-- .../src/main/res/drawable/manual_picture.png | Bin 0 -> 3734 bytes .../res/layout/activity_scan_document.xml | 99 ++++++------- 4 files changed, 177 insertions(+), 65 deletions(-) create mode 100644 plugin/android/src/main/res/drawable/manual_picture.png diff --git a/example/RNExampleApp/config/DocumentConfig.js b/example/RNExampleApp/config/DocumentConfig.js index a8be4259..88c553e1 100755 --- a/example/RNExampleApp/config/DocumentConfig.js +++ b/example/RNExampleApp/config/DocumentConfig.js @@ -57,6 +57,11 @@ export default { }, "cancelOnResult": true }, + "document": { + "manualCaptureButton": { + "buttonColor": "0099ff" + } + }, quality: 90 }, } diff --git a/plugin/android/src/main/java/com/anyline/reactnative/Document4Activity.java b/plugin/android/src/main/java/com/anyline/reactnative/Document4Activity.java index f4b4169e..47816a02 100644 --- a/plugin/android/src/main/java/com/anyline/reactnative/Document4Activity.java +++ b/plugin/android/src/main/java/com/anyline/reactnative/Document4Activity.java @@ -4,6 +4,7 @@ import android.animation.ValueAnimator; import android.app.ProgressDialog; import android.graphics.Bitmap; +import android.graphics.Color; import android.graphics.PointF; import android.os.Bundle; import android.util.Log; @@ -14,6 +15,7 @@ import android.view.animation.AccelerateInterpolator; import android.view.animation.DecelerateInterpolator; import android.widget.FrameLayout; +import android.widget.ImageButton; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; @@ -54,13 +56,15 @@ public class Document4Activity extends AnylineBaseActivity implements CameraOpen private long lastErrorRecieved = 0; private int quality = 100; private Runnable errorMessageCleanup; + private ImageButton btnCapture; + JSONObject jsonResult; private android.os.Handler handler = new android.os.Handler(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(getResources().getIdentifier("activity_scan_scanview", "layout", getPackageName())); + setContentView(getResources().getIdentifier("activity_scan_document", "layout", getPackageName())); // takes care of fading the error message out after some time with no error reported from the SDK @@ -101,14 +105,53 @@ public void run() { documentScanView.setCameraOpenListener(this); // the view can be configured via a json file in the assets, and this config is set here + JSONObject json = null; try { - final JSONObject json = new JSONObject(configJson); + json = new JSONObject(configJson); documentScanView.setScanConfig(json, licenseKey); } catch (Exception e) { e.printStackTrace(); + Log.i(TAG, "**************** Exception: " + e); } + btnCapture = findViewById(getResources().getIdentifier("capture", "id", getPackageName())); + // get Document specific Configs + if (json.has("document")) { + try { + // Get the Document specific Config + JSONObject documentConfig = json.getJSONObject("document"); + + // set manual capture Button Config + if (documentConfig.has("manualCaptureButton")) { + JSONObject manCapBtnConf = documentConfig.getJSONObject("manualCaptureButton"); + + if (manCapBtnConf.has("buttonColor")) { + //btnCapture.setBackgroundColor(Color.parseColor("#" + manCapBtnConf.getString("buttonColor"))); + btnCapture.setColorFilter(Color.parseColor("#" + manCapBtnConf.getString("buttonColor"))); + + } + + // init Manual Capture Button + btnCapture.setVisibility(View.VISIBLE); + btnCapture.setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(View v) { + btnCapture.setClickable(false); + documentScanView.stop(); + ((DocumentScanViewPlugin) documentScanView.getScanViewPlugin()).triggerPictureCornerDetection(); + } + }); + + } else { + btnCapture.setVisibility(View.GONE); + } + + } catch (JSONException e) { + Log.e(TAG, e.getMessage()); + } + } // initialize Anyline with the license key and a Listener that is called if a result is found documentScanView.getScanViewPlugin().addScanResultListener(new DocumentScanResultListener() { @@ -119,6 +162,7 @@ public void onResult(ScanResult documentResult) { if (progressDialog != null && progressDialog.isShowing()) { progressDialog.dismiss(); } + btnCapture.setClickable(false); AnylineImage transformedImage = (AnylineImage) documentResult.getResult(); AnylineImage fullFrame = documentResult.getFullImage(); @@ -158,7 +202,8 @@ public void onResult(ScanResult documentResult) { File outDir = new File(getCacheDir(), "ok"); outDir.mkdir(); // change the file ending to png if you want a png - JSONObject jsonResult = new JSONObject(); + //JSONObject + jsonResult = new JSONObject(); try { // convert the transformed image into a gray scaled image internally // transformedImage.getGrayCvMat(false); @@ -166,9 +211,10 @@ public void onResult(ScanResult documentResult) { // Bitmap bmp = transformedImage.getBitmap(); // save the image with quality 100 (only used for jpeg, ignored for png) File imageFile = TempFileUtil.createTempFileCheckCache(Document4Activity.this, - UUID.randomUUID().toString(), ".jpg"); + UUID.randomUUID().toString(), ".jpg"); transformedImage.save(imageFile, quality); - showToast(getString(getResources().getIdentifier("document_image_saved_to", "string", getPackageName())) + " " + imageFile.getAbsolutePath()); + showToast(getString( + getResources().getIdentifier("document_image_saved_to", "string", getPackageName())) + " " + imageFile.getAbsolutePath()); jsonResult.put("imagePath", imageFile.getAbsolutePath()); @@ -176,7 +222,7 @@ public void onResult(ScanResult documentResult) { // Save the Full Frame Image if (fullFrame != null) { imageFile = TempFileUtil.createTempFileCheckCache(Document4Activity.this, - UUID.randomUUID().toString(), ".jpg"); + UUID.randomUUID().toString(), ".jpg"); fullFrame.save(imageFile, quality); jsonResult.put("fullImagePath", imageFile.getAbsolutePath()); } @@ -209,10 +255,9 @@ public void onResult(ScanResult documentResult) { setResult(AnylineSDKPlugin.RESULT_OK); finish(); } else { + btnCapture.setClickable(true); ResultReporter.onResult(jsonResult, false); } - - } @@ -241,7 +286,7 @@ public void onPictureProcessingFailure(DocumentScanViewPlugin.DocumentError docu // if there is a problem, here is how images could be saved in the error case // this will be a full, not cropped, not transformed image - AnylineImage image = ((DocumentScanViewPlugin)documentScanView.getScanViewPlugin()).getCurrentFullImage(); + AnylineImage image = ((DocumentScanViewPlugin) documentScanView.getScanViewPlugin()).getCurrentFullImage(); if (image != null) { File outDir = new File(getCacheDir(), "error"); @@ -268,9 +313,11 @@ public boolean onDocumentOutlineDetected(List rect, boolean documentShapeAndBrig @Override public void onTakePictureSuccess() { // this is called after the image has been captured from the camera and is about to be processed - progressDialog = ProgressDialog.show(Document4Activity.this, getString(getResources().getIdentifier("document_processing_picture_header", "string", getPackageName())), - getString(getResources().getIdentifier("document_processing_picture", "string", getPackageName())), - true); + progressDialog = ProgressDialog.show(Document4Activity.this, getString( + getResources().getIdentifier("document_processing_picture_header", "string", getPackageName())), + getString( + getResources().getIdentifier("document_processing_picture", "string", getPackageName())), + true); if (errorMessageAnimator != null && errorMessageAnimator.isRunning()) { @@ -293,16 +340,76 @@ public void onTakePictureError(Throwable throwable) { } @Override - public void onPictureCornersDetected(AnylineImage anylineImage, List rect) { + public void onPictureCornersDetected(AnylineImage anylineImage, List list) { // this is called after manual corner detection was requested - // Note: not implemented in this example + + // save fullFrame + //JSONObject + jsonResult = new JSONObject(); + + try { + File imageFile = TempFileUtil.createTempFileCheckCache(Document4Activity.this, UUID.randomUUID().toString(), ".jpg"); + anylineImage.save(imageFile, quality); + //manualResult.put("fullImagePath", imageFile.getAbsolutePath()); + jsonResult.put("fullImagePath", imageFile.getAbsolutePath()); + jsonResult.put("outline", jsonForOutline(list)); + } catch (IOException e) { + e.printStackTrace(); + } catch (JSONException e) { + e.printStackTrace(); + } + + ((DocumentScanViewPlugin) documentScanView.getScanViewPlugin()).transformPicture(anylineImage, list); + anylineImage.release(); } + @Override public void onPictureTransformed(AnylineImage anylineImage) { // this is called after a full frame image and 4 corners were passed to the SDK for // transformation (e.g. when a user manually selected the corners in an image) - // Note: not implemented in this example + + // handle the result document images here + if (progressDialog != null && progressDialog.isShowing()) { + progressDialog.dismiss(); + } + + // save fullFrame + try { + File imageFile = TempFileUtil.createTempFileCheckCache(Document4Activity.this, UUID.randomUUID().toString(), ".jpg"); + anylineImage.save(imageFile, quality); + jsonResult.put("imagePath", imageFile.getAbsolutePath()); + + // if (showSuccessToast) { + // // Only show toast if user has specified it should be shown + // showToast(getString(getResources().getIdentifier("document_image_saved_to", "string", getPackageName())) + " " + imageFile.getAbsolutePath()); + // } + + } catch (IOException e) { + e.printStackTrace(); + } catch (JSONException e) { + e.printStackTrace(); + } + + anylineImage.release(); + + Boolean cancelOnResult = true; + JSONObject jsonObject; + try { + jsonObject = new JSONObject(configJson); + cancelOnResult = jsonObject.getBoolean("cancelOnResult"); + } catch (Exception e) { + e.printStackTrace(); + } + + if (cancelOnResult) { + ResultReporter.onResult(jsonResult, true); + setResult(AnylineSDKPlugin.RESULT_OK); + finish(); + } else { + btnCapture.setClickable(true); + ResultReporter.onResult(jsonResult, false); + } } @Override @@ -313,7 +420,6 @@ public void onPictureTransformError(DocumentScanViewPlugin.DocumentError documen }); - // optionally stop the scan once a valid result was returned // documentScanView.setCancelOnResult(cancelOnResult); diff --git a/plugin/android/src/main/res/drawable/manual_picture.png b/plugin/android/src/main/res/drawable/manual_picture.png new file mode 100644 index 0000000000000000000000000000000000000000..e1627352a293f1e92a2a9a1bd7f09262a405d045 GIT binary patch literal 3734 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 literal 0 HcmV?d00001 diff --git a/plugin/android/src/main/res/layout/activity_scan_document.xml b/plugin/android/src/main/res/layout/activity_scan_document.xml index 58c55903..eb81a22d 100755 --- a/plugin/android/src/main/res/layout/activity_scan_document.xml +++ b/plugin/android/src/main/res/layout/activity_scan_document.xml @@ -1,62 +1,63 @@ - + - + + android:id="@+id/image_result" + android:layout_width="100dp" + android:layout_height="wrap_content" + android:layout_alignParentRight="true" + android:layout_alignParentBottom="true" + android:adjustViewBounds="true" /> + android:id="@+id/full_image" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:layout_alignParentLeft="true" + android:layout_alignParentBottom="true" + android:adjustViewBounds="true" /> -