From 0aafe6fb38d19e8474483c4b8a28ce645c53045f Mon Sep 17 00:00:00 2001 From: Roy Ben-Shabat Date: Sun, 24 Mar 2019 15:24:21 +0200 Subject: WOrking on android. some fixes to machine studio. --- .../ColorCapture/app/src/main/cpp/native-lib.cpp | 46 +++--- .../twine/colorcapture/core/AnimationsHelper.java | 59 +++++++ .../com/twine/colorcapture/mvvm/FragmentBase.java | 5 + .../navigation/AndroidNavigationProvider.java | 1 + .../twine/colorcapture/opencv/ImageProcessor.java | 2 +- .../views/capture/CaptureFragment.java | 176 ++++++++------------- .../views/capture/CaptureFragmentVM.java | 110 ++++++++++++- .../views/capture/ICaptureFragment.java | 12 ++ .../colorcapture/views/main/MainActivity.java | 125 ++------------- .../app/src/main/res/layout/activity_main.xml | 32 +--- 10 files changed, 289 insertions(+), 279 deletions(-) create mode 100644 Software/Android_Studio/ColorCapture/app/src/main/java/com/twine/colorcapture/core/AnimationsHelper.java (limited to 'Software/Android_Studio') diff --git a/Software/Android_Studio/ColorCapture/app/src/main/cpp/native-lib.cpp b/Software/Android_Studio/ColorCapture/app/src/main/cpp/native-lib.cpp index 343203368..62d702b7f 100644 --- a/Software/Android_Studio/ColorCapture/app/src/main/cpp/native-lib.cpp +++ b/Software/Android_Studio/ColorCapture/app/src/main/cpp/native-lib.cpp @@ -8,8 +8,6 @@ using namespace cv; -Mat *mCanny = NULL; - enum RotateFlags { ROTATE_90DEG_CLOCKWISE = 0, //Rotate 90 degrees clockwise ROTATE_180DEG = 1, //Rotate 180 degrees clockwise @@ -33,28 +31,24 @@ void rot90(cv::Mat &matImage, int rotflag) { extern "C" JNIEXPORT jboolean JNICALL Java_com_twine_colorcapture_opencv_ImageProcessor_ProcessImage( - JNIEnv *env, jobject instance, jint width, - jint height, jbyteArray NV21FrameData, - jintArray outPixels,jintArray wrapedOutPixels) -{ + JNIEnv *env, jobject instance, jint frameWidth, + jint frameHeight, jint correctedWidth, jint correctedHeight, jbyteArray NV21FrameData, + jintArray outPixels, jintArray wrapedOutPixels) { jbyte *pNV21FrameData = env->GetByteArrayElements(NV21FrameData, 0); jint *poutPixels = env->GetIntArrayElements(outPixels, 0); jint *pwrapedPixels = env->GetIntArrayElements(wrapedOutPixels, 0); //// - jboolean has_result = false; + jboolean has_result = jboolean(false); try { ColorCaptureLib capture; - if (mCanny == NULL) { - mCanny = new Mat(height, width, CV_8UC1); - } - - Mat yuv(height + height / 2, width, CV_8UC1, (unsigned char *) pNV21FrameData); + Mat yuv(frameHeight + frameHeight / 2, frameWidth, CV_8UC1, + (unsigned char *) pNV21FrameData); Mat rgb; - Mat result(width, height, CV_8UC4, (unsigned char *) poutPixels); + Mat result(frameWidth, frameHeight, CV_8UC4, (unsigned char *) poutPixels); cvtColor(yuv, rgb, COLOR_YUV2RGB_NV21); Mat gray; @@ -69,7 +63,7 @@ Java_com_twine_colorcapture_opencv_ImageProcessor_ProcessImage( __android_log_print(ANDROID_LOG_ERROR, "FOCUS", "\n Focus measure is %f \n", focusMeasure); - rot90(rgb,ROTATE_180DEG); + rot90(rgb, ROTATE_180DEG); //resize(src, dst, dst.size(), 0, 0, interpolation); @@ -83,19 +77,23 @@ Java_com_twine_colorcapture_opencv_ImageProcessor_ProcessImage( circle(rgb, vertices[i], 2, CV_RGB(0, 0, 255), -1); } - int w = 300; - int h = 330; + int w = correctedWidth; + int h = correctedHeight; - Mat wraped(h,w,CV_8UC4, (unsigned char *) pwrapedPixels); + Mat wraped(h, w, CV_8UC4, (unsigned char *) pwrapedPixels); if (vertices.size() == 4) { has_result = jboolean(true); Mat m = capture.ApplyHomography(rgb, vertices, Size(w, h)); + + //Draw Blocks! + BhBlocks b(m, w / 10, h / 11); + b.drawBlocks(m, Scalar(255, 0, 0), 1); + cvtColor(m, wraped, COLOR_RGB2BGRA); - //BhBlocks b(image, w / columns, h / rows); - //b.drawBlocks(image, Scalar(0, 0, 0), 1); + m.release(); } cvtColor(rgb, result, COLOR_RGB2BGRA); @@ -125,9 +123,15 @@ Java_com_twine_colorcapture_opencv_ImageProcessor_ProcessImage( env->ReleaseByteArrayElements(NV21FrameData, pNV21FrameData, 0); env->ReleaseIntArrayElements(outPixels, poutPixels, 0); env->ReleaseIntArrayElements(wrapedOutPixels, pwrapedPixels, 0); + + yuv.release(); + rgb.release(); + result.release(); + wraped.release(); + dst.release(); + gray.release(); } - catch (Exception ex) - { + catch (Exception ex) { env->ThrowNew(env->FindClass("java/lang/NullPointerException"), ex.what()); } return has_result; diff --git a/Software/Android_Studio/ColorCapture/app/src/main/java/com/twine/colorcapture/core/AnimationsHelper.java b/Software/Android_Studio/ColorCapture/app/src/main/java/com/twine/colorcapture/core/AnimationsHelper.java new file mode 100644 index 000000000..a5faab0d1 --- /dev/null +++ b/Software/Android_Studio/ColorCapture/app/src/main/java/com/twine/colorcapture/core/AnimationsHelper.java @@ -0,0 +1,59 @@ +package com.twine.colorcapture.core; + +import android.view.View; +import android.view.animation.AlphaAnimation; +import android.view.animation.Animation; +import android.view.animation.Animation.AnimationListener; +import android.view.animation.ScaleAnimation; + +/** + * Contains helper methods related to animations. + */ +public class AnimationsHelper +{ + /** + * Animates the specified view scale transform. + */ + public static void animateScale(View v, float startScale, float endScale, int duration, boolean keepResult, IAction onCompleted) + { + Animation anim = new ScaleAnimation( + startScale, endScale, // Start and end values for the X axis scaling + 1f, 1f, // Start and end values for the Y axis scaling + Animation.RELATIVE_TO_SELF, 0f, // Pivot point of X scaling + Animation.RELATIVE_TO_SELF, 0f); // Pivot point of Y scaling + anim.setFillAfter(keepResult); // Needed to keep the result of the animation + anim.setDuration(duration); + anim.setAnimationListener(new AnimationListener() + { + @Override + public void onAnimationStart(Animation animation) + { + + } + + @Override + public void onAnimationEnd(Animation animation) + { + if (onCompleted != null) onCompleted.invoke(); + } + + @Override + public void onAnimationRepeat(Animation animation) + { + + } + }); + v.startAnimation(anim); + } + + /** + * Animates the specified view alpha channel. + */ + public static void animateAlpha(View v, float from, float to, int duration, boolean keepResult) + { + AlphaAnimation animation1 = new AlphaAnimation(from, to); + animation1.setDuration(duration); + animation1.setFillAfter(keepResult); + v.startAnimation(animation1); + } +} diff --git a/Software/Android_Studio/ColorCapture/app/src/main/java/com/twine/colorcapture/mvvm/FragmentBase.java b/Software/Android_Studio/ColorCapture/app/src/main/java/com/twine/colorcapture/mvvm/FragmentBase.java index d9cb58725..48d970a6c 100644 --- a/Software/Android_Studio/ColorCapture/app/src/main/java/com/twine/colorcapture/mvvm/FragmentBase.java +++ b/Software/Android_Studio/ColorCapture/app/src/main/java/com/twine/colorcapture/mvvm/FragmentBase.java @@ -1,5 +1,6 @@ package com.twine.colorcapture.mvvm; +import android.animation.Animator; import android.app.Fragment; import android.databinding.DataBindingUtil; import android.databinding.ViewDataBinding; @@ -8,10 +9,14 @@ import android.os.Handler; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.view.animation.Animation; +import android.view.animation.Animation.AnimationListener; +import android.view.animation.AnimationUtils; import android.widget.EditText; import android.widget.Toast; import com.mobsandgeeks.saripaar.ValidationError; import com.mobsandgeeks.saripaar.Validator; +import com.twine.colorcapture.R; import com.twine.colorcapture.core.IAction1; import java.lang.reflect.Method; diff --git a/Software/Android_Studio/ColorCapture/app/src/main/java/com/twine/colorcapture/navigation/AndroidNavigationProvider.java b/Software/Android_Studio/ColorCapture/app/src/main/java/com/twine/colorcapture/navigation/AndroidNavigationProvider.java index 68a6a3068..175a99b77 100644 --- a/Software/Android_Studio/ColorCapture/app/src/main/java/com/twine/colorcapture/navigation/AndroidNavigationProvider.java +++ b/Software/Android_Studio/ColorCapture/app/src/main/java/com/twine/colorcapture/navigation/AndroidNavigationProvider.java @@ -3,6 +3,7 @@ package com.twine.colorcapture.navigation; import android.app.FragmentManager; import android.app.FragmentTransaction; import android.support.v7.app.AppCompatActivity; +import android.util.Log; import com.twine.colorcapture.R; import com.twine.colorcapture.mvvm.ExtendedObject; diff --git a/Software/Android_Studio/ColorCapture/app/src/main/java/com/twine/colorcapture/opencv/ImageProcessor.java b/Software/Android_Studio/ColorCapture/app/src/main/java/com/twine/colorcapture/opencv/ImageProcessor.java index 02dde50e7..373f1009a 100644 --- a/Software/Android_Studio/ColorCapture/app/src/main/java/com/twine/colorcapture/opencv/ImageProcessor.java +++ b/Software/Android_Studio/ColorCapture/app/src/main/java/com/twine/colorcapture/opencv/ImageProcessor.java @@ -2,5 +2,5 @@ package com.twine.colorcapture.opencv; public class ImageProcessor { - public native boolean ProcessImage(int width, int height, byte[] NV21FrameData, int[] pixels,int[] wpixels); + public native boolean ProcessImage(int width, int height,int correctedWidth,int correctedHeight, byte[] NV21FrameData, int[] pixels,int[] wpixels); } diff --git a/Software/Android_Studio/ColorCapture/app/src/main/java/com/twine/colorcapture/views/capture/CaptureFragment.java b/Software/Android_Studio/ColorCapture/app/src/main/java/com/twine/colorcapture/views/capture/CaptureFragment.java index 491a05564..87e5c56cd 100644 --- a/Software/Android_Studio/ColorCapture/app/src/main/java/com/twine/colorcapture/views/capture/CaptureFragment.java +++ b/Software/Android_Studio/ColorCapture/app/src/main/java/com/twine/colorcapture/views/capture/CaptureFragment.java @@ -23,7 +23,6 @@ import android.widget.ImageView; import com.twine.colorcapture.App; import com.twine.colorcapture.R; -import com.twine.colorcapture.core.Task; import com.twine.colorcapture.core.Task.TaskBuilder; import com.twine.colorcapture.databinding.FragmentCaptureBinding; import com.twine.colorcapture.mvvm.FragmentBase; @@ -33,7 +32,6 @@ import com.yanzhenjie.zbar.ImageScanner; import com.yanzhenjie.zbar.Symbol; import com.yanzhenjie.zbar.SymbolSet; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.List; @@ -43,54 +41,45 @@ public class CaptureFragment extends FragmentBase { surfraceFrame.addView(surfaceView, new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); - },500); + }, 500); } - + private void startScanAnimation() { //Scanner overlay @@ -98,69 +87,70 @@ public class CaptureFragment extends FragmentBase sizes = parameters.getSupportedPreviewSizes(); - + for (Camera.Size size : parameters.getSupportedPreviewSizes()) { if (size.width >= 1200 & size.width <= 1280) @@ -210,30 +200,23 @@ public class CaptureFragment extends FragmentBase - { - bProcessing = true; - processor.ProcessImage(previewWidth, previewHeight, frameData, pixels, wrappedPixels); - bitmap.setPixels(pixels, 0, previewHeight, 0, 0, previewHeight, previewWidth); - wrappedBitmap.setPixels(wrappedPixels, 0, 300, 0, 0, 300, 330); + @Override + public void setListener(ICaptureFragmentListener listener) + { + this.listener = listener; + } - Log.d("BARCODE", "scanning barcode..."); - ImageScanner scanner = new ImageScanner(); - Image img = new Image(bitmap.getWidth(),bitmap.getHeight(),"RGB4"); - img.setData(pixels); - int result = scanner.scanImage(img.convert("Y800")); - - if (result != 0) - { - Log.d("BARCODE", "Got positive result..."); - - String text = null; - - SymbolSet symSet = scanner.getResults(); - for (Symbol sym : symSet) - text = sym.getData(); - - - String f = text; - - Log.d("BARCODE", "Barcode text is: " + text); - } - - }) - .setContinueWith(() -> - { - imagePreview.setImageBitmap(bitmap); - imagewrappedPreview.setImageBitmap(wrappedBitmap); - bProcessing = false; - }) - .build() - .start(); + @Override + public void onFrameResult(Bitmap frameBitmap, Bitmap correctedBitmap, String barcode) + { + imagePreview.setImageBitmap(frameBitmap); + imagewrappedPreview.setImageBitmap(correctedBitmap); } } \ No newline at end of file diff --git a/Software/Android_Studio/ColorCapture/app/src/main/java/com/twine/colorcapture/views/capture/CaptureFragmentVM.java b/Software/Android_Studio/ColorCapture/app/src/main/java/com/twine/colorcapture/views/capture/CaptureFragmentVM.java index 6be978036..b434b9dfb 100644 --- a/Software/Android_Studio/ColorCapture/app/src/main/java/com/twine/colorcapture/views/capture/CaptureFragmentVM.java +++ b/Software/Android_Studio/ColorCapture/app/src/main/java/com/twine/colorcapture/views/capture/CaptureFragmentVM.java @@ -1,8 +1,114 @@ package com.twine.colorcapture.views.capture; +import android.graphics.Bitmap; +import android.util.Log; +import android.util.Size; + +import com.twine.colorcapture.core.Task.TaskBuilder; import com.twine.colorcapture.mvvm.ViewModelBase; +import com.twine.colorcapture.opencv.ImageProcessor; +import com.twine.colorcapture.views.capture.ICaptureFragment.ICaptureFragmentListener; +import com.yanzhenjie.zbar.Image; +import com.yanzhenjie.zbar.ImageScanner; +import com.yanzhenjie.zbar.Symbol; +import com.yanzhenjie.zbar.SymbolSet; -public class CaptureFragmentVM extends ViewModelBase +public class CaptureFragmentVM extends ViewModelBase implements ICaptureFragmentListener { - + private ImageProcessor processor; + private Bitmap frameBitmap = null; + private Bitmap correctedBitmap = null; + private int[] framePixels = null; + private int[] correctedPixels = null; + private int previewWidth; + private int previewHeight; + private boolean isProcessing; + private byte[] frameData; + private String barcode; + private Size correctedSize = new Size(300, 330); //The desired cropped rectified bitmap. + + public CaptureFragmentVM() + { + processor = new ImageProcessor(); + } + + @Override + protected void onViewAttached(ICaptureFragment view) + { + super.onViewAttached(view); + view.setListener(this); + } + + @SuppressWarnings("SuspiciousNameCombination") + @Override + public void onFrameAvailable(byte[] frame) + { + if (!isProcessing) + { + isProcessing = true; + + frameData = frame; + + new TaskBuilder() + .setAction(() -> + { + isProcessing = true; + + processor.ProcessImage( + previewWidth, + previewHeight, + correctedSize.getWidth(), + correctedSize.getHeight(), + frameData, + framePixels, + correctedPixels); + + frameBitmap.setPixels(framePixels, 0, previewHeight, 0, 0, previewHeight, previewWidth); + correctedBitmap.setPixels(correctedPixels, 0, correctedSize.getWidth(), 0, 0, correctedSize.getWidth(), correctedSize.getHeight()); + + + Log.d("BARCODE", "scanning barcode..."); + ImageScanner scanner = new ImageScanner(); + Image img = new Image(frameBitmap.getWidth(), frameBitmap.getHeight(), "RGB4"); + img.setData(framePixels); + int result = scanner.scanImage(img.convert("Y800")); + + if (result != 0) + { + Log.d("BARCODE", "Got positive result..."); + + String text = null; + + SymbolSet symSet = scanner.getResults(); + for (Symbol sym : symSet) + text = sym.getData(); + + + barcode = text; + + Log.d("BARCODE", "Barcode text is: " + text); + } + + }) + .setContinueWith(() -> + { + view.onFrameResult(frameBitmap, correctedBitmap, barcode); + isProcessing = false; + }) + .build() + .start(); + } + } + + @SuppressWarnings("SuspiciousNameCombination") + @Override + public void onPreviewSettingsAvailable(int previewWidth, int previewHeight) + { + this.previewWidth = previewWidth; + this.previewHeight = previewHeight; + frameBitmap = Bitmap.createBitmap(previewHeight, previewWidth, Bitmap.Config.ARGB_8888); + correctedBitmap = Bitmap.createBitmap(correctedSize.getWidth(), correctedSize.getHeight(), Bitmap.Config.ARGB_8888); + framePixels = new int[previewWidth * previewHeight]; + correctedPixels = new int[correctedSize.getWidth() * correctedSize.getHeight()]; + } } diff --git a/Software/Android_Studio/ColorCapture/app/src/main/java/com/twine/colorcapture/views/capture/ICaptureFragment.java b/Software/Android_Studio/ColorCapture/app/src/main/java/com/twine/colorcapture/views/capture/ICaptureFragment.java index c88d632b6..434e5b10d 100644 --- a/Software/Android_Studio/ColorCapture/app/src/main/java/com/twine/colorcapture/views/capture/ICaptureFragment.java +++ b/Software/Android_Studio/ColorCapture/app/src/main/java/com/twine/colorcapture/views/capture/ICaptureFragment.java @@ -1,7 +1,19 @@ package com.twine.colorcapture.views.capture; +import android.graphics.Bitmap; + import com.twine.colorcapture.mvvm.IView; public interface ICaptureFragment extends IView { + void setListener(ICaptureFragmentListener listener); + + void onFrameResult(Bitmap frameBitmap,Bitmap correctedBitmap,String barcode); + + interface ICaptureFragmentListener + { + void onFrameAvailable(byte[] frame); + + void onPreviewSettingsAvailable(int previewWidth, int previewHeight); + } } diff --git a/Software/Android_Studio/ColorCapture/app/src/main/java/com/twine/colorcapture/views/main/MainActivity.java b/Software/Android_Studio/ColorCapture/app/src/main/java/com/twine/colorcapture/views/main/MainActivity.java index 56f426f9c..74e3d5707 100644 --- a/Software/Android_Studio/ColorCapture/app/src/main/java/com/twine/colorcapture/views/main/MainActivity.java +++ b/Software/Android_Studio/ColorCapture/app/src/main/java/com/twine/colorcapture/views/main/MainActivity.java @@ -4,7 +4,9 @@ import android.app.FragmentTransaction; import android.graphics.Color; import android.os.Bundle; import android.os.Handler; +import android.support.v4.widget.DrawerLayout; import android.util.Log; +import android.view.Gravity; import android.view.View; import android.view.animation.AlphaAnimation; import android.view.animation.Animation; @@ -35,7 +37,6 @@ import butterknife.ButterKnife; public class MainActivity extends ActivityBase implements IMainActivity { private boolean displayOnboarding = false; - private boolean isMenuOpened; @Inject public INavigationProvider navigationProvider; @@ -43,15 +44,12 @@ public class MainActivity extends ActivityBase { - showHeader(); - },2000); + new Handler().postDelayed(this::showHeader,2000); navigationProvider.navigateTo(NavigationView.Loading, false); } @@ -112,71 +108,8 @@ public class MainActivity extends ActivityBase { Log.d("TCC", "Clicked..."); - openMenu(); - }); - - frameMask.setOnClickListener((x) -> - { - Log.d("TCC", "Closed..."); - closeMenu(); - }); - - frameMask.setClickable(false); - frameMask.setFocusable(false); - } - - @Override - public void onBackPressed() - { - if (!isMenuOpened) - { - super.onBackPressed(); - } - else - { - closeMenu(); - } - } - - private void openMenu() - { - frameMask.setVisibility(View.VISIBLE); - frameMenu.setVisibility(View.VISIBLE); - frameMask.setClickable(true); - frameMask.setFocusable(true); - frameMenu.setClickable(true); - frameMenu.setFocusable(true); - frameMask.setAlpha(1); - animateAlpha(frameMask, 0, 1, 200, true); - frameMenu.setScaleX(1); - scaleView(frameMenu, 0, 1, 200, true, null); - isMenuOpened = true; - } - - private void closeMenu() - { - animateAlpha(frameMask, 1, 0, 200, true); - scaleView(frameMenu, 1, 0, 200, false, () -> - { - frameMask.setClickable(false); - frameMask.setFocusable(false); - frameMenu.setClickable(false); - frameMenu.setFocusable(false); - frameMask.setAlpha(0); - frameMask.setVisibility(View.GONE); - frameMenu.setVisibility(View.GONE); + drawerLayout.openDrawer(Gravity.START); }); - isMenuOpened = false; - } - - private void showHeader() - { - frameHeader.setVisibility(View.VISIBLE); - } - - private void hideHeader() - { - frameHeader.setVisibility(View.GONE); } @Override @@ -191,49 +124,13 @@ public class MainActivity extends ActivityBase - @@ -82,36 +82,10 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@+id/header" /> - - - - - - - - - - - + - + -- cgit v1.3.1