diff --git a/ID-Photo-DIY/README.md b/ID-Photo-DIY/README.md index e461eeb..41d482d 100644 --- a/ID-Photo-DIY/README.md +++ b/ID-Photo-DIY/README.md @@ -18,8 +18,8 @@ It uses image segmentation function of Huawei Machine Learning SDK. It uses stil ## Configuration To use functions provided by packages in examples, You need to add the dependencies to the build.gradle file as follows: - implementation 'com.huawei.hms:ml-computer-vision-image-segmentation-body-model:1.0.2.301' - implementation 'com.huawei.hms:ml-computer-vision:1.0.2.300' + implementation 'com.huawei.hms:ml-computer-vision-image-segmentation-body-model:1.0.3.300' + implementation 'com.huawei.hms:ml-computer-vision-segmentation:1.0.3.300' ## Supported Environments android 4.4 or a later version is recommended. diff --git a/ID-Photo-DIY/app/build.gradle b/ID-Photo-DIY/app/build.gradle index fb6ca0c..53199e8 100644 --- a/ID-Photo-DIY/app/build.gradle +++ b/ID-Photo-DIY/app/build.gradle @@ -32,6 +32,6 @@ dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' - implementation 'com.huawei.hms:ml-computer-vision:1.0.2.300' - implementation 'com.huawei.hms:ml-computer-vision-image-segmentation-body-model:1.0.2.301' + implementation 'com.huawei.hms:ml-computer-vision-segmentation:1.0.3.300' + implementation 'com.huawei.hms:ml-computer-vision-image-segmentation-body-model:1.0.3.300' } diff --git a/MLKit-Sample/README.md b/MLKit-Sample/README.md index 988333e..1b708e8 100644 --- a/MLKit-Sample/README.md +++ b/MLKit-Sample/README.md @@ -47,26 +47,24 @@ You only need to modify the applicationId in app HUAWEI-HMS-MLKit-Sample ## Installation -You can find the app-release.apk in code->releases->app-release.apk, you can download the APK, copy it to your phone, install and experience it. if you have installed adb on your computer, open the cmd window and install the application on your phone through adb install app-release. apk. - Download the HUAWEI-HMS-MLKit-Sample code and open in Android Studio, after ensuring that your device is connected to the network, obtain the apk through build. ## Configuration To use functions provided by packages in examples, You need to add the dependencies to the build.gradle file as follows: - implementation 'com.huawei.hms:ml-computer-vision-ocr-cn-model:1.0.2.300' - implementation 'com.huawei.hms:ml-computer-vision-ocr-jk-model:1.0.2.300' - implementation 'com.huawei.hms:ml-computer-vision-ocr-latin-model:1.0.2.300' - implementation 'com.huawei.hms:ml-computer-vision-image-classification-model:1.0.2.300' - implementation 'com.huawei.hms:ml-computer-vision-object-detection-model:1.0.2.300' - implementation 'com.huawei.hms:ml-computer-vision-face-recognition-model:1.0.2.300' - implementation 'com.huawei.hms:ml-computer-card-icr-cn-model:1.0.2.300' - implementation 'com.huawei.hms:ml-computer-vision-image-segmentation-model:1.0.2.300' - implementation 'com.huawei.hms:ml-computer-vision:1.0.2.300' - implementation 'com.huawei.hms:ml-computer-translate:1.0.2.300' - implementation 'com.huawei.hms:ml-computer-card-icr-cn-plugin:1.0.2.300' - implementation 'com.huawei.hms:ml-computer-language-detection:1.0.2.300' + implementation 'com.huawei.hms:ml-computer-vision-ocr-cn-model:1.0.3.300' + implementation 'com.huawei.hms:ml-computer-vision-ocr-jk-model:1.0.3.300' + implementation 'com.huawei.hms:ml-computer-vision-ocr-latin-model:1.0.3.300' + implementation 'com.huawei.hms:ml-computer-vision-image-classification-model:1.0.3.300' + implementation 'com.huawei.hms:ml-computer-vision-object-detection-model:1.0.3.300' + implementation 'com.huawei.hms:ml-computer-vision-face-recognition-model:1.0.3.300' + implementation 'com.huawei.hms:ml-computer-card-icr-cn-model:1.0.3.300' + implementation 'com.huawei.hms:ml-computer-vision-image-segmentation-model:1.0.3.300' + implementation 'com.huawei.hms:ml-computer-vision:1.0.3.300' + implementation 'com.huawei.hms:ml-computer-translate:1.0.3.300' + implementation 'com.huawei.hms:ml-computer-card-icr-cn-plugin:1.0.3.300' + implementation 'com.huawei.hms:ml-computer-language-detection:1.0.3.300' ## Supported Environments android 4.4 or a later version is recommended. @@ -81,26 +79,24 @@ Sample code majors activitys as follows: 2. Choose LoadPhotoActivity to see a demo of the following: - Image Segmentation(Segments the pixels representing specific elements (such as human body, plant, and sky) from an image) 3. Choose IDCardRecognitionActivity to see a demo of the following: - - Product Visual Search(Recognizes product information such as the product category in an image) - 4. Choose IDIdentificationActivity to see a demo of the following: - Chinese IDCard Recognition(Recognizes text in images of second-generation ID cards of Chinese mainland residents) - 5. Choose ObjectDetectionActivity to see a demo of the following: + 4. Choose ObjectDetectionActivity to see a demo of the following: - Object detection (Detects and tracks an object in images or video streams) - 6. Choose ImageClassificationActivity to see a demo of the following: + 5. Choose ImageClassificationActivity to see a demo of the following: - Image Classification(Classifies entities in images, such as people, objects, environments, activities, or artwork to define image themes and application scenarios) - 7. Choose FaceDetectionActivity to see a demo of the following: + 6. Choose FaceDetectionActivity to see a demo of the following: - Face detection (Detects and tracks faces) - Camera front and back flip - 8. Choose TranslatorActivity to see a demo of the following: + 7. Choose TranslatorActivity to see a demo of the following: - Language translation function - Automatic language monitoring for input text - Multi language support - 9. Choose TextRecognitionActivity to see a demo of the following: + 8. Choose TextRecognitionActivity to see a demo of the following: - Dynamic and real-time text recognition - Take photos after identifying words - Generated photos can be zoomed - It can load photos in the local album and parse the text in the photos (Cloud) - 10. Choose CloudDetectionActivity to see a demo of the following: + 9. Choose CloudDetectionActivity to see a demo of the following: - Document text recognition (Cloud) - Landmark recognition (Cloud) diff --git a/MLKit-Sample/app/.gitignore b/MLKit-Sample/app/.gitignore deleted file mode 100644 index e8091cc..0000000 --- a/MLKit-Sample/app/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/build -/gradle diff --git a/MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/AllFunctionActivity.java b/MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/AllFunctionActivity.java deleted file mode 100644 index 2ca738f..0000000 --- a/MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/AllFunctionActivity.java +++ /dev/null @@ -1,168 +0,0 @@ -/** - * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.mlkit.sample.activity; - -import android.graphics.Color; -import android.os.Bundle; -import android.view.View; - -import android.widget.TextView; - -import com.mlkit.sample.R; -import com.mlkit.sample.activity.adapter.TabFragmentAdapter; -import com.mlkit.sample.activity.fragment.LanguageCategoryFragment; -import com.mlkit.sample.activity.fragment.OtherCategoryFragment; -import com.mlkit.sample.activity.fragment.PictureCategoryFragment; - -import java.util.ArrayList; -import java.util.List; - -import androidx.fragment.app.Fragment; -import androidx.viewpager.widget.ViewPager; - -public class AllFunctionActivity extends BaseActivity implements View.OnClickListener { - - private List mFragmentList; - private TextView mBgChangeTv; - private TextView mCaptureImgTv; - private TextView mSliceTv; - private ViewPager mViewPager; - private View mBgChangeLine; - private View mCaptureImgLine; - private View mSliceLine; - private TabFragmentAdapter mAdapter; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - this.setContentView(R.layout.activity_all_function); - this.initView(); - this.setStatusBar(); - this.setStatusBarFontColor(); - } - - private void initView() { - this.findViewById(R.id.back).setOnClickListener(this); - this.mBgChangeTv = this.findViewById(R.id.fragment_one); - this.mCaptureImgTv = this.findViewById(R.id.fragment_two); - this.mSliceTv = this.findViewById(R.id.fragment_three); - this.mBgChangeLine = this.findViewById(R.id.line_one); - this.mCaptureImgLine = this.findViewById(R.id.line_two); - this.mSliceLine = this.findViewById(R.id.line_three); - this.mBgChangeTv.setOnClickListener(this); - this.mCaptureImgTv.setOnClickListener(this); - this.mSliceTv.setOnClickListener(this); - this.mViewPager = this.findViewById(R.id.view_pager); - // Bind click event. - this.mViewPager.setOnPageChangeListener(new PagerChangeListener()); - // Add fragment to the collection list. - this.mFragmentList = new ArrayList<>(); - this.mFragmentList.add(new PictureCategoryFragment()); - this.mFragmentList.add(new LanguageCategoryFragment()); - this.mFragmentList.add(new OtherCategoryFragment()); - - this.mAdapter = new TabFragmentAdapter(this.getSupportFragmentManager(), this.mFragmentList); - this.mViewPager.setAdapter(this.mAdapter); - this.mViewPager.setCurrentItem(0); - - } - - @Override - public void onClick(View v) { - switch (v.getId()) { - case R.id.fragment_one: - this.mViewPager.setCurrentItem(0); - this.setBgChangeView(); - break; - case R.id.fragment_two: - this.mViewPager.setCurrentItem(1); - this.setCaptureImageView(); - break; - case R.id.fragment_three: - this.mViewPager.setCurrentItem(2); - this.setSliceImageView(); - break; - case R.id.back: - this.finish(); - break; - default: - break; - } - } - - private void setBgChangeView() { - this.mBgChangeTv.setTextColor(this.getResources().getColor(R.color.button_background)); - this.mCaptureImgTv.setTextColor(Color.BLACK); - this.mSliceTv.setTextColor(Color.BLACK); - this.mBgChangeLine.setVisibility(View.VISIBLE); - this.mCaptureImgLine.setVisibility(View.GONE); - this.mSliceLine.setVisibility(View.GONE); - } - - private void setCaptureImageView() { - this.mBgChangeTv.setTextColor(Color.BLACK); - this.mCaptureImgTv.setTextColor(this.getResources().getColor(R.color.button_background)); - this.mSliceTv.setTextColor(Color.BLACK); - this.mBgChangeLine.setVisibility(View.GONE); - this.mCaptureImgLine.setVisibility(View.VISIBLE); - this.mSliceLine.setVisibility(View.GONE); - } - - private void setSliceImageView() { - this.mBgChangeTv.setTextColor(Color.BLACK); - this.mCaptureImgTv.setTextColor(Color.BLACK); - this.mSliceTv.setTextColor(this.getResources().getColor(R.color.button_background)); - this.mBgChangeLine.setVisibility(View.GONE); - this.mCaptureImgLine.setVisibility(View.GONE); - this.mSliceLine.setVisibility(View.VISIBLE); - } - - /** - * Set a ViewPager listening event. When the ViewPager is swiped left or right, the menu bar selected state changes accordingly. - */ - public class PagerChangeListener implements ViewPager.OnPageChangeListener { - - @Override - public void onPageScrollStateChanged(int arg0) { - } - - @Override - public void onPageScrolled(int arg0, float arg1, int arg2) { - } - - @Override - public void onPageSelected(int position) { - switch (position) { - case 0: - AllFunctionActivity.this.setBgChangeView(); - break; - case 1: - AllFunctionActivity.this.setCaptureImageView(); - break; - case 2: - AllFunctionActivity.this.setSliceImageView(); - break; - default: - break; - } - } - } - - public void onBackPressed(View view) { - this.finish(); - } -} diff --git a/MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/fragment/BaseFragment.java b/MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/fragment/BaseFragment.java deleted file mode 100644 index fbd1f05..0000000 --- a/MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/fragment/BaseFragment.java +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.mlkit.sample.activity.fragment; - -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.GridView; - -import com.mlkit.sample.R; -import com.mlkit.sample.activity.adapter.GridViewAdapter; -import com.mlkit.sample.activity.entity.GridViewItem; - - -import java.util.ArrayList; - -import androidx.fragment.app.Fragment; - -public abstract class BaseFragment extends Fragment { - - protected GridView mGridView; - private GridViewAdapter mAdapter; - protected ArrayList mDataList; - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.fragment_picture, container, false); - this.initData(); - this.mGridView = view.findViewById(R.id.gridview); - this.mAdapter = new GridViewAdapter(this.mDataList, this.getContext()); - this.mGridView.setAdapter(this.mAdapter); - this.initClickEvent(view); - return view; - } - - protected abstract void initClickEvent(View view); - - protected abstract void initData(); -} diff --git a/MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/fragment/LanguageCategoryFragment.java b/MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/fragment/LanguageCategoryFragment.java deleted file mode 100644 index c47cda2..0000000 --- a/MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/fragment/LanguageCategoryFragment.java +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.mlkit.sample.activity.fragment; - -import android.content.Intent; -import android.view.View; -import android.widget.AdapterView; - -import com.mlkit.sample.R; -import com.mlkit.sample.activity.TranslatorActivity; -import com.mlkit.sample.activity.entity.GridViewItem; - -import java.util.ArrayList; - -public class LanguageCategoryFragment extends BaseFragment { - - private static final int[] language_icons = {R.drawable.icon_translate}; - - private static final int[] language_titles = {R.string.translate}; - - @Override - protected void initClickEvent(View view) { - if (this.mGridView == null) { - return; - } - this.mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView parent, View view, int position, long id) { - switch (position) { - case 0: - LanguageCategoryFragment.this.startActivity(new Intent(LanguageCategoryFragment.this.getActivity(), TranslatorActivity.class)); - break; - default: - break; - } - } - }); - } - - @Override - protected void initData() { - this.mDataList = new ArrayList(); - GridViewItem item; - for (int i = 0; i < LanguageCategoryFragment.language_icons.length; i++) { - item = new GridViewItem(LanguageCategoryFragment.language_icons[i], LanguageCategoryFragment.language_titles[i]); - this.mDataList.add(item); - } - } -} - diff --git a/MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/fragment/PictureCategoryFragment.java b/MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/fragment/PictureCategoryFragment.java deleted file mode 100644 index 76d96ae..0000000 --- a/MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/fragment/PictureCategoryFragment.java +++ /dev/null @@ -1,115 +0,0 @@ -/** - * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.mlkit.sample.activity.fragment; - -import android.content.Intent; -import android.view.View; -import android.widget.AdapterView; -import android.widget.Toast; - -import com.mlkit.sample.R; -import com.mlkit.sample.activity.RemoteDetectionActivity; -import com.mlkit.sample.activity.FaceDetectionActivity; -import com.mlkit.sample.activity.IDCardRecognitionActivity; -import com.mlkit.sample.activity.ImageClassificationActivity; -import com.mlkit.sample.activity.ObjectDetectionActivity; -import com.mlkit.sample.activity.TextRecognitionActivity; -import com.mlkit.sample.activity.entity.GridViewItem; -import com.mlkit.sample.activity.imgseg.ImageSegmentationActivity; -import com.mlkit.sample.util.Constant; - -import java.util.ArrayList; - -public class PictureCategoryFragment extends BaseFragment { - - private static final int[] image_icons = {R.drawable.icon_segmentation, R.drawable.icon_face, - R.drawable.icon_shopping, R.drawable.icon_object, R.drawable.icon_classification, - R.drawable.icon_landmark, R.drawable.icon_text, R.drawable.icon_idcard}; - - private static final int[] image_titles = {R.string.image_segmentation, R.string.face_detection, - R.string.photographed_shopping, R.string.object_detection, R.string.image_classification, - R.string.landmark, R.string.text_detection, R.string.idcard_recognition}; - - @Override - protected void initClickEvent(View view) { - if(this.mGridView == null){ - return; - } - this.mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() { - Intent intent = null; - - @Override - public void onItemClick(AdapterView parent, View view, int position, long id) { - switch (position) { - case 0: - // Image Segmentation - PictureCategoryFragment.this.startActivity( - new Intent(PictureCategoryFragment.this.getActivity(), ImageSegmentationActivity.class)); - break; - case 1: - // Face detection - PictureCategoryFragment.this.startActivity( - new Intent(PictureCategoryFragment.this.getActivity(), FaceDetectionActivity.class)); - break; - case 2: - // Product Visual Search - Toast.makeText(PictureCategoryFragment.this.getActivity(), PictureCategoryFragment.this.getText(R.string.coming_soon), Toast.LENGTH_SHORT).show(); - break; - case 3: - // Object detection and tracking - PictureCategoryFragment.this.startActivity( - new Intent(PictureCategoryFragment.this.getActivity(), ObjectDetectionActivity.class)); - break; - case 4: - // Image classification - PictureCategoryFragment.this.startActivity( - new Intent(PictureCategoryFragment.this.getActivity(), ImageClassificationActivity.class)); - break; - case 5: - // Landmark recognition - this.intent = - new Intent(PictureCategoryFragment.this.getActivity(), RemoteDetectionActivity.class); - this.intent.putExtra(Constant.MODEL_TYPE, Constant.CLOUD_LANDMARK_DETECTION); - PictureCategoryFragment.this.startActivity(this.intent); - break; - case 6: - // Text recognition - PictureCategoryFragment.this.startActivity( - new Intent(PictureCategoryFragment.this.getActivity(), TextRecognitionActivity.class)); - break; - case 7: - // Card recognition - PictureCategoryFragment.this.startActivity( - new Intent(PictureCategoryFragment.this.getActivity(), IDCardRecognitionActivity.class)); - break; - default: - break; - } - } - }); - } - - @Override - protected void initData() { - this.mDataList = new ArrayList(); - GridViewItem item; - for (int i = 0; i < PictureCategoryFragment.image_icons.length; i++) { - item = new GridViewItem(PictureCategoryFragment.image_icons[i], PictureCategoryFragment.image_titles[i]); - this.mDataList.add(item); - } - } -} diff --git a/MLKit-Sample/app/src/main/java/com/mlkit/sample/util/EdgeDetection.java b/MLKit-Sample/app/src/main/java/com/mlkit/sample/util/EdgeDetection.java deleted file mode 100644 index 801015d..0000000 --- a/MLKit-Sample/app/src/main/java/com/mlkit/sample/util/EdgeDetection.java +++ /dev/null @@ -1,127 +0,0 @@ -/** - * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.mlkit.sample.util; - -public class EdgeDetection { - int label; - int[][] array; - boolean[][] isEdgeArray; - - public EdgeDetection() { - } - - public EdgeDetection(int[][] array, boolean[][] isEdgeArray) { - if (array != null) { - this.array = array.clone(); - } - if (isEdgeArray != null) { - this.isEdgeArray = isEdgeArray.clone(); - } - } - - public void setArray(int[][] array) { - if (array != null) { - this.array = array.clone(); - } - } - - public int[][] getArray() { - return this.array.clone(); - } - - public boolean[][] getIsEdgeArray() { - return this.isEdgeArray.clone(); - } - - public void setIsEdgeArray(boolean[][] isEdgeArray) { - if (isEdgeArray != null) { - this.isEdgeArray = isEdgeArray.clone(); - } - } - - public int getLabel() { - return this.label; - } - - public void setLabel(int label) { - this.label = label; - } - - /** - * Detect all pixels and output the judgment result of each pixel. - */ - public boolean[] detect() { - for (int row = 0; row < this.array.length; row++) { - for (int col = 0; col < this.array[0].length; col++) { - this.isEdgeArray[row][col] = this.isEdge(row, col); - } - } - return this.twoToOneArray(); - } - - /** - * Whether it is the edge point of the specified segmentation type. - * Condition 1: The current pixel is the category to be segmented. - * Condition 2: There are pixels of other segmentation types around. - */ - public boolean isEdge(int row, int col) { - if (!this.isSelectedLabel(row, col)) { - return false; - } - return this.isOthersSurrouding(row, col); - } - - /** - * Detection condition 1, detecting whether the current pixel is a segmentation type to be identified. - */ - private boolean isSelectedLabel(int row, int col) { - int currentLabel = this.array[row][col]; - return currentLabel == this.label; - } - - /** - * Detection condition 2, traverse the surrounding pixels to check if there are other segmentation types. - */ - private boolean isOthersSurrouding(int row, int col) { - int[] xInterval = {-1, -1, -1, 0, 0, 1, 1, 1}; - int[] yInterval = {-1, 0, 1, -1, 1, -1, 0, 1}; - for (int index = 0; index < xInterval.length; index++) { - int currentX = row + xInterval[index]; - int currentY = col + yInterval[index]; - if (currentX >= 0 && currentX < this.array.length && currentY >= 0 && currentY < this.array[0].length) { - if (!this.isSelectedLabel(currentX, currentY)) { - return true; - } - } - } - return false; - } - - /** - * Convert two-dimensional array to one-dimensional array. - */ - private boolean[] twoToOneArray() { - boolean[] result = new boolean[this.isEdgeArray.length * this.isEdgeArray[0].length]; - int index = 0; - for (boolean[] tmp : this.isEdgeArray) { - for (boolean value : tmp) { - result[index++] = value; - } - } - return result; - } -} diff --git a/MLKit-Sample/app/src/main/res/drawable-xxhdpi/icon_document.png b/MLKit-Sample/app/src/main/res/drawable-xxhdpi/icon_document.png deleted file mode 100644 index 80ecbdf..0000000 Binary files a/MLKit-Sample/app/src/main/res/drawable-xxhdpi/icon_document.png and /dev/null differ diff --git a/MLKit-Sample/app/src/main/res/drawable-xxxhdpi/icon_document.png b/MLKit-Sample/app/src/main/res/drawable-xxxhdpi/icon_document.png deleted file mode 100644 index 8da0ef4..0000000 Binary files a/MLKit-Sample/app/src/main/res/drawable-xxxhdpi/icon_document.png and /dev/null differ diff --git a/MLKit-Sample/app/src/main/res/drawable-xxxhdpi/icon_more.png b/MLKit-Sample/app/src/main/res/drawable-xxxhdpi/icon_more.png deleted file mode 100644 index c75a547..0000000 Binary files a/MLKit-Sample/app/src/main/res/drawable-xxxhdpi/icon_more.png and /dev/null differ diff --git a/MLKit-Sample/app/src/main/res/layout-land/activity_start.xml b/MLKit-Sample/app/src/main/res/layout-land/activity_start.xml deleted file mode 100644 index 2d185ba..0000000 --- a/MLKit-Sample/app/src/main/res/layout-land/activity_start.xml +++ /dev/null @@ -1,399 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/MLKit-Sample/app/src/main/res/layout/activity_all_function.xml b/MLKit-Sample/app/src/main/res/layout/activity_all_function.xml deleted file mode 100644 index a25f507..0000000 --- a/MLKit-Sample/app/src/main/res/layout/activity_all_function.xml +++ /dev/null @@ -1,134 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/MLKit-Sample/app/src/main/res/layout/activity_product_vision_search_dialog.xml b/MLKit-Sample/app/src/main/res/layout/activity_product_vision_search_dialog.xml deleted file mode 100644 index 6c6d81d..0000000 --- a/MLKit-Sample/app/src/main/res/layout/activity_product_vision_search_dialog.xml +++ /dev/null @@ -1,94 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/MLKit-Sample/app/src/main/res/layout/activity_product_vision_search_dialog_item.xml b/MLKit-Sample/app/src/main/res/layout/activity_product_vision_search_dialog_item.xml deleted file mode 100644 index 2e11131..0000000 --- a/MLKit-Sample/app/src/main/res/layout/activity_product_vision_search_dialog_item.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/MLKit-Sample/app/src/main/res/layout/activity_start.xml b/MLKit-Sample/app/src/main/res/layout/activity_start.xml deleted file mode 100644 index 6710d23..0000000 --- a/MLKit-Sample/app/src/main/res/layout/activity_start.xml +++ /dev/null @@ -1,418 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/MLKit-Sample/app/src/main/res/layout/fragment_picture.xml b/MLKit-Sample/app/src/main/res/layout/fragment_picture.xml deleted file mode 100644 index 4758f8e..0000000 --- a/MLKit-Sample/app/src/main/res/layout/fragment_picture.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/MLKit-Sample/app/src/main/res/menu/camera_button_menu.xml b/MLKit-Sample/app/src/main/res/menu/camera_button_menu.xml deleted file mode 100644 index ab57007..0000000 --- a/MLKit-Sample/app/src/main/res/menu/camera_button_menu.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - diff --git a/MLKit-Sample/app/src/main/res/mipmap-xxxhdpi/right_arraw.png b/MLKit-Sample/app/src/main/res/mipmap-xxxhdpi/right_arraw.png deleted file mode 100644 index 7873c67..0000000 Binary files a/MLKit-Sample/app/src/main/res/mipmap-xxxhdpi/right_arraw.png and /dev/null differ diff --git a/MLKit-Sample/app/src/main/res/values-zh-rCN/strings.xml b/MLKit-Sample/app/src/main/res/values-zh-rCN/strings.xml deleted file mode 100644 index e62d3b5..0000000 --- a/MLKit-Sample/app/src/main/res/values-zh-rCN/strings.xml +++ /dev/null @@ -1,126 +0,0 @@ - - - ML Kit - 图片 - - HDR Viewfinder Demo:\n\n - - Tap viewfinder to switch modes.\n\n - - Normal: Standard camera preview\n - Split: Manual exposure control\n - HDR: Fused HDR viewfinder\n\n - - Swipe up/down in Split/HDR modes to change manual exposure - values.\n\n - - The left half of the viewfinder controls exposure time for - even-numbered frames, and the right half of the viewfinder - controls exposure time for odd-numbered frames - - - 信息 - - 示例应用需要相机和存储权限 - 示例应用需要存储权限 - 没有可用的后置摄像头! - 相机已通过设备策略禁用 - 相机在打开前已断开连接 - 相机服务报告了错误 - 未知相机错误: %s - 您已拒绝该应用需要其核心功能的权限。 如果您选择过不再询问,则需要使用“设置”重新启用权限。 - - OK - 设置 - 取消 - 需要访问相机进行检测 - 该应用程序没有摄像头权限,因此无法运行。 应用程序现在将退出。 - 由于设备存储空间不足,无法下载人脸检测器依赖性 - 前摄像头 - 后摄像头 - 视觉探测器演示与实时摄像机预览 - 视觉检测器演示静态图像 - - 实时检测 - 图像检测 - - 云端图像分类 - 云端文字识别 - 从相册选择图像 - 拍照 - 身份证识别 - 云端图像识别 - 相机实时连续识别 - 采集更多人脸数据 - 版本号: - 语言 - 文字识别语言设置 - 简体中文 - 英文 - 日文 - 韩文 - 拉丁文 - 获取数据失败 - 加载中… - 加载图片 - - 图像分割 - 文档识别 - 拍照购 - 人脸检测 - 对象检测 - 图片分类 - 地标识别 - 文字识别 - 身份证识别 - - 图像分割 - 翻译 - 拍照购 - 人脸检测 - 对象检测 - 图片分类 - 地标识别 - 文字识别 - 文档识别 - 所有 - 敬请期待 - 返回 - 翻译 - 语种识别 - 耗时: - 0 字符 - 视觉类 - 语言类 - 其他类 - 机器学习 - 背景替换 - 人像抠图 - 选择图片 - 剪切 - 背景 - 保存 - 剪切成功 - 保存成功 - - 请选择一张要处理的图片~ - 点击添加图片~ - 没有可保存的图片 - 目标 - 颜色 - - "请上传本人身份证照片" - "上传人像面" - "上传国徽面" - "请上传有效身份证照片" - "智能检测识别到图片可能存在部分遮挡,如果清晰可见请忽略" - "我们将依法保护您的个人信息安全" - "检测结果" - 端侧 - 云侧 - - 相似商品 - - - 注:只用于中国大陆地区 - diff --git a/MLKit-Sample/app/src/main/res/values/colors.xml b/MLKit-Sample/app/src/main/res/values/colors.xml deleted file mode 100644 index 7cb4589..0000000 --- a/MLKit-Sample/app/src/main/res/values/colors.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - #000000 - #D9D9D9 - #A9A9A9 - #626262 - #003853 - #f2f2f2 - #5CACEE - #ffffff - #1d1d1d - #cc696969 - #E3E7F0 - - #2E5C8D - - #646464 - - #BBE0E3 - - #008000 - - #c2c2c2 - - #FF0000 - #FFFA2A2D - #EE6A50 - - #FFE557 - - #60B2BE - #182E46 - - diff --git a/MLKit-Sample/app/src/main/res/values/dimens.xml b/MLKit-Sample/app/src/main/res/values/dimens.xml deleted file mode 100644 index 76157d1..0000000 --- a/MLKit-Sample/app/src/main/res/values/dimens.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - 16dp - 20dp - 10dp - 18sp - 19sp - 14sp - 35dp - 18dp - 18dp - 20dp - 15dp - 24sp - 12dp - 13dp - 17sp - 45dp - 12dp - 5dp - 12dp - 30dp - 1dp - 7dp - 45dp - 35dp - 18dp - 15dp - 45dp - 1.5999756px - 8.0px - 24dp - 24dp - 65dp - - 250dp - 230dp - 70dp - diff --git a/MLKit-Sample/app/src/main/res/values/strings.xml b/MLKit-Sample/app/src/main/res/values/strings.xml deleted file mode 100644 index fd4a570..0000000 --- a/MLKit-Sample/app/src/main/res/values/strings.xml +++ /dev/null @@ -1,134 +0,0 @@ - - - ML Kit - Picture - - HDR Viewfinder Demo:\n\n - - Tap viewfinder to switch modes.\n\n - - Normal: Standard camera preview\n - Split: Manual exposure control\n - HDR: Fused HDR viewfinder\n\n - - Swipe up/down in Split/HDR modes to change manual exposure - values.\n\n - - The left half of the viewfinder controls exposure time for - even-numbered frames, and the right half of the viewfinder - controls exposure time for odd-numbered frames - - - Info - - This sample app requires camera and storage access in order to - demo the API. - This sample app requires storage access in order to - demo the API. - No back-facing sufficiently capable camera available! - Camera is disabled by device policy - Camera was disconnected before it was opened - Camera service reported an error - Unknown camera error: %s - You\'ve denied a permission that the app - needs for core functionality. If you selected "don\'t ask again" in the past then - you need to use Settings to re-enable the permission. - - OK - Settings - cancel - Access to the camera is needed for detection - This application cannot run because it does not have the camera permission. The application will now exit. - Face detector dependencies cannot be downloaded due to low device storage - Front - Back - Vision detectors demo with live camera preview - Vision detectors demo with a still image - - Live - Still - - - Cloud Image Classification - Cloud Text Recognition - - Select image from album - Take photo - Cloud image recognition - Camera real-time continuous recognition - More face data - Version: - Language settings - Text recognition language settings - Simplified chinese - English - Japanese - Korean - Latin - Failed to get data. - Loading… - Load pictures - - Image Segmentation - Product Visual Search - Face Detection - Object Detection and Tracking - Image Classification - ID Card Recognition - Landmark Recognition - Text Recognition - Document Recognition - - Segmentation - Document - Translation - Shopping - Face - Object - Classification - ID Card - Landmark - Text - all - coming soon - back - Translate - Language Recognition - Elapsed Time: - 0 character - Vision - Language - Other - Machine Learning - - Substitution - Select Picture - Cutout - Cut - Cut success - Save success - - Background - Save - Please select a picture to process~ - Click to add picture~ - Null Image needed to save - - Object - Color - - - Upload photos of your ID card - Photo side - Other side - Upload photos of your valid ID card. - Something may be blocking important information in the photo. Retake the photo if needed. - Your personal information will be protected in accordance with the law. - Recognition results: - Device Side - Cloud Side - - Similar Products - Empty - Note: For Mainland China Only - diff --git a/MLKit-Sample/build.gradle b/MLKit-Sample/build.gradle index ffd4523..456b006 100644 --- a/MLKit-Sample/build.gradle +++ b/MLKit-Sample/build.gradle @@ -6,7 +6,7 @@ buildscript { } dependencies { classpath 'com.android.tools.build:gradle:3.3.2' - classpath 'com.huawei.agconnect:agcp:1.0.0.300' + classpath 'com.huawei.agconnect:agcp:1.2.1.301' } } diff --git a/MLKit-Sample/module-text/.gitignore b/MLKit-Sample/module-text/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/MLKit-Sample/module-text/.gitignore @@ -0,0 +1 @@ +/build diff --git a/MLKit-Sample/app/build.gradle b/MLKit-Sample/module-text/build.gradle similarity index 67% rename from MLKit-Sample/app/build.gradle rename to MLKit-Sample/module-text/build.gradle index 868758c..21894d5 100644 --- a/MLKit-Sample/app/build.gradle +++ b/MLKit-Sample/module-text/build.gradle @@ -4,13 +4,16 @@ android { compileSdkVersion 28 buildToolsVersion "28.0.3" defaultConfig { - applicationId "com.mlkit.sample" + applicationId "com.mlkit.sample.text" minSdkVersion 19 targetSdkVersion 28 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } + lintOptions{ + abortOnError false + } // Support simulator. splits { abi { @@ -32,21 +35,22 @@ android { } dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation 'com.huawei.hms:ml-computer-vision:1.0.2.300' - implementation 'com.huawei.hms:ml-computer-translate:1.0.2.300' - implementation 'com.huawei.hms:ml-computer-language-detection:1.0.2.300' + implementation fileTree(dir: 'libs', include: ['*.aar']) + implementation 'com.huawei.hms:ml-computer-vision-cloud:1.0.3.300' + implementation 'com.huawei.hms:ml-computer-translate:1.0.3.300' + implementation 'com.huawei.hms:ml-computer-language-detection:1.0.3.300' + + implementation 'com.huawei.hms:ml-computer-vision-ocr-cn-model:1.0.3.300' + implementation 'com.huawei.hms:ml-computer-vision-ocr-jk-model:1.0.3.300' + implementation 'com.huawei.hms:ml-computer-vision-ocr-latin-model:1.0.3.300' + + implementation 'com.huawei.hms:ml-computer-card-icr-cn-model:1.0.3.300' + implementation 'com.huawei.hms:ml-computer-card-icr-cn-plugin:1.0.3.300' + + implementation 'com.huawei.hms:ml-computer-card-bcr-plugin:1.0.3.300' + implementation 'com.huawei.hms:ml-computer-card-bcr-model:1.0.3.300' - implementation 'com.huawei.hms:ml-computer-vision-ocr-cn-model:1.0.2.300' - implementation 'com.huawei.hms:ml-computer-vision-ocr-jk-model:1.0.2.300' - implementation 'com.huawei.hms:ml-computer-vision-ocr-latin-model:1.0.2.300' - implementation 'com.huawei.hms:ml-computer-vision-image-segmentation-body-model:1.0.2.300' - implementation 'com.huawei.hms:ml-computer-vision-image-segmentation-multiclass-model:1.0.2.300' - implementation 'com.huawei.hms:ml-computer-vision-image-classification-model:1.0.2.300' - implementation 'com.huawei.hms:ml-computer-vision-object-detection-model:1.0.2.300' - implementation 'com.huawei.hms:ml-computer-vision-face-recognition-model:1.0.2.300' - implementation 'com.huawei.hms:ml-computer-card-icr-cn-model:1.0.2.300' - implementation 'com.huawei.hms:ml-computer-card-icr-cn-plugin:1.0.2.300' + implementation 'com.huawei.hms:ml-computer-card-gcr-plugin:1.0.3.300' implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' diff --git a/MLKit-Sample/module-text/gradlew b/MLKit-Sample/module-text/gradlew new file mode 100644 index 0000000..cccdd3d --- /dev/null +++ b/MLKit-Sample/module-text/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/MLKit-Sample/app/gradlew.bat b/MLKit-Sample/module-text/gradlew.bat similarity index 100% rename from MLKit-Sample/app/gradlew.bat rename to MLKit-Sample/module-text/gradlew.bat diff --git a/MLKit-Sample/app/proguard-rules.pro b/MLKit-Sample/module-text/proguard-rules.pro similarity index 100% rename from MLKit-Sample/app/proguard-rules.pro rename to MLKit-Sample/module-text/proguard-rules.pro diff --git a/MLKit-Sample/app/sample-agconnect-services.json b/MLKit-Sample/module-text/sample-agconnect-services.json similarity index 93% rename from MLKit-Sample/app/sample-agconnect-services.json rename to MLKit-Sample/module-text/sample-agconnect-services.json index 1326374..57a99b8 100644 --- a/MLKit-Sample/app/sample-agconnect-services.json +++ b/MLKit-Sample/module-text/sample-agconnect-services.json @@ -9,7 +9,7 @@ "client_id":"268600551012363200", "client_secret":"4819981CE7939A526B71AC3092D35C5CB77DF8341C6986559AA9211", "app_id":"1015883", - "package_name":"com.mlkit.sample", + "package_name":"com.mlkit.sample.text", "api_key":"CV46Xu0Y3+YFDS832xvOY69LHiAtZ2SviYUSZyELicm2NrxUesZE1TO" }, "service":{ diff --git a/MLKit-Sample/module-text/src/main/AndroidManifest.xml b/MLKit-Sample/module-text/src/main/AndroidManifest.xml new file mode 100644 index 0000000..78a0bc4 --- /dev/null +++ b/MLKit-Sample/module-text/src/main/AndroidManifest.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/BankCardRecognitionActivity.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/BankCardRecognitionActivity.java new file mode 100644 index 0000000..cce76d3 --- /dev/null +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/BankCardRecognitionActivity.java @@ -0,0 +1,159 @@ +/** + * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mlkit.sample.activity; + +import android.graphics.Bitmap; +import android.os.Bundle; + +import android.view.View; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.huawei.hms.mlplugin.card.bcr.MLBcrCapture; +import com.huawei.hms.mlplugin.card.bcr.MLBcrCaptureConfig; +import com.huawei.hms.mlplugin.card.bcr.MLBcrCaptureFactory; +import com.huawei.hms.mlplugin.card.bcr.MLBcrCaptureResult; +import com.mlkit.sample.R; + +import androidx.appcompat.app.AppCompatActivity; + +public class BankCardRecognitionActivity extends AppCompatActivity implements View.OnClickListener { + private ImageView frontImg; + private ImageView frontSimpleImg; + private ImageView frontDeleteImg; + private LinearLayout frontAddView; + private TextView showResult; + private String lastFrontResult = ""; + private String lastBackResult = ""; + private Bitmap currentImage; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_bank_card_recognition); + + initComponent(); + } + + private void initComponent() { + frontImg = findViewById(R.id.avatar_img); + frontSimpleImg = findViewById(R.id.avatar_sample_img); + frontDeleteImg = findViewById(R.id.avatar_delete); + frontAddView = findViewById(R.id.avatar_add); + showResult = findViewById(R.id.show_result); + + frontAddView.setOnClickListener(this); + frontDeleteImg.setOnClickListener(this); + findViewById(R.id.back).setOnClickListener(this); + } + + @Override + public void onClick(View view) { + int id = view.getId(); + switch (id) { + case R.id.avatar_add: + startCaptureActivity(); + break; + case R.id.avatar_delete: + showFrontDeleteImage(); + lastFrontResult = ""; + break; + case R.id.back: + finish(); + break; + default: + break; + } + } + + + @Override + protected void onDestroy() { + super.onDestroy(); + if (currentImage != null && !currentImage.isRecycled()) { + currentImage.recycle(); + currentImage = null; + } + } + + private void startCaptureActivity() { + MLBcrCaptureConfig config = new MLBcrCaptureConfig.Factory() + .setOrientation(MLBcrCaptureConfig.ORIENTATION_AUTO) + .create(); + MLBcrCapture bcrCapture = MLBcrCaptureFactory.getInstance().getBcrCapture(config); + + bcrCapture.captureFrame(this, this.callback); + } + + private String formatIdCardResult(MLBcrCaptureResult result) { + StringBuilder resultBuilder = new StringBuilder(); + + resultBuilder.append("Number:"); + resultBuilder.append(result.getNumber()); + resultBuilder.append("\r\n"); + + return resultBuilder.toString(); + } + + private MLBcrCapture.Callback callback = new MLBcrCapture.Callback() { + @Override + public void onSuccess(MLBcrCaptureResult result) { + if (result == null) { + return; + } + Bitmap bitmap = result.getOriginalBitmap(); + showSuccessResult(bitmap, result); + } + + @Override + public void onCanceled() { + } + + @Override + public void onFailure(int recCode, Bitmap bitmap) { + showResult.setText(" RecFailed "); + } + + @Override + public void onDenied() { + } + }; + + private void showSuccessResult(Bitmap bitmap, MLBcrCaptureResult idCardResult) { + showFrontImage(bitmap); + lastFrontResult = formatIdCardResult(idCardResult); + showResult.setText(lastFrontResult); + showResult.append(lastBackResult); + ((ImageView) findViewById(R.id.number)).setImageBitmap(idCardResult.getNumberBitmap()); + } + + private void showFrontImage(Bitmap bitmap) { + frontImg.setVisibility(View.VISIBLE); + frontImg.setImageBitmap(bitmap); + frontSimpleImg.setVisibility(View.GONE); + frontAddView.setVisibility(View.GONE); + frontDeleteImg.setVisibility(View.VISIBLE); + } + + private void showFrontDeleteImage() { + frontImg.setVisibility(View.GONE); + frontSimpleImg.setVisibility(View.VISIBLE); + frontAddView.setVisibility(View.VISIBLE); + frontDeleteImg.setVisibility(View.GONE); + } +} diff --git a/MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/BaseActivity.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/BaseActivity.java similarity index 100% rename from MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/BaseActivity.java rename to MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/BaseActivity.java diff --git a/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/GeneralCardRecognitionActivity.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/GeneralCardRecognitionActivity.java new file mode 100644 index 0000000..1012e3d --- /dev/null +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/GeneralCardRecognitionActivity.java @@ -0,0 +1,310 @@ +/** + * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mlkit.sample.activity; + +import android.app.Activity; +import android.content.Intent; +import android.content.res.Configuration; +import android.graphics.Bitmap; +import android.net.Uri; +import android.os.Bundle; +import android.provider.MediaStore; +import android.util.Log; +import android.view.View; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.RadioGroup; +import android.widget.TextView; + +import com.mlkit.sample.R; +import com.mlkit.sample.activity.dialog.AddPictureDialog; +import com.mlkit.sample.activity.entity.GeneralCardResult; +import com.mlkit.sample.processor.gcr.GeneralCardProcessor; +import com.mlkit.sample.processor.gcr.homecard.HomeCardProcessor; +import com.mlkit.sample.processor.gcr.hongkong.HKIdCardProcessor; +import com.mlkit.sample.processor.gcr.passcard.PassCardProcessor; +import com.huawei.hms.mlplugin.card.gcr.MLGcrCapture; +import com.huawei.hms.mlplugin.card.gcr.MLGcrCaptureConfig; +import com.huawei.hms.mlplugin.card.gcr.MLGcrCaptureFactory; +import com.huawei.hms.mlplugin.card.gcr.MLGcrCaptureResult; +import com.huawei.hms.mlplugin.card.gcr.MLGcrCaptureUIConfig; + +import java.io.IOException; + +public class GeneralCardRecognitionActivity extends Activity implements View.OnClickListener { + private static final String TAG = "GCRActivity"; + private Uri mImageUri; + private static final int REQUEST_IMAGE_SELECT_FROM_ALBUM = 1000; + private static final int REQUEST_IMAGE_CAPTURE = 1001; + private Object object = false; + private ImageView frontImg; + private ImageView frontSimpleImg; + private ImageView frontDeleteImg; + private LinearLayout frontAddView; + private TextView showResult; + private RadioGroup cardType; + private CardType cardTypeEnum = CardType.PASSCARD; + private Bitmap imageBitmap; + RadioGroup.OnCheckedChangeListener radioListener = new RadioGroup.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(RadioGroup group, int checkedId) { + switch (checkedId) { + case R.id.passCard: + updateCardType(CardType.PASSCARD); + break; + case R.id.HKIdCard: + updateCardType(CardType.HKIDCARD); + break; + case R.id.comeHomeCard: + updateCardType(CardType.COMEHOMECARD); + break; + } + } + }; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_general_card_recognition); + initComponent(); + } + + private void initComponent() { + frontImg = findViewById(R.id.avatar_img); + frontSimpleImg = findViewById(R.id.avatar_sample_img); + frontDeleteImg = findViewById(R.id.avatar_delete); + frontAddView = findViewById(R.id.avatar_add); + showResult = findViewById(R.id.show_result); + + frontAddView.setOnClickListener(this); + frontDeleteImg.setOnClickListener(this); + cardType = findViewById(R.id.card_type); + cardType.setOnCheckedChangeListener(radioListener); + findViewById(R.id.back).setOnClickListener(this); + } + + private void updateCardType(CardType type) { + if (cardTypeEnum != type) { + showResult.setText(""); + showFrontDeleteImage(); + } + cardTypeEnum = type; + } + + @Override + public void onClick(View view) { + int id = view.getId(); + switch (id) { + case R.id.avatar_add: + showChoosePicDialog(); + break; + case R.id.avatar_delete: + showFrontDeleteImage(); + break; + case R.id.back: + finish(); + default: + break; + } + } + + private void showChoosePicDialog() { + AddPictureDialog addPictureDialog = new AddPictureDialog(this, AddPictureDialog.TYPE_CUSTOM); + addPictureDialog.setClickListener(new AddPictureDialog.ClickListener() { + @Override + public void takePicture() { + detectPhoto(object, callback); + } + + @Override + public void selectImage() { + startChooseImageIntentForResult(); + } + + @Override + public void doExtend() { + detectPreview(object, callback); + } + }); + addPictureDialog.show(); + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + Log.d(TAG, "onConfigurationChanged"); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent intent) { + super.onActivityResult(requestCode, resultCode, intent); + Log.i(TAG, "onActivityResult requestCode " + requestCode + ", resultCode " + resultCode); + if (requestCode == REQUEST_IMAGE_SELECT_FROM_ALBUM && resultCode == RESULT_OK) { + mImageUri = intent.getData(); + tryReloadAndDetectInImage(); + } else if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) { + tryReloadAndDetectInImage(); + } + } + + public enum CardType { + HKIDCARD, PASSCARD, COMEHOMECARD + } + + // video stream + private void detectPreview(Object object, MLGcrCapture.Callback callback) { + MLGcrCaptureConfig cardConfig = new MLGcrCaptureConfig.Factory().setLanguage("en").create(); + MLGcrCaptureUIConfig uiConfig = new MLGcrCaptureUIConfig.Factory() + .setTipText(getResources().getString(R.string.vedio_tip)) + .setOrientation(MLGcrCaptureUIConfig.ORIENTATION_AUTO).create(); + MLGcrCapture ocrManager = MLGcrCaptureFactory.getInstance().getGcrCapture(cardConfig, uiConfig); + ocrManager.capturePreview(this, object, callback); + } + + // take a picture + private void detectPhoto(Object object, MLGcrCapture.Callback callback) { + MLGcrCaptureConfig cardConfig = new MLGcrCaptureConfig.Factory().setLanguage("en").create(); + MLGcrCaptureUIConfig uiConfig = new MLGcrCaptureUIConfig.Factory() + .setTipText(getResources().getString(R.string.capture_tip)) + .setOrientation(MLGcrCaptureUIConfig.ORIENTATION_AUTO).create(); + MLGcrCapture ocrManager = MLGcrCaptureFactory.getInstance().getGcrCapture(cardConfig, uiConfig); + + ocrManager.capturePhoto(this, object, callback); + } + + // local image + private void detectLocalImage(Bitmap bitmap, Object object, MLGcrCapture.Callback callback) { + MLGcrCaptureConfig config = new MLGcrCaptureConfig.Factory().create(); + MLGcrCapture ocrManager = MLGcrCaptureFactory.getInstance().getGcrCapture(config); + ocrManager.captureImage(bitmap, object, callback); + } + + private MLGcrCapture.Callback callback = new MLGcrCapture.Callback() { + @Override + public int onResult(MLGcrCaptureResult result, Object object) { + Log.i(TAG, "callback onRecSuccess"); + if (result == null) { + Log.e(TAG, "callback onRecSuccess result is null"); + return MLGcrCaptureResult.CAPTURE_CONTINUE; + } + + GeneralCardProcessor idCard = null; + GeneralCardResult cardResult = null; + + if (cardTypeEnum == CardType.PASSCARD) { + idCard = new PassCardProcessor(result.text); + } else if (cardTypeEnum == CardType.HKIDCARD) { + idCard = new HKIdCardProcessor(result.text); + } else if (cardTypeEnum == CardType.COMEHOMECARD) { + idCard = new HomeCardProcessor(result.text); + } + + if (idCard != null) { + cardResult = idCard.getResult(); + } + + showFrontImage(result.cardBitmap); + displayResult(cardResult); + + // If the results don't match + if (cardResult == null || cardResult.valid.isEmpty() || cardResult.number.isEmpty()) { + return MLGcrCaptureResult.CAPTURE_CONTINUE; + } + + displayResult(cardResult); + return MLGcrCaptureResult.CAPTURE_STOP; + } + + @Override + public void onCanceled() { + Log.i(TAG, "callback onRecCanceled"); + } + + @Override + public void onFailure(int i, Bitmap bitmap) { + + } + + @Override + public void onDenied() { + Log.i(TAG, "callback onCameraDenied"); + } + }; + + private void displayResult(GeneralCardResult result) { + if (result == null) { + return; + } + if (showResult.getText().length() != 0) { + showResult.setText(""); + } + StringBuilder builder = new StringBuilder(); + builder.append("valid: "); + builder.append(result.valid); + builder.append("\r\n"); + + builder.append("number: "); + builder.append(result.number); + + showResult.setText(builder.toString()); + } + + private void showFrontImage(Bitmap bitmap) { + frontImg.setVisibility(View.VISIBLE); + frontImg.setImageBitmap(bitmap); + frontSimpleImg.setVisibility(View.GONE); + frontAddView.setVisibility(View.GONE); + frontDeleteImg.setVisibility(View.VISIBLE); + } + + private void showFrontDeleteImage() { + frontImg.setVisibility(View.GONE); + frontSimpleImg.setVisibility(View.VISIBLE); + frontAddView.setVisibility(View.VISIBLE); + frontDeleteImg.setVisibility(View.GONE); + } + + private void startChooseImageIntentForResult() { + Intent intent = new Intent(Intent.ACTION_PICK, null); + intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*"); + startActivityForResult(intent, REQUEST_IMAGE_SELECT_FROM_ALBUM); + } + + private void tryReloadAndDetectInImage() { + if (mImageUri == null) { + return; + } + Bitmap imageBitmap = null; + try { + imageBitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), mImageUri); + } catch (IOException error) { + error.printStackTrace(); + } + + detectLocalImage(imageBitmap, null, callback); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (imageBitmap != null && !imageBitmap.isRecycled()) { + imageBitmap.recycle(); + imageBitmap = null; + } + } +} + diff --git a/MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/IDCardRecognitionActivity.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/IDCardRecognitionActivity.java similarity index 92% rename from MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/IDCardRecognitionActivity.java rename to MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/IDCardRecognitionActivity.java index 00aa900..e7a3bf4 100644 --- a/MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/IDCardRecognitionActivity.java +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/IDCardRecognitionActivity.java @@ -14,6 +14,8 @@ * limitations under the License. */ + + package com.mlkit.sample.activity; import android.Manifest; @@ -59,7 +61,6 @@ public class IDCardRecognitionActivity extends AppCompatActivity implements View private SwitchButton switchButton; private LinearLayout frontAddView; private LinearLayout backAddView; - private RadioGroup radioGroup; private TextView showResult; private String lastFrontResult = ""; private String lastBackResult = ""; @@ -81,7 +82,6 @@ private void initComponent() { this.backDeleteImg = this.findViewById(R.id.emblem_delete); this.frontAddView = this.findViewById(R.id.avatar_add); this.backAddView = this.findViewById(R.id.emblem_add); - this.radioGroup = this.findViewById(R.id.local_or_remote); this.showResult = this.findViewById(R.id.show_result); this.switchButton = this.findViewById(R.id.switch_button_view); this.switchButton.setOnSwitchButtonStateChangeListener(this); @@ -91,27 +91,8 @@ private void initComponent() { this.frontDeleteImg.setOnClickListener(this); this.backDeleteImg.setOnClickListener(this); this.findViewById(R.id.back).setOnClickListener(this); - this.radioGroup.setOnCheckedChangeListener(this.radioListener); } - RadioGroup.OnCheckedChangeListener radioListener = new RadioGroup.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(RadioGroup group, int checkedId) { - switch (checkedId) { - case R.id.local: - Log.i(IDCardRecognitionActivity.TAG, "local"); - IDCardRecognitionActivity.this.isRemote = false; - break; - case R.id.remote: - Log.i(IDCardRecognitionActivity.TAG, "remote"); - IDCardRecognitionActivity.this.isRemote = true; - break; - default: - break; - } - } - }; - @Override public void onClick(View view) { int id = view.getId(); @@ -180,10 +161,10 @@ public void onConfigurationChanged(Configuration newConfig) { Log.d(IDCardRecognitionActivity.TAG, "onConfigurationChanged"); } - private void startCaptureActivity(MLCnIcrCapture.CallBack callBack, boolean isFront, boolean isLocal) { + private void startCaptureActivity(MLCnIcrCapture.CallBack callBack, boolean isFront, boolean isRemote) { Log.i(IDCardRecognitionActivity.TAG, "startCaptureActivity"); MLCnIcrCaptureConfig config = - new MLCnIcrCaptureConfig.Factory().setFront(isFront).setRemote(isLocal).create(); + new MLCnIcrCaptureConfig.Factory().setFront(isFront).setRemote(isRemote).create(); MLCnIcrCapture icrCapture = MLCnIcrCaptureFactory.getInstance().getIcrCapture(config); icrCapture.capture(callBack, this); @@ -267,7 +248,7 @@ public void onCanceled() { @Override public void onFailure(int recCode, Bitmap bitmap) { Toast.makeText(IDCardRecognitionActivity.this.getApplicationContext(), R.string.get_data_failed, Toast.LENGTH_SHORT).show(); - Log.i(IDCardRecognitionActivity.TAG, "IdCallBack onRecFailed"); + Log.i(IDCardRecognitionActivity.TAG, "IdCallBack onRecFailed: " + recCode); } @Override @@ -306,4 +287,5 @@ private void showBackDeleteImage() { this.backSimpleImg.setVisibility(View.VISIBLE); this.backDeleteImg.setVisibility(View.GONE); } -} \ No newline at end of file +} + diff --git a/MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/RemoteDetectionActivity.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/RemoteDetectionActivity.java similarity index 88% rename from MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/RemoteDetectionActivity.java rename to MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/RemoteDetectionActivity.java index d9bc908..db86eaf 100644 --- a/MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/RemoteDetectionActivity.java +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/RemoteDetectionActivity.java @@ -41,21 +41,19 @@ import android.widget.TextView; import android.widget.Toast; -import com.mlkit.sample.R; +import com.huawei.hms.mlsdk.document.MLDocument; +import com.huawei.hms.mlsdk.text.MLText; import com.mlkit.sample.activity.dialog.AddPictureDialog; -import com.mlkit.sample.callback.CloudInfoResultCallBack; -import com.mlkit.sample.manager.CloudDataManager; +import com.mlkit.sample.callback.CouldInfoResultCallBack; +import com.mlkit.sample.processor.CloudDataProcessor; +import com.mlkit.sample.transactor.DocumentTextTransactor; +import com.mlkit.sample.transactor.ImageTransactor; +import com.mlkit.sample.transactor.RemoteTextTransactor; import com.mlkit.sample.util.BitmapUtils; import com.mlkit.sample.util.Constant; -import com.mlkit.sample.views.overlay.ZoomImageView; import com.mlkit.sample.views.overlay.GraphicOverlay; -import com.mlkit.sample.transactor.ImageTransactor; -import com.mlkit.sample.transactor.RemoteImageClassificationTransactor; -import com.mlkit.sample.transactor.RemoteLandmarkTransactor; -import com.mlkit.sample.transactor.DocumentTextTransactor; -import com.mlkit.sample.transactor.RemoteTextTransactor; -import com.huawei.hms.mlsdk.document.MLDocument; -import com.huawei.hms.mlsdk.text.MLText; +import com.mlkit.sample.views.overlay.ZoomImageView; +import com.mlkit.sample.R; import java.lang.ref.WeakReference; @@ -77,7 +75,7 @@ public final class RemoteDetectionActivity extends BaseActivity implements OnCli private TextView title; private GraphicOverlay graphicOverlay; private ZoomImageView changeImageView; - private String selectedMode = Constant.CLOUD_IMAGE_CLASSIFICATION; + private String selectedMode = Constant.CLOUD_TEXT_DETECTION; boolean isLandScape; @@ -94,11 +92,11 @@ public final class RemoteDetectionActivity extends BaseActivity implements OnCli private boolean flag = true; - private CloudDataManager cloudDataManager; + private CloudDataProcessor cloudDataProcessor; private AddPictureDialog addPictureDialog; - private CloudInfoResultCallBack textResultCallBack = new MyCloudInfoResultCallBack(); + private CouldInfoResultCallBack textResultCallBack = new MyCouldInfoResultCallBack(); private GestureDetector.OnDoubleTapListener onDoubleTapListener = new MyOnDoubleTapListener(); @@ -186,6 +184,7 @@ protected void onCreate(Bundle savedInstanceState) { this.getImageButton = this.findViewById(R.id.getImageButton); this.getImageButton.setOnClickListener(this); this.changeImageView.setOnDoubleTapListener(this.onDoubleTapListener); + this.cloudDataProcessor = new CloudDataProcessor(); this.createImageTransactor(); this.createDialog(); this.isLandScape = (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE); @@ -205,10 +204,6 @@ private void initTitle() { this.title.setText(this.getResources().getText(R.string.cloud_text)); } else if (this.selectedMode.equals(Constant.CLOUD_DOCUMENT_TEXT_DETECTION)) { this.title.setText(this.getResources().getText(R.string.document_recognition_s)); - } else if (this.selectedMode.equals(Constant.CLOUD_IMAGE_CLASSIFICATION)) { - this.title.setText(this.getResources().getText(R.string.cloud_classification)); - } else if (this.selectedMode.equals(Constant.CLOUD_LANDMARK_DETECTION)) { - this.title.setText(this.getResources().getText(R.string.landmark_s)); } } @@ -235,10 +230,8 @@ public void onClick(View view) { } } - private void createDialog(){ - this.addPictureDialog = new AddPictureDialog(this); - final Intent intent = new Intent(RemoteDetectionActivity.this, RemoteDetectionActivity.class); - intent.putExtra(Constant.MODEL_TYPE, Constant.CLOUD_IMAGE_CLASSIFICATION); + private void createDialog() { + this.addPictureDialog = new AddPictureDialog(this, AddPictureDialog.TYPE_NORMAL); this.addPictureDialog.setClickListener(new AddPictureDialog.ClickListener() { @Override public void takePicture() { @@ -249,6 +242,11 @@ public void takePicture() { public void selectImage() { RemoteDetectionActivity.this.selectLocalImage(); } + + @Override + public void doExtend() { + + } }); } @@ -271,16 +269,9 @@ public void onSaveInstanceState(Bundle outState) { @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); - if (this.selectedMode.equals(Constant.CLOUD_TEXT_DETECTION) - || this.selectedMode.equals(Constant.CLOUD_DOCUMENT_TEXT_DETECTION)) { - this.preview.setVisibility(View.GONE); - this.graphicOverlay.setVisibility(View.GONE); - this.changeImageView.setVisibility(View.VISIBLE); - } else { - this.preview.setVisibility(View.VISIBLE); - this.graphicOverlay.setVisibility(View.VISIBLE); - this.changeImageView.setVisibility(View.GONE); - } + this.preview.setVisibility(View.GONE); + this.graphicOverlay.setVisibility(View.GONE); + this.changeImageView.setVisibility(View.VISIBLE); } private void startCamera() { @@ -357,12 +348,6 @@ private Integer getMaxHeightOfImage() { private void createImageTransactor() { switch (this.selectedMode) { - case Constant.CLOUD_IMAGE_CLASSIFICATION: - this.imageTransactor = new RemoteImageClassificationTransactor(this.getApplicationContext(), this.mHandler); - break; - case Constant.CLOUD_LANDMARK_DETECTION: - this.imageTransactor = new RemoteLandmarkTransactor(this.mHandler); - break; case Constant.CLOUD_TEXT_DETECTION: this.imageTransactor = new RemoteTextTransactor(this.mHandler); ((RemoteTextTransactor) this.imageTransactor).addCouldTextResultCallBack(this.textResultCallBack); @@ -397,7 +382,7 @@ protected void onDestroy() { } } - class MyCloudInfoResultCallBack implements CloudInfoResultCallBack { + class MyCouldInfoResultCallBack implements CouldInfoResultCallBack { @Override public void onSuccessForText(Bitmap originalCameraImage, MLText text, GraphicOverlay graphicOverlay) { if (text == null) { @@ -407,10 +392,12 @@ public void onSuccessForText(Bitmap originalCameraImage, MLText text, GraphicOve RemoteDetectionActivity.this.changeImageView.setVisibility(View.VISIBLE); RemoteDetectionActivity.this.bitmapCopy = Bitmap.createBitmap(originalCameraImage).copy(Bitmap.Config.ARGB_8888, true); RemoteDetectionActivity.this.bitmapCopyForTap = Bitmap.createBitmap(originalCameraImage).copy(Bitmap.Config.ARGB_8888, true); - RemoteDetectionActivity.this.cloudDataManager = new CloudDataManager(graphicOverlay, RemoteDetectionActivity.this.bitmapCopyForTap, text); + RemoteDetectionActivity.this.cloudDataProcessor.setGraphicOverlay(graphicOverlay); + RemoteDetectionActivity.this.cloudDataProcessor.setBitmap(RemoteDetectionActivity.this.bitmapCopyForTap); + RemoteDetectionActivity.this.cloudDataProcessor.setText(text); RemoteDetectionActivity.this.changeImageView.setImageBitmap(RemoteDetectionActivity.this.bitmapCopy); Canvas canvas = new Canvas(RemoteDetectionActivity.this.bitmapCopy); - RemoteDetectionActivity.this.cloudDataManager.drawView(canvas, true); + RemoteDetectionActivity.this.cloudDataProcessor.drawView(canvas, true); } @Override @@ -420,7 +407,7 @@ public void onSuccessForDoc(Bitmap originalCameraImage, MLDocument text, Graphic Bitmap bitmap = Bitmap.createBitmap(originalCameraImage).copy(Bitmap.Config.ARGB_8888, true); RemoteDetectionActivity.this.changeImageView.setImageBitmap(bitmap); Canvas canvas = new Canvas(bitmap); - RemoteDetectionActivity.this.cloudDataManager.drawCloudDocText(text, canvas); + RemoteDetectionActivity.this.cloudDataProcessor.drawCloudDocText(text, canvas); } } @@ -439,7 +426,7 @@ public boolean onSingleTapConfirmed(MotionEvent motionEvent) { TransitionDrawable transitionDrawable; if (RemoteDetectionActivity.this.flag) { Canvas canvas = new Canvas(RemoteDetectionActivity.this.bitmapCopyForTap); - RemoteDetectionActivity.this.cloudDataManager.drawView(canvas, false); + RemoteDetectionActivity.this.cloudDataProcessor.drawView(canvas, false); transitionDrawable = new TransitionDrawable(new Drawable[]{bitmap_drawable, bitmapcopy_drawable}); } else { transitionDrawable = new TransitionDrawable(new Drawable[]{bitmapcopy_drawable, bitmap_drawable}); diff --git a/MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/SettingActivity.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/SettingActivity.java similarity index 75% rename from MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/SettingActivity.java rename to MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/SettingActivity.java index fdafbf9..376ab5a 100644 --- a/MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/SettingActivity.java +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/SettingActivity.java @@ -1,17 +1,17 @@ /** * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.mlkit.sample.activity; @@ -22,11 +22,10 @@ import android.view.View; import android.widget.TextView; -import androidx.annotation.Nullable; - -import com.mlkit.sample.R; -import com.mlkit.sample.util.Constant; import com.huawei.hms.mlsdk.common.internal.client.SmartLog; +import com.mlkit.sample.util.Constant; +import com.mlkit.sample.R; +import androidx.annotation.Nullable; public class SettingActivity extends BaseActivity implements View.OnClickListener { private static final String TAG = "SettingActivity"; diff --git a/MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/StartActivity.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/StartActivity.java similarity index 60% rename from MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/StartActivity.java rename to MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/StartActivity.java index 62a358e..0e19ac2 100644 --- a/MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/StartActivity.java +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/StartActivity.java @@ -1,17 +1,17 @@ /** * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package com.mlkit.sample.activity; @@ -27,14 +27,19 @@ import android.provider.Settings; import android.util.Log; import android.view.View; +import android.widget.AdapterView; +import android.widget.GridView; import android.widget.Toast; -import com.mlkit.sample.R; -import com.mlkit.sample.activity.imgseg.ImageSegmentationActivity; +import com.mlkit.sample.activity.adapter.GridViewAdapter; +import com.mlkit.sample.activity.entity.GridViewItem; import java.util.ArrayList; import java.util.List; +import com.mlkit.sample.R; +import com.mlkit.sample.util.Constant; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; @@ -46,6 +51,13 @@ public final class StartActivity extends BaseActivity implements OnRequestPermissionsResultCallback, View.OnClickListener { private static final String TAG = "StartActivity"; private static final int PERMISSION_REQUESTS = 1; + private static final int[] icons = {R.drawable.icon_bcr, R.drawable.icon_gcr, R.drawable.icon_text, + R.drawable.icon_icr, R.drawable.icon_document, R.drawable.icon_translate}; + + private static final int[] titles = {R.string.bcr, R.string.gcr, R.string.text_detection, R.string.icr, + R.string.document_recognition, R.string.translate}; + private GridView mGridView; + private ArrayList mDataList; @Override protected void onCreate(Bundle savedInstanceState) { @@ -53,56 +65,70 @@ protected void onCreate(Bundle savedInstanceState) { BaseActivity.setStatusBarColor(this, R.color.logo_background); this.setContentView(R.layout.activity_start); this.findViewById(R.id.setting_img).setOnClickListener(this); - this.findViewById(R.id.layout_segmentation).setOnClickListener(this); - this.findViewById(R.id.layout_face).setOnClickListener(this); - this.findViewById(R.id.layout_object).setOnClickListener(this); - this.findViewById(R.id.layout_text).setOnClickListener(this); - this.findViewById(R.id.layout_classification).setOnClickListener(this); - this.findViewById(R.id.layout_icr).setOnClickListener(this); - this.findViewById(R.id.layout_shopping).setOnClickListener(this); - this.findViewById(R.id.layout_translate).setOnClickListener(this); - this.findViewById(R.id.layout_more).setOnClickListener(this); + initData(); + this.mGridView = findViewById(R.id.gridview); + GridViewAdapter mAdapter = new GridViewAdapter(this.mDataList, getApplicationContext()); + this.mGridView.setAdapter(mAdapter); + initClickEvent(); if (!this.allPermissionsGranted()) { this.getRuntimePermissions(); } } + private void initClickEvent() { + if (this.mGridView == null) { + return; + } + this.mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + switch (position) { + case 0: + // BCR + startActivity(new Intent(StartActivity.this, BankCardRecognitionActivity.class)); + break; + case 1: + // GCR + startActivity(new Intent(StartActivity.this, GeneralCardRecognitionActivity.class)); + break; + case 2: + // Text recognition + startActivity(new Intent(StartActivity.this, TextRecognitionActivity.class)); + break; + case 3: + // ICR + startActivity(new Intent(StartActivity.this, IDCardRecognitionActivity.class)); + break; + case 4: + // Document recognition + final Intent intent = new Intent(StartActivity.this, RemoteDetectionActivity.class); + intent.putExtra(Constant.MODEL_TYPE, Constant.CLOUD_DOCUMENT_TEXT_DETECTION); + startActivity(intent); + break; + case 5: + startActivity(new Intent(StartActivity.this, TranslatorActivity.class)); + break; + default: + Toast.makeText(getApplicationContext(), R.string.coming_soon, Toast.LENGTH_SHORT).show(); + break; + } + } + }); + } + @Override public void onClick(View view) { - switch (view.getId()) { - case R.id.layout_face: - this.startActivity(new Intent(StartActivity.this, FaceDetectionActivity.class)); - break; - case R.id.layout_object: - this.startActivity(new Intent(StartActivity.this, ObjectDetectionActivity.class)); - break; - case R.id.layout_classification: - this.startActivity(new Intent(StartActivity.this, ImageClassificationActivity.class)); - break; - case R.id.layout_text: - this.startActivity(new Intent(StartActivity.this, TextRecognitionActivity.class)); - break; - case R.id.layout_shopping: - Toast.makeText(this.getApplicationContext(), this.getText(R.string.coming_soon), Toast.LENGTH_SHORT).show(); - break; - case R.id.layout_translate: - this.startActivity(new Intent(StartActivity.this, TranslatorActivity.class)); - break; - case R.id.layout_more: - this.startActivity(new Intent(StartActivity.this, AllFunctionActivity.class)); - break; - case R.id.setting_img: - this.startActivity(new Intent(StartActivity.this, SettingActivity.class)); - break; - case R.id.layout_segmentation: - this.startActivity(new Intent(StartActivity.this, ImageSegmentationActivity.class)); - break; - case R.id.layout_icr: - this.startActivity(new Intent(StartActivity.this, IDCardRecognitionActivity.class)); - break; - default: - Toast.makeText(this.getApplicationContext(), this.getText(R.string.coming_soon), Toast.LENGTH_SHORT).show(); + if (view.getId() == R.id.setting_img) { + this.startActivity(new Intent(StartActivity.this, SettingActivity.class)); + } + } + private void initData() { + this.mDataList = new ArrayList(); + GridViewItem item; + for (int i = 0; i < icons.length; i++) { + item = new GridViewItem(icons[i], titles[i]); + this.mDataList.add(item); } } @@ -180,7 +206,7 @@ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permis @Override public void onClick(DialogInterface dialog, int which) { Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); - // Open the corresponding setting interface according to the package name. + // Open the corresponding setting interface according to the package name. intent.setData(Uri.parse("package:" + StartActivity.this.getPackageName())); StartActivity.this.startActivityForResult(intent, 200); StartActivity.this.startActivity(intent); diff --git a/MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/TextRecognitionActivity.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/TextRecognitionActivity.java similarity index 91% rename from MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/TextRecognitionActivity.java rename to MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/TextRecognitionActivity.java index f9e2c94..14316a9 100644 --- a/MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/TextRecognitionActivity.java +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/TextRecognitionActivity.java @@ -36,18 +36,18 @@ import android.widget.TextView; import android.widget.Toast; -import com.mlkit.sample.R; import com.mlkit.sample.activity.dialog.AddPictureDialog; import com.mlkit.sample.camera.CameraConfiguration; import com.mlkit.sample.camera.LensEngine; import com.mlkit.sample.camera.LensEnginePreview; -import com.mlkit.sample.util.BitmapUtils; -import com.mlkit.sample.manager.LocalDataManager; +import com.mlkit.sample.processor.LocalDataProcessor; import com.mlkit.sample.transactor.LocalTextTransactor; +import com.mlkit.sample.util.BitmapUtils; import com.mlkit.sample.util.Constant; import com.mlkit.sample.util.SharedPreferencesUtil; -import com.mlkit.sample.views.overlay.ZoomImageView; import com.mlkit.sample.views.overlay.GraphicOverlay; +import com.mlkit.sample.views.overlay.ZoomImageView; +import com.mlkit.sample.R; import java.io.IOException; import java.lang.ref.WeakReference; @@ -76,7 +76,7 @@ public final class TextRecognitionActivity extends BaseActivity private AddPictureDialog addPictureDialog; private TextView textCN; private TextView textEN; - private TextView textJN ; + private TextView textJN; private TextView textKN; private TextView textLN; private String textType = Constant.POSITION_CN; @@ -195,7 +195,7 @@ public void onClick(View view) { } private void restartLensEngine(String type) { - if(this.textType.equals(type)){ + if (this.textType.equals(type)) { return; } this.lensEngine.release(); @@ -205,9 +205,7 @@ private void restartLensEngine(String type) { if (null != this.lensEngine) { this.mCamera = this.lensEngine.getCamera(); try { - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) { - this.mCamera.setPreviewDisplay(this.preview.getSurfaceHolder()); - } + this.mCamera.setPreviewDisplay(this.preview.getSurfaceHolder()); } catch (IOException e) { Log.d(TextRecognitionActivity.TAG, "initViews IOException"); } @@ -224,7 +222,7 @@ public void onBackPressed() { } } - private void createLanguageDialog(){ + private void createLanguageDialog() { this.languageDialog = new Dialog(this, R.style.MyDialogStyle); View view = View.inflate(this, R.layout.dialog_language_setting, null); // Set up a custom layout @@ -254,8 +252,8 @@ private void showLanguageDialog() { this.languageDialog.show(); } - private void createAddPictureDialog(){ - this.addPictureDialog = new AddPictureDialog(this); + private void createAddPictureDialog() { + this.addPictureDialog = new AddPictureDialog(this, AddPictureDialog.TYPE_NORMAL); final Intent intent = new Intent(TextRecognitionActivity.this, RemoteDetectionActivity.class); intent.putExtra(Constant.MODEL_TYPE, Constant.CLOUD_TEXT_DETECTION); this.addPictureDialog.setClickListener(new AddPictureDialog.ClickListener() { @@ -270,8 +268,14 @@ public void selectImage() { intent.putExtra(Constant.ADD_PICTURE_TYPE, Constant.TYPE_SELECT_IMAGE); TextRecognitionActivity.this.startActivity(intent); } + + @Override + public void doExtend() { + + } }); } + private void showAddPictureDialog() { this.addPictureDialog.show(); } @@ -375,15 +379,15 @@ private void recycleBitmap() { private void takePicture() { this.zoomImageLayout.setVisibility(View.VISIBLE); - LocalDataManager localDataManager = new LocalDataManager(); - localDataManager.setLandScape(this.isLandScape); + LocalDataProcessor localDataProcessor = new LocalDataProcessor(); + localDataProcessor.setLandScape(this.isLandScape); this.bitmap = BitmapUtils.getBitmap(this.localTextTransactor.getTransactingImage(), this.localTextTransactor.getTransactingMetaData()); - float previewWidth = localDataManager.getMaxWidthOfImage(this.localTextTransactor.getTransactingMetaData()); - float previewHeight = localDataManager.getMaxHeightOfImage(this.localTextTransactor.getTransactingMetaData()); + float previewWidth = localDataProcessor.getMaxWidthOfImage(this.localTextTransactor.getTransactingMetaData()); + float previewHeight = localDataProcessor.getMaxHeightOfImage(this.localTextTransactor.getTransactingMetaData()); if (this.isLandScape) { - previewWidth = localDataManager.getMaxHeightOfImage(this.localTextTransactor.getTransactingMetaData()); - previewHeight = localDataManager.getMaxWidthOfImage(this.localTextTransactor.getTransactingMetaData()); + previewWidth = localDataProcessor.getMaxHeightOfImage(this.localTextTransactor.getTransactingMetaData()); + previewHeight = localDataProcessor.getMaxWidthOfImage(this.localTextTransactor.getTransactingMetaData()); } this.bitmapCopy = Bitmap.createBitmap(this.bitmap).copy(Bitmap.Config.ARGB_8888, true); @@ -392,11 +396,11 @@ private void takePicture() { float max = Math.max(previewWidth, previewHeight); if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { - localDataManager.setCameraInfo(this.graphicOverlay, canvas, min, max); + localDataProcessor.setCameraInfo(this.graphicOverlay, canvas, min, max); } else { - localDataManager.setCameraInfo(this.graphicOverlay, canvas, max, min); + localDataProcessor.setCameraInfo(this.graphicOverlay, canvas, max, min); } - localDataManager.drawHmsMLVisionText(canvas, this.localTextTransactor.getLastResults().getBlocks()); + localDataProcessor.drawHmsMLVisionText(canvas, this.localTextTransactor.getLastResults().getBlocks()); this.zoomImageView.setImageBitmap(this.bitmapCopy); } } diff --git a/MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/TranslatorActivity.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/TranslatorActivity.java similarity index 98% rename from MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/TranslatorActivity.java rename to MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/TranslatorActivity.java index d8b23c3..9acf8dd 100644 --- a/MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/TranslatorActivity.java +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/TranslatorActivity.java @@ -32,7 +32,6 @@ import com.huawei.hmf.tasks.OnFailureListener; import com.huawei.hmf.tasks.OnSuccessListener; import com.huawei.hmf.tasks.Task; -import com.mlkit.sample.R; import com.huawei.hms.mlsdk.langdetect.MLDetectedLang; import com.huawei.hms.mlsdk.langdetect.MLLangDetectorFactory; import com.huawei.hms.mlsdk.langdetect.cloud.MLRemoteLangDetector; @@ -40,6 +39,7 @@ import com.huawei.hms.mlsdk.translate.MLTranslatorFactory; import com.huawei.hms.mlsdk.translate.cloud.MLRemoteTranslateSetting; import com.huawei.hms.mlsdk.translate.cloud.MLRemoteTranslator; +import com.mlkit.sample.R; import java.util.ArrayList; import java.util.Arrays; @@ -88,7 +88,7 @@ public class TranslatorActivity extends BaseActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - this.setContentView(R.layout.activity_translator); + this.setContentView(R.layout.activity_translate); this.createComponent(); this.createSpinner(); this.bindEventListener(); @@ -226,7 +226,7 @@ private void updateOutputText(final String text) { this.runOnUiThread(new Runnable() { @Override public void run() { - TranslatorActivity.this.tvOutputString.setText(String.format(Locale.ENGLISH, text)); + TranslatorActivity.this.tvOutputString.setText(text); TranslatorActivity.this.updateLength(TranslatorActivity.this.tvOutputLen, text.length()); } }); @@ -241,7 +241,7 @@ private void updateInputText(final String text) { this.runOnUiThread(new Runnable() { @Override public void run() { - TranslatorActivity.this.etInputString.setText(String.format(Locale.ENGLISH, text)); + TranslatorActivity.this.etInputString.setText(text); TranslatorActivity.this.updateLength(TranslatorActivity.this.tvInputLen, text.length()); } }); @@ -365,7 +365,7 @@ public void onSuccess(List result) { for (MLDetectedLang recognizedLang : result) { String langCode = recognizedLang.getLangCode(); float probability = recognizedLang.getProbability(); - sb.append("Language=" + TranslatorActivity.this.getEnLanguageName(langCode) +"(" + langCode + "), score=" + probability); + sb.append("Language=" + TranslatorActivity.this.getEnLanguageName(langCode) + "(" + langCode + "), score=" + probability); sb.append("."); } TranslatorActivity.this.updateOutputText(sb.toString()); diff --git a/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/adapter/GridViewAdapter.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/adapter/GridViewAdapter.java new file mode 100644 index 0000000..a670345 --- /dev/null +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/adapter/GridViewAdapter.java @@ -0,0 +1,94 @@ +/** + * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mlkit.sample.activity.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; +import android.widget.TextView; + +import com.mlkit.sample.R; +import com.mlkit.sample.activity.entity.GridViewItem; +import com.huawei.hms.mlsdk.common.internal.client.SmartLog; + +import java.util.ArrayList; + +public class GridViewAdapter extends BaseAdapter { + private final static String TAG = GridViewAdapter.class.getName(); + + private Context mContext; + + private ArrayList mDataList; + + public GridViewAdapter(ArrayList dataList, Context mContext) { + super(); + this.mDataList = dataList; + this.mContext = mContext; + } + + @Override + public int getCount() { + return this.mDataList.size(); + } + + @Override + public Object getItem(int position) { + return this.mDataList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ViewHolder holder = null; + try { + if (convertView == null) { + convertView = LayoutInflater.from(this.mContext).inflate(R.layout.gridview_item, null); + holder = new ViewHolder(); + holder.imageView = convertView.findViewById(R.id.image_item); + holder.textView = convertView.findViewById(R.id.text_item); + holder.imageNew = convertView.findViewById(R.id.icon_new); + convertView.setTag(holder); + } else { + holder = (ViewHolder) convertView.getTag(); + } + GridViewItem item = this.mDataList.get(position); + if(position == 0 || position == 1){ + holder.imageNew.setBackgroundResource(R.drawable.icon_new); + } + holder.imageView.setImageResource(item.getResourceId()); + holder.textView.setText(item.getStringId()); + } catch (Exception e) { + SmartLog.e("GridViewAdapter", e.getMessage()); + } + return convertView; + } + + static class ViewHolder { + ImageView imageView; + + ImageView imageNew; + + TextView textView; + } +} diff --git a/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/dialog/AddPictureDialog.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/dialog/AddPictureDialog.java new file mode 100644 index 0000000..6adb377 --- /dev/null +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/dialog/AddPictureDialog.java @@ -0,0 +1,106 @@ +/** + * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mlkit.sample.activity.dialog; + +import android.app.Dialog; +import android.content.Context; +import android.os.Bundle; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.widget.TextView; +import com.mlkit.sample.R; + +public class AddPictureDialog extends Dialog implements View.OnClickListener { + public static final int TYPE_NORMAL = 1; + public static final int TYPE_CUSTOM = 2; + private TextView tvTakePicture; + private TextView tvSelectImage; + private TextView tvExtend; + private Context context; + private ClickListener clickListener; + private int type; + + public interface ClickListener { + void takePicture(); + + void selectImage(); + + void doExtend(); + } + + public AddPictureDialog(Context context, int type) { + super(context, R.style.MyDialogStyle); + this.context = context; + this.type = type; + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + this.initViews(); + } + + private void initViews() { + LayoutInflater inflater = LayoutInflater.from(this.context); + View view = inflater.inflate(R.layout.dialog_add_picture, null); + this.setContentView(view); + + this.tvTakePicture = view.findViewById(R.id.take_photo); + this.tvSelectImage = view.findViewById(R.id.select_image); + this.tvExtend = view.findViewById(R.id.extend); + if (type == TYPE_CUSTOM) { + this.tvExtend.setText(R.string.video_frame); + } + this.tvTakePicture.setOnClickListener(this); + this.tvSelectImage.setOnClickListener(this); + this.tvExtend.setOnClickListener(this); + + this.setCanceledOnTouchOutside(true); + Window dialogWindow = this.getWindow(); + WindowManager.LayoutParams layoutParams = dialogWindow.getAttributes(); + layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT; + layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT; + layoutParams.gravity = Gravity.BOTTOM; + dialogWindow.setAttributes(layoutParams); + } + + public void setClickListener(ClickListener clickListener) { + this.clickListener = clickListener; + } + + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.take_photo: + this.dismiss(); + this.clickListener.takePicture(); + break; + case R.id.select_image: + this.dismiss(); + this.clickListener.selectImage(); + break; + case R.id.extend: + this.dismiss(); + this.clickListener.doExtend(); + break; + } + } +} + diff --git a/MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/fragment/OtherCategoryFragment.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/entity/BlockItem.java similarity index 63% rename from MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/fragment/OtherCategoryFragment.java rename to MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/entity/BlockItem.java index 4cdc877..e74118a 100644 --- a/MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/fragment/OtherCategoryFragment.java +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/entity/BlockItem.java @@ -14,22 +14,20 @@ * limitations under the License. */ -package com.mlkit.sample.activity.fragment; +package com.mlkit.sample.activity.entity; +import android.graphics.Rect; -import android.view.View; - -import com.mlkit.sample.activity.entity.GridViewItem; - - -import java.util.ArrayList; - -public class OtherCategoryFragment extends BaseFragment { - @Override - protected void initClickEvent(View view) { - } +/** + * Re-encapsulate the return result of OCR in Block + * + * @since 2020-03-12 + */ +public class BlockItem { + public final String text; + public final Rect rect; - @Override - protected void initData() { - this.mDataList = new ArrayList(); + public BlockItem(String text, Rect rect) { + this.text = text; + this.rect = rect; } } diff --git a/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/entity/GeneralCardResult.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/entity/GeneralCardResult.java new file mode 100644 index 0000000..c94ee79 --- /dev/null +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/entity/GeneralCardResult.java @@ -0,0 +1,34 @@ +/** + * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mlkit.sample.activity.entity; + + +/** + * Return result class of post-processing plugin + * + * @since 2020-03-12 + */ +public class GeneralCardResult { + public final String valid; + public final String number; + + public GeneralCardResult(String valid, String number) { + this.valid = valid; + this.number = number; + } + +} \ No newline at end of file diff --git a/MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/entity/GridViewItem.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/entity/GridViewItem.java similarity index 100% rename from MLKit-Sample/app/src/main/java/com/mlkit/sample/activity/entity/GridViewItem.java rename to MLKit-Sample/module-text/src/main/java/com/mlkit/sample/activity/entity/GridViewItem.java diff --git a/MLKit-Sample/app/src/main/java/com/mlkit/sample/callback/CloudInfoResultCallBack.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/callback/CouldInfoResultCallBack.java similarity index 96% rename from MLKit-Sample/app/src/main/java/com/mlkit/sample/callback/CloudInfoResultCallBack.java rename to MLKit-Sample/module-text/src/main/java/com/mlkit/sample/callback/CouldInfoResultCallBack.java index 6f9bff9..4077fb3 100644 --- a/MLKit-Sample/app/src/main/java/com/mlkit/sample/callback/CloudInfoResultCallBack.java +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/callback/CouldInfoResultCallBack.java @@ -22,7 +22,7 @@ import com.huawei.hms.mlsdk.document.MLDocument; import com.huawei.hms.mlsdk.text.MLText; -public interface CloudInfoResultCallBack { +public interface CouldInfoResultCallBack { void onSuccessForText(Bitmap originalCameraImage, MLText text, GraphicOverlay graphicOverlay); void onSuccessForDoc(Bitmap originalCameraImage, MLDocument text, GraphicOverlay graphicOverlay); diff --git a/MLKit-Sample/app/src/main/java/com/mlkit/sample/callback/ImageUtilCallBack.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/callback/ImageUtilCallBack.java similarity index 95% rename from MLKit-Sample/app/src/main/java/com/mlkit/sample/callback/ImageUtilCallBack.java rename to MLKit-Sample/module-text/src/main/java/com/mlkit/sample/callback/ImageUtilCallBack.java index 8e87191..6a9a313 100644 --- a/MLKit-Sample/app/src/main/java/com/mlkit/sample/callback/ImageUtilCallBack.java +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/callback/ImageUtilCallBack.java @@ -16,8 +16,6 @@ package com.mlkit.sample.callback; -import android.graphics.Bitmap; - public interface ImageUtilCallBack { void callSavePath(String path); } diff --git a/MLKit-Sample/app/src/main/java/com/mlkit/sample/callback/OnDeviceTextResultCallBack.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/callback/OnDeviceTextResultCallBack.java similarity index 100% rename from MLKit-Sample/app/src/main/java/com/mlkit/sample/callback/OnDeviceTextResultCallBack.java rename to MLKit-Sample/module-text/src/main/java/com/mlkit/sample/callback/OnDeviceTextResultCallBack.java diff --git a/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/camera/CameraConfiguration.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/camera/CameraConfiguration.java new file mode 100644 index 0000000..1906819 --- /dev/null +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/camera/CameraConfiguration.java @@ -0,0 +1,73 @@ +/** + * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mlkit.sample.camera; + +import android.hardware.Camera; + +public class CameraConfiguration { + + public static final int CAMERA_FACING_BACK = Camera.CameraInfo.CAMERA_FACING_BACK; + public static final int CAMERA_FACING_FRONT = Camera.CameraInfo.CAMERA_FACING_FRONT; + + public static final int MAX_WIDTH = 960; + public static final int MAX_HEIGHT = 720; + protected static int cameraFacing = CameraConfiguration.CAMERA_FACING_BACK; + + private float fps = 20.0f; + private int previewWidth = CameraConfiguration.MAX_WIDTH; + private int previewHeight = CameraConfiguration.MAX_HEIGHT; + private boolean isAutoFocus = true; + + public synchronized void setCameraFacing(int facing) { + if ((facing != CameraConfiguration.CAMERA_FACING_BACK) && (facing != CameraConfiguration.CAMERA_FACING_FRONT)) { + throw new IllegalArgumentException("Invalid camera: " + facing); + } + cameraFacing = facing; + } + + public float getFps() { + return this.fps; + } + + public void setFps(float fps) { + this.fps = fps; + } + + public int getPreviewWidth() { + return this.previewWidth; + } + + public void setPreviewWidth(int previewWidth) { + this.previewWidth = previewWidth; + } + + public int getPreviewHeight() { + return this.previewHeight; + } + + public void setPreviewHeight(int previewHeight) { + this.previewHeight = previewHeight; + } + + public boolean isAutoFocus() { + return this.isAutoFocus; + } + + public synchronized static int getCameraFacing() { + return cameraFacing; + } +} diff --git a/MLKit-Sample/app/src/main/java/com/mlkit/sample/camera/CameraSelector.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/camera/CameraSelector.java similarity index 100% rename from MLKit-Sample/app/src/main/java/com/mlkit/sample/camera/CameraSelector.java rename to MLKit-Sample/module-text/src/main/java/com/mlkit/sample/camera/CameraSelector.java diff --git a/MLKit-Sample/app/src/main/java/com/mlkit/sample/camera/FrameMetadata.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/camera/FrameMetadata.java similarity index 100% rename from MLKit-Sample/app/src/main/java/com/mlkit/sample/camera/FrameMetadata.java rename to MLKit-Sample/module-text/src/main/java/com/mlkit/sample/camera/FrameMetadata.java diff --git a/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/camera/LensEngine.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/camera/LensEngine.java new file mode 100644 index 0000000..ed9863f --- /dev/null +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/camera/LensEngine.java @@ -0,0 +1,317 @@ +/** + * Copyright 2018 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * 2020.2.21-Changed name from CameraSource to LensEngine, and adjusted the architecture, except for the classes: start and stop + * Huawei Technologies Co., Ltd. + */ + +package com.mlkit.sample.camera; + +import android.Manifest; +import android.annotation.SuppressLint; +import android.app.Activity; +import android.content.res.Configuration; +import android.graphics.ImageFormat; +import android.graphics.SurfaceTexture; +import android.hardware.Camera; +import android.util.Log; + +import androidx.annotation.RequiresPermission; + +import com.huawei.hms.common.size.Size; +import com.mlkit.sample.transactor.ImageTransactor; +import com.mlkit.sample.views.overlay.GraphicOverlay; + +import java.io.IOException; +import java.lang.Thread.State; +import java.nio.ByteBuffer; +import java.util.IdentityHashMap; +import java.util.Map; + +/** + * Manages the camera and allows UI updates on top of it (e.g. overlaying extra Graphics or + * displaying extra information). This receives preview frames from the camera at a specified rate, + * sending those frames to child classes' detectors / classifiers as fast as it is able to process. + */ +@SuppressLint("MissingPermission") +public class LensEngine { + private static final String TAG = "LensEngine"; + protected Activity activity; + private Camera camera; + private Thread transactingThread; + private final FrameTransactingRunnable transactingRunnable; + private final Object transactorLock = new Object(); + private ImageTransactor frameTransactor; + private CameraSelector selector; + private final Map bytesToByteBuffer = new IdentityHashMap<>(); + private GraphicOverlay overlay; + + public LensEngine(Activity activity, CameraConfiguration configuration, GraphicOverlay graphicOverlay) { + this.activity = activity; + this.transactingRunnable = new FrameTransactingRunnable(); + this.selector = new CameraSelector(activity, configuration); + this.overlay = graphicOverlay; + this.overlay.clear(); + } + + /** + * Stop the camera and release the resources of the camera and analyzer. + */ + public void release() { + synchronized (this.transactorLock) { + this.stop(); + this.transactingRunnable.release(); + if (this.frameTransactor != null) { + this.frameTransactor.stop(); + this.frameTransactor = null; + } + } + } + + /** + * Turn on the camera and start sending preview frames to the analyzer for detection. + * + * @throws IOException IO Exception + */ + @SuppressLint("MissingPermission") + @RequiresPermission(Manifest.permission.CAMERA) + public synchronized LensEngine run() throws IOException { + if (this.camera != null) { + return this; + } + this.camera = this.createCamera(); + this.camera.startPreview(); + this.initializeOverlay(); + this.transactingThread = new Thread(this.transactingRunnable); + this.transactingRunnable.setActive(true); + this.transactingThread.start(); + return this; + } + + /** + * Take pictures. + * + * @param pictureCallback Callback function after obtaining photo data. + */ + public synchronized void takePicture(android.hardware.Camera.PictureCallback pictureCallback) { + synchronized(this.transactorLock) { + if (this.camera != null) { + this.camera.takePicture(null,null,null, pictureCallback); + } + } + } + + public synchronized Camera getCamera() { + return this.camera; + } + + private void initializeOverlay() { + if (this.overlay != null) { + int min; + int max; + Size size = this.getPreviewSize(); + min = Math.min(size.getWidth(), size.getHeight()); + max = Math.max(size.getWidth(), size.getHeight()); + + if (this.activity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { + this.overlay.setCameraInfo(min, max, this.getFacing()); + } else { + this.overlay.setCameraInfo(max, min, this.getFacing()); + } + this.overlay.clear(); + } + } + + /** + * Get camera preview size. + * + * @return Size Size of camera preview. + */ + public Size getPreviewSize() { + return this.selector.getPreviewSize(); + } + + public int getFacing() { + return this.selector.getFacing(); + } + + /** + * Turn off the camera and stop transmitting frames to the analyzer. + */ + public synchronized void stop() { + this.transactingRunnable.setActive(false); + if (this.transactingThread != null) { + try { + this.transactingThread.join(); + } catch (InterruptedException e) { + Log.d(LensEngine.TAG, "Frame transacting thread interrupted on release."); + } + this.transactingThread = null; + } + if (this.camera != null) { + this.camera.stopPreview(); + this.camera.setPreviewCallbackWithBuffer(null); + try { + this.camera.setPreviewDisplay(null); + } catch (Exception e) { + Log.e(LensEngine.TAG, "Failed to clear camera preview: " + e); + } + this.camera.release(); + this.camera = null; + } + this.bytesToByteBuffer.clear(); + } + + @SuppressLint("InlinedApi") + private Camera createCamera() throws IOException { + Camera camera = this.selector.createCamera(); + camera.setPreviewCallbackWithBuffer(new CameraPreviewCallback()); + camera.addCallbackBuffer(this.createPreviewBuffer(this.selector.getPreviewSize())); + camera.addCallbackBuffer(this.createPreviewBuffer(this.selector.getPreviewSize())); + camera.addCallbackBuffer(this.createPreviewBuffer(this.selector.getPreviewSize())); + camera.addCallbackBuffer(this.createPreviewBuffer(this.selector.getPreviewSize())); + return camera; + } + + /** + * Create a buffer for the camera preview callback. The size of the buffer is based on the camera preview size and the camera image format. + * + * @param previewSize + * @return Image data from the camera + */ + @SuppressLint("InlinedApi") + private byte[] createPreviewBuffer(Size previewSize) { + int bitsPerPixel = ImageFormat.getBitsPerPixel(ImageFormat.NV21); + long sizeInBits = (long) previewSize.getHeight() * previewSize.getWidth() * bitsPerPixel; + int bufferSize = (int) Math.ceil(sizeInBits / 8.0d) + 1; + + byte[] byteArray = new byte[bufferSize]; + ByteBuffer buffer = ByteBuffer.wrap(byteArray); + if (!buffer.hasArray() || (buffer.array() != byteArray)) { + throw new IllegalStateException("Failed to create valid buffer for lensEngine."); + } + this.bytesToByteBuffer.put(byteArray, buffer); + return byteArray; + } + + private class CameraPreviewCallback implements Camera.PreviewCallback { + @Override + public void onPreviewFrame(byte[] data, Camera camera) { + LensEngine.this.transactingRunnable.setNextFrame(data, camera); + } + } + + public void setMachineLearningFrameTransactor(ImageTransactor transactor) { + synchronized (this.transactorLock) { + if (this.frameTransactor != null) { + this.frameTransactor.stop(); + } + this.frameTransactor = transactor; + } + } + + /** + * It is used to receive the frame captured by the camera and pass it to the analyzer. + */ + private class FrameTransactingRunnable implements Runnable { + private final Object lock = new Object(); + private boolean active = true; + private ByteBuffer pendingFrameData; + + FrameTransactingRunnable() { + } + + /** + * Frees the transactor and can safely perform this operation only after the associated thread has completed. + */ + @SuppressLint("Assert") + void release() { + synchronized (this.lock) { + assert (LensEngine.this.transactingThread.getState() == State.TERMINATED); + } + } + + void setActive(boolean active) { + synchronized (this.lock) { + this.active = active; + this.lock.notifyAll(); + } + } + + /** + * Sets the frame data received from the camera. Adds a previously unused frame buffer (if exit) back to the camera. + */ + void setNextFrame(byte[] data, Camera camera) { + synchronized (this.lock) { + if (this.pendingFrameData != null) { + camera.addCallbackBuffer(this.pendingFrameData.array()); + this.pendingFrameData = null; + } + if (!LensEngine.this.bytesToByteBuffer.containsKey(data)) { + Log.d(LensEngine.TAG, "Skipping frame. Could not find ByteBuffer associated with the image " + + "data from the camera."); + return; + } + this.pendingFrameData = LensEngine.this.bytesToByteBuffer.get(data); + this.lock.notifyAll(); + } + } + + @SuppressLint("InlinedApi") + @SuppressWarnings("GuardedBy") + @Override + public void run() { + ByteBuffer data; + + while (true) { + synchronized (this.lock) { + while (this.active && (this.pendingFrameData == null)) { + try { + // Waiting for next frame. + this.lock.wait(); + } catch (InterruptedException e) { + Log.w(LensEngine.TAG, "Frame transacting loop terminated.", e); + return; + } + } + if (!this.active) { + this.pendingFrameData = null; + return; + } + data = this.pendingFrameData; + this.pendingFrameData = null; + } + try { + synchronized (LensEngine.this.transactorLock) { + Log.d(LensEngine.TAG, "Process an image"); + LensEngine.this.frameTransactor.process( + data, + new FrameMetadata.Builder() + .setWidth(LensEngine.this.selector.getPreviewSize().getWidth()) + .setHeight(LensEngine.this.selector.getPreviewSize().getHeight()) + .setRotation(LensEngine.this.selector.getRotation()) + .setCameraFacing(LensEngine.this.selector.getFacing()) + .build(), + LensEngine.this.overlay + ); + } + } catch (Throwable t) { + Log.e(LensEngine.TAG, "Exception thrown from receiver.", t); + } finally { + LensEngine.this.camera.addCallbackBuffer(data.array()); + } + } + } + } +} diff --git a/MLKit-Sample/app/src/main/java/com/mlkit/sample/camera/LensEnginePreview.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/camera/LensEnginePreview.java similarity index 95% rename from MLKit-Sample/app/src/main/java/com/mlkit/sample/camera/LensEnginePreview.java rename to MLKit-Sample/module-text/src/main/java/com/mlkit/sample/camera/LensEnginePreview.java index 5b35ffe..2cf791a 100644 --- a/MLKit-Sample/app/src/main/java/com/mlkit/sample/camera/LensEnginePreview.java +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/camera/LensEnginePreview.java @@ -123,15 +123,15 @@ public void surfaceDestroyed(SurfaceHolder surface) { @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { Log.d(LensEnginePreview.TAG, "surfaceChanged"); - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) { - if (!LensEnginePreview.this.isSynchronous) { - Camera camera = LensEnginePreview.this.lensEngine.getCamera(); - try { - camera.setPreviewDisplay(LensEnginePreview.this.surfaceView.getHolder()); - } catch (IOException e) { - Log.e(LensEnginePreview.TAG, "IOException", e); - } - } + + Camera camera = LensEnginePreview.this.lensEngine.getCamera(); + if (camera == null) { + return; + } + try { + camera.setPreviewDisplay(LensEnginePreview.this.surfaceView.getHolder()); + } catch (IOException e) { + Log.e(LensEnginePreview.TAG, "IOException", e); } } } @@ -203,6 +203,9 @@ public boolean onTouchEvent(MotionEvent event) { if (CameraConfiguration.getCameraFacing() == CameraConfiguration.CAMERA_FACING_FRONT) { return true; } + if (this.lensEngine == null) { + return true; + } if (event.getPointerCount() == 1) { switch (event.getAction()) { case MotionEvent.ACTION_UP: diff --git a/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/parcel/NestParam.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/parcel/NestParam.java new file mode 100644 index 0000000..926e595 --- /dev/null +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/parcel/NestParam.java @@ -0,0 +1,84 @@ +/** + * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mlkit.sample.parcel; + +import android.os.Parcel; +import android.os.Parcelable; + +import com.huawei.hms.ml.common.parcel.ParcelReader; +import com.huawei.hms.ml.common.parcel.ParcelWriter; + +import androidx.annotation.NonNull; + +/** + * Custom nested parameters + * + * @since 2020-03-02 + */ +public class NestParam implements Parcelable { + public int filed1; + + public int filed2; + + public NestParam() { + + } + + protected NestParam(Parcel in) { + final ParcelReader reader = new ParcelReader(in); + this.filed1 = reader.readInt(2, -1); + this.filed2 = reader.readInt(3, -1); + reader.finish(); // Key steps + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + final ParcelWriter writer = new ParcelWriter(dest); + final int pos = writer.beginObjectHeader(); + writer.writeInt(2, this.filed1); + writer.writeInt(3, this.filed2); + writer.finishObjectHeader(pos); + } + + @Override + public int describeContents() { + return 0; + } + + public static final Creator CREATOR = new Creator() { + @Override + public NestParam createFromParcel(Parcel in) { + return new NestParam(in); + } + + @Override + public NestParam[] newArray(int size) { + return new NestParam[size]; + } + }; + + @NonNull + @Override + public String toString() { + StringBuffer buffer = new StringBuffer(); + buffer.append("filed1 = " + this.filed1); + buffer.append(", "); + buffer.append("filed2 = " + this.filed2); + + return buffer.toString(); + } +} diff --git a/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/parcel/Parameter.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/parcel/Parameter.java new file mode 100644 index 0000000..1602a42 --- /dev/null +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/parcel/Parameter.java @@ -0,0 +1,112 @@ +/** + * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mlkit.sample.parcel; + +import android.graphics.Bitmap; +import android.graphics.Rect; +import android.os.Parcel; +import android.os.Parcelable; + +import com.huawei.hms.ml.common.parcel.ParcelReader; +import com.huawei.hms.ml.common.parcel.ParcelWriter; + +import androidx.annotation.NonNull; + +public class Parameter implements Parcelable { + + public NestParam nestParam; + + public int width; + + public int height; + + public Bitmap bitmap; + + public byte[] bytes; + + public Rect rect; + + public String aString; + + public Parameter() { + + } + + protected Parameter(Parcel in) { + final ParcelReader reader = new ParcelReader(in); + this.nestParam = reader.readParcelable(2, NestParam.CREATOR, null); + this.width = reader.readInt(3, -1); + this.height = reader.readInt(4, -1); + this.bitmap = reader.readParcelable(5, Bitmap.CREATOR, null); + this.bytes = reader.createByteArray(6, null); + this.rect = reader.readParcelable(7, Rect.CREATOR, null); + this.aString = reader.createString(8, null); + reader.finish(); // Key steps + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + final ParcelWriter writer = new ParcelWriter(dest); + final int pos = writer.beginObjectHeader(); + writer.writeParcelable(2, this.nestParam, flags, false); + writer.writeInt(3, this.width); + writer.writeInt(4, this.height); + writer.writeParcelable(5, this.bitmap, flags, false); + writer.writeByteArray(6, this.bytes, false); + writer.writeParcelable(7, this.rect, flags, false); + writer.writeString(8, this.aString, false); + writer.finishObjectHeader(pos); + } + + @Override + public int describeContents() { + return 0; + } + + public static final Creator CREATOR = new Creator() { + @Override + public Parameter createFromParcel(Parcel in) { + return new Parameter(in); + } + + @Override + public Parameter[] newArray(int size) { + return new Parameter[size]; + } + }; + + @NonNull + @Override + public String toString() { + StringBuffer buffer = new StringBuffer(); + buffer.append("nestParam = " + this.nestParam); + buffer.append(", "); + buffer.append("width = " + this.width); + buffer.append(", "); + buffer.append("height = " + this.height); + buffer.append(", "); + buffer.append("bitmap.size = " + (this.bitmap == null ? "NULL" : this.bitmap.getByteCount())); + buffer.append(", "); + buffer.append("bytes = " + (this.bytes == null ? "NULL" : this.bytes.length)); + buffer.append(", "); + buffer.append("rect = " + (this.rect == null ? "NULL" : this.rect)); + buffer.append(", "); + buffer.append("aString = " + (this.aString == null ? "NULL" : this.aString)); + + return buffer.toString(); + } +} diff --git a/MLKit-Sample/app/src/main/java/com/mlkit/sample/manager/CloudDataManager.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/processor/CloudDataProcessor.java similarity index 93% rename from MLKit-Sample/app/src/main/java/com/mlkit/sample/manager/CloudDataManager.java rename to MLKit-Sample/module-text/src/main/java/com/mlkit/sample/processor/CloudDataProcessor.java index fe5b2ea..3ff7dc7 100644 --- a/MLKit-Sample/app/src/main/java/com/mlkit/sample/manager/CloudDataManager.java +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/processor/CloudDataProcessor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.mlkit.sample.manager; +package com.mlkit.sample.processor; import android.graphics.Bitmap; import android.graphics.Canvas; @@ -24,14 +24,14 @@ import android.graphics.Point; import android.graphics.Rect; -import com.mlkit.sample.views.overlay.GraphicOverlay; import com.huawei.hms.mlsdk.common.LensEngine; import com.huawei.hms.mlsdk.document.MLDocument; import com.huawei.hms.mlsdk.text.MLText; +import com.mlkit.sample.views.overlay.GraphicOverlay; import java.util.List; -public class CloudDataManager { +public class CloudDataProcessor { private GraphicOverlay mGraphicOverlay; @@ -39,10 +39,16 @@ public class CloudDataManager { private MLText mHmsMLVisionText; - public CloudDataManager(GraphicOverlay mGraphicOverlay, Bitmap mBitmapCopyForTap, MLText mHmsMLVisionText) { - this.mGraphicOverlay = mGraphicOverlay; - this.mBitmapCopyForTap = mBitmapCopyForTap; - this.mHmsMLVisionText = mHmsMLVisionText; + public void setGraphicOverlay (GraphicOverlay graphicOverlay) { + this.mGraphicOverlay = graphicOverlay; + } + + public void setBitmap(Bitmap bitmapCopyForTap) { + this.mBitmapCopyForTap = bitmapCopyForTap; + } + + public void setText(MLText text) { + this.mHmsMLVisionText = text; } public void drawView(Canvas canvas, boolean flag) { @@ -164,7 +170,7 @@ private float translateY(float y, GraphicOverlay graphicOverlay) { public void drawCloudDocText(MLDocument text, Canvas canvas) { Paint textPaint = new Paint(); - textPaint.setColor(Color.WHITE); + textPaint.setColor(Color.parseColor("#EE6A50")); List blocks = text.getBlocks(); for (int i = 0; i < blocks.size(); i++) { diff --git a/MLKit-Sample/app/src/main/java/com/mlkit/sample/manager/LocalDataManager.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/processor/LocalDataProcessor.java similarity index 98% rename from MLKit-Sample/app/src/main/java/com/mlkit/sample/manager/LocalDataManager.java rename to MLKit-Sample/module-text/src/main/java/com/mlkit/sample/processor/LocalDataProcessor.java index 0b41c02..7237827 100644 --- a/MLKit-Sample/app/src/main/java/com/mlkit/sample/manager/LocalDataManager.java +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/processor/LocalDataProcessor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.mlkit.sample.manager; +package com.mlkit.sample.processor; import android.graphics.Canvas; import android.graphics.Color; @@ -22,13 +22,13 @@ import android.graphics.Path; import android.graphics.Point; +import com.huawei.hms.mlsdk.text.MLText; import com.mlkit.sample.camera.FrameMetadata; import com.mlkit.sample.views.overlay.GraphicOverlay; -import com.huawei.hms.mlsdk.text.MLText; import java.util.List; -public class LocalDataManager { +public class LocalDataProcessor { private float previewWidth; private float previewHeight; private float widthScaleValue = 1.0f; diff --git a/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/processor/gcr/GeneralCardProcessor.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/processor/gcr/GeneralCardProcessor.java new file mode 100644 index 0000000..4d8f37b --- /dev/null +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/processor/gcr/GeneralCardProcessor.java @@ -0,0 +1,28 @@ +/** + * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mlkit.sample.processor.gcr; + +import com.mlkit.sample.activity.entity.GeneralCardResult; + +/** + * Common interface for post-processing plugins + * + * @since 2020-03-12 + */ +public interface GeneralCardProcessor { + GeneralCardResult getResult(); +} \ No newline at end of file diff --git a/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/processor/gcr/homecard/HomeCardProcessor.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/processor/gcr/homecard/HomeCardProcessor.java new file mode 100644 index 0000000..94f50a0 --- /dev/null +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/processor/gcr/homecard/HomeCardProcessor.java @@ -0,0 +1,113 @@ +/** + * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mlkit.sample.processor.gcr.homecard; + +import android.graphics.Point; +import android.graphics.Rect; +import android.util.Log; + +import com.huawei.hms.mlsdk.text.MLText; +import com.mlkit.sample.activity.entity.BlockItem; +import com.mlkit.sample.activity.entity.GeneralCardResult; +import com.mlkit.sample.processor.gcr.GeneralCardProcessor; +import com.mlkit.sample.util.StringUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + * Post processing plug-in of Mainland Travel Permit for Hong Kong、Macao and Taiwan residents + * + * @since 2020-03-12 + */ +public class HomeCardProcessor implements GeneralCardProcessor { + private static final String TAG = "HomeCardProcessor"; + + private final MLText text; + + public HomeCardProcessor(MLText text) { + this.text = text; + } + + @Override + public GeneralCardResult getResult() { + List blocks = text.getBlocks(); + if (blocks.isEmpty()) { + Log.i(TAG, "Result blocks is empty"); + return null; + } + + ArrayList originItems = getOriginItems(blocks); + + String valid = ""; + String number = ""; + boolean numberFlag = false; + boolean validFlag = false; + + for (BlockItem item : originItems) { + String tempStr = item.text; + + if (!validFlag) { + String result = tryGetValidDate(tempStr); + if (!result.isEmpty()) { + valid = result; + validFlag = true; + } + } + + if (!numberFlag) { + String result = tryGetCardNumber(tempStr); + if (!result.isEmpty()) { + number = result; + numberFlag = true; + } + } + } + + Log.i(TAG, "valid: " + valid); + Log.i(TAG, "number: " + number); + + return new GeneralCardResult(valid, number); + } + + private ArrayList getOriginItems(List blocks) { + ArrayList originItems = new ArrayList<>(); + + for (MLText.Block block : blocks) { + // Add in behavior units + List lines = block.getContents(); + for (MLText.TextLine line : lines) { + String text = line.getStringValue(); + text = StringUtils.filterString(text, "[^a-zA-Z0-9\\.\\-,<\\(\\)\\s]"); + Log.d(TAG, "text: " + text); + Point[] points = line.getVertexes(); + Rect rect = new Rect(points[0].x, points[0].y, points[2].x, points[2].y); + BlockItem item = new BlockItem(text, rect); + originItems.add(item); + } + } + return originItems; + } + + private String tryGetValidDate(String originStr) { + return StringUtils.getCorrectValidDate(originStr); + } + + private String tryGetCardNumber(String originStr) { + return StringUtils.getHomeCardNumber(originStr); + } +} \ No newline at end of file diff --git a/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/processor/gcr/hongkong/HKIdCardProcessor.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/processor/gcr/hongkong/HKIdCardProcessor.java new file mode 100644 index 0000000..f2c1bf5 --- /dev/null +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/processor/gcr/hongkong/HKIdCardProcessor.java @@ -0,0 +1,115 @@ +/** + * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mlkit.sample.processor.gcr.hongkong; + +import android.graphics.Point; +import android.graphics.Rect; +import android.util.Log; + +import com.huawei.hms.mlsdk.text.MLText; +import com.mlkit.sample.activity.entity.BlockItem; +import com.mlkit.sample.activity.entity.GeneralCardResult; +import com.mlkit.sample.processor.gcr.GeneralCardProcessor; +import com.mlkit.sample.util.StringUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + * Post processing plug-in of Hong Kong permanent identity card recognition + * + * @since 2020-03-12 + */ +public class HKIdCardProcessor implements GeneralCardProcessor { + private static final String TAG = "HKIdCardProcessor"; + + private final MLText text; + + public HKIdCardProcessor(MLText text) { + this.text = text; + } + + @Override + public GeneralCardResult getResult() { + List blocks = text.getBlocks(); + if (blocks.isEmpty()) { + Log.i(TAG, "Result blocks is empty"); + return null; + } + + ArrayList originItems = getOriginItems(blocks); + + String valid = ""; + String number = ""; + boolean numberFlag = false; + boolean validFlag = false; + + int location = 1; + for (BlockItem item : originItems) { + String tempStr = item.text; + + if (!validFlag && (originItems.size() - location) < 3) { + String result = tryGetValidDate(tempStr); + if (!result.isEmpty()) { + valid = result; + validFlag = true; + } + } + + if (!numberFlag) { + String result = tryGetCardNumber(tempStr); + if (!result.isEmpty()) { + number = result; + numberFlag = true; + } + } + location++; + } + + Log.i(TAG, "valid: " + valid); + Log.i(TAG, "number: " + number); + + return new GeneralCardResult(valid, number); + } + + private String tryGetValidDate(String originStr) { + int[] formatter = {2, 2, 2}; + return StringUtils.getCorrectDate(originStr, "\\-", formatter); + } + + private String tryGetCardNumber(String originStr) { + return StringUtils.getHKIdCardNum(originStr); + } + + private ArrayList getOriginItems(List blocks) { + ArrayList originItems = new ArrayList<>(); + for (MLText.Block block : blocks) { + // Add in behavior units + List lines = block.getContents(); + for (MLText.TextLine line : lines) { + String text = line.getStringValue(); + text = StringUtils.filterString(text, "[^a-zA-Z0-9\\.\\-,<\\(\\)\\s]"); + Log.d(TAG, "text: " + text); + Point[] points = line.getVertexes(); + Rect rect = new Rect(points[0].x, points[0].y, points[2].x, points[2].y); + BlockItem item = new BlockItem(text, rect); + originItems.add(item); + } + } + return originItems; + } +} diff --git a/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/processor/gcr/passcard/PassCardProcessor.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/processor/gcr/passcard/PassCardProcessor.java new file mode 100644 index 0000000..3e1d559 --- /dev/null +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/processor/gcr/passcard/PassCardProcessor.java @@ -0,0 +1,119 @@ +/** + * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mlkit.sample.processor.gcr.passcard; + +import android.graphics.Point; +import android.graphics.Rect; +import android.util.Log; + +import com.huawei.hms.mlsdk.text.MLText; +import com.mlkit.sample.activity.entity.BlockItem; +import com.mlkit.sample.activity.entity.GeneralCardResult; +import com.mlkit.sample.processor.gcr.GeneralCardProcessor; +import com.mlkit.sample.util.StringUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +/** + * Post processing plug-in of Hong Kong, Macao and Taiwan pass recognition + * + * @since 2020-03-12 + */ +public class PassCardProcessor implements GeneralCardProcessor { + private static final String TAG = "PassCardProcessor"; + + private final MLText text; + + public PassCardProcessor(MLText text) { + this.text = text; + } + + @Override + public GeneralCardResult getResult() { + List blocks = text.getBlocks(); + if (blocks.isEmpty()) { + Log.i(TAG, "Result blocks is empty"); + return null; + } + + ArrayList originItems = getOriginItems(blocks); + + String valid = ""; + String number = ""; + boolean validFlag = false; + boolean numberFlag = false; + + for (BlockItem item : originItems) { + String tempStr = item.text; + + if (!validFlag) { + String result = tryGetValidDate(tempStr); + if (!result.isEmpty()) { + valid = result; + validFlag = true; + } + } + + if (!numberFlag) { + String result = tryGetCardNumber(tempStr); + if (!result.isEmpty()) { + number = result; + numberFlag = true; + } + } + } + + Log.i(TAG, "valid: " + valid); + Log.i(TAG, "number: " + number); + + return new GeneralCardResult(valid, number); + } + + private String tryGetValidDate(String originStr) { + return StringUtils.getCorrectValidDate(originStr); + } + + private String tryGetCardNumber(String originStr) { + String result = StringUtils.getPassCardNumber(originStr); + if (!result.isEmpty()) { + result = result.toUpperCase(Locale.ENGLISH); + result = StringUtils.filterString(result, "[^0-9A-Z<]"); + } + return result; + } + + private ArrayList getOriginItems(List blocks) { + ArrayList originItems = new ArrayList<>(); + + for (MLText.Block block : blocks) { + // Add in behavior units + List lines = block.getContents(); + for (MLText.TextLine line : lines) { + String text = line.getStringValue(); + text = StringUtils.filterString(text, "[^a-zA-Z0-9\\.\\-,<\\(\\)\\s]"); + Log.d(TAG, "text: " + text); + Point[] points = line.getVertexes(); + Rect rect = new Rect(points[0].x, points[0].y, points[2].x, points[2].y); + BlockItem item = new BlockItem(text, rect); + originItems.add(item); + } + } + return originItems; + } +} diff --git a/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/transactor/BaseTransactor.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/transactor/BaseTransactor.java new file mode 100644 index 0000000..da80bd6 --- /dev/null +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/transactor/BaseTransactor.java @@ -0,0 +1,149 @@ +/** + * Copyright 2018 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * 2020.2.21-Changed name from VisionProcessorBase to BaseTransactor. + * 2020.2.21-Deleted method: process(Bitmap bitmap, GraphicOverlay graphicOverlay, + * String path,boolean flag); + * process(Bitmap bitmap, GraphicOverlay graphicOverlay,String path); + * onSuccess( + * @Nullable Bitmap originalCameraImage, + * @NonNull T results, + * @NonNull FrameMetadata frameMetadata, + * @NonNull GraphicOverlay graphicOverlay, String path, boolean flag); + * onSuccess( + * @Nullable Bitmap originalCameraImage, + * @NonNull T results, + * @NonNull FrameMetadata frameMetadata, + * @NonNull GraphicOverlay graphicOverlay, String path); + * writeFileSdcard(String message); + * Huawei Technologies Co., Ltd. + */ + +package com.mlkit.sample.transactor; + +import android.graphics.Bitmap; +import android.graphics.ImageFormat; + +import com.huawei.hmf.tasks.OnFailureListener; +import com.huawei.hmf.tasks.OnSuccessListener; +import com.huawei.hmf.tasks.Task; +import com.mlkit.sample.camera.CameraConfiguration; +import com.mlkit.sample.util.BitmapUtils; +import com.mlkit.sample.camera.FrameMetadata; +import com.mlkit.sample.util.CommonUtils; +import com.mlkit.sample.views.overlay.GraphicOverlay; +import com.huawei.hms.mlsdk.common.MLFrame; + +import java.nio.ByteBuffer; + +public abstract class BaseTransactor implements ImageTransactor { + + // To keep the latest images and its metadata. + private ByteBuffer latestImage; + + private FrameMetadata latestImageMetaData; + + // To keep the images and metadata in process. + private ByteBuffer transactingImage; + + private FrameMetadata transactingMetaData; + + public BaseTransactor() { + } + + @Override + public synchronized void process(ByteBuffer data, final FrameMetadata frameMetadata, GraphicOverlay graphicOverlay) { + this.latestImage = data; + this.latestImageMetaData = frameMetadata; + if (this.transactingImage == null && this.transactingMetaData == null) { + this.processLatestImage(graphicOverlay); + } + } + + @Override + public void process(Bitmap bitmap, GraphicOverlay graphicOverlay) { + MLFrame frame = new MLFrame.Creator().setBitmap(bitmap).create(); + this.detectInVisionImage(bitmap, frame, null, graphicOverlay); + } + + private synchronized void processLatestImage(GraphicOverlay graphicOverlay) { + this.transactingImage = this.latestImage; + this.transactingMetaData = this.latestImageMetaData; + this.latestImage = null; + this.latestImageMetaData = null; + if (this.transactingImage != null && this.transactingMetaData != null) { + int width; + int height; + width = this.transactingMetaData.getWidth(); + height = this.transactingMetaData.getHeight(); + + MLFrame.Property metadata = + new MLFrame.Property.Creator() + .setFormatType(ImageFormat.NV21) + .setWidth(width) + .setHeight(height) + .setQuadrant(this.transactingMetaData.getRotation()) + .create(); + Bitmap bitmap = BitmapUtils.getBitmap(this.transactingImage, this.transactingMetaData); + this.detectInVisionImage( + bitmap, MLFrame.fromByteBuffer(this.transactingImage, metadata), this.transactingMetaData, graphicOverlay); + + } + } + + private void detectInVisionImage(final Bitmap bitmap, MLFrame image, final FrameMetadata metadata, + final GraphicOverlay graphicOverlay) { + this.detectInImage(image) + .addOnSuccessListener( + new OnSuccessListener() { + @Override + public void onSuccess(T results) { + if (metadata == null || metadata.getCameraFacing() == CameraConfiguration.getCameraFacing()) { + BaseTransactor.this.onSuccess(bitmap, results, metadata, graphicOverlay); + } + BaseTransactor.this.processLatestImage(graphicOverlay); + } + }) + .addOnFailureListener( + new OnFailureListener() { + @Override + public void onFailure(Exception e) { + BaseTransactor.this.onFailure(e); + } + }); + } + + @Override + public void stop() { + } + + protected abstract Task detectInImage(MLFrame image); + + /** + * Callback that executes with a successful detection result. + * @param originalCameraImage hold the original image from camera, used to draw the background + * image. + * @param results + * @param frameMetadata + * @param graphicOverlay + */ + + protected abstract void onSuccess( + Bitmap originalCameraImage, + T results, + FrameMetadata frameMetadata, GraphicOverlay graphicOverlay); + + protected abstract void onFailure(Exception e); + +} diff --git a/MLKit-Sample/app/src/main/java/com/mlkit/sample/transactor/DocumentTextTransactor.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/transactor/DocumentTextTransactor.java similarity index 93% rename from MLKit-Sample/app/src/main/java/com/mlkit/sample/transactor/DocumentTextTransactor.java rename to MLKit-Sample/module-text/src/main/java/com/mlkit/sample/transactor/DocumentTextTransactor.java index 9dd1f09..3af8ba2 100644 --- a/MLKit-Sample/app/src/main/java/com/mlkit/sample/transactor/DocumentTextTransactor.java +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/transactor/DocumentTextTransactor.java @@ -24,7 +24,7 @@ import androidx.annotation.Nullable; import com.huawei.hmf.tasks.Task; -import com.mlkit.sample.callback.CloudInfoResultCallBack; +import com.mlkit.sample.callback.CouldInfoResultCallBack; import com.mlkit.sample.camera.FrameMetadata; import com.mlkit.sample.util.Constant; import com.mlkit.sample.views.overlay.GraphicOverlay; @@ -40,7 +40,7 @@ public class DocumentTextTransactor private final MLDocumentAnalyzer detector; - private CloudInfoResultCallBack callBack; + private CouldInfoResultCallBack callBack; private Handler handler; @@ -49,7 +49,7 @@ public DocumentTextTransactor(Handler handler) { this.handler = handler; } - public void addCouldTextResultCallBack(CloudInfoResultCallBack callBack) { + public void addCouldTextResultCallBack(CouldInfoResultCallBack callBack) { this.callBack = callBack; } diff --git a/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/transactor/ImageTransactor.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/transactor/ImageTransactor.java new file mode 100644 index 0000000..c411409 --- /dev/null +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/transactor/ImageTransactor.java @@ -0,0 +1,38 @@ +/** + * Copyright 2018 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * 2020.2.21-Changed name from VisionImageProcessor to ImageTransactor. + * 2020.2.21-Deleted method: process(Bitmap bitmap, GraphicOverlay graphicOverlay,String path,boolean flag); + * process(Bitmap bitmap, GraphicOverlay graphicOverlay,String path); + * Huawei Technologies Co., Ltd. + */ + +package com.mlkit.sample.transactor; + +import android.graphics.Bitmap; + + +import com.mlkit.sample.camera.FrameMetadata; +import com.mlkit.sample.views.overlay.GraphicOverlay; + +import java.nio.ByteBuffer; + +public interface ImageTransactor { + + void process(ByteBuffer data, FrameMetadata frameMetadata, GraphicOverlay graphicOverlay); + + void process(Bitmap bitmap, GraphicOverlay graphicOverlay); + + void stop(); +} diff --git a/MLKit-Sample/app/src/main/java/com/mlkit/sample/transactor/LocalTextTransactor.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/transactor/LocalTextTransactor.java similarity index 98% rename from MLKit-Sample/app/src/main/java/com/mlkit/sample/transactor/LocalTextTransactor.java rename to MLKit-Sample/module-text/src/main/java/com/mlkit/sample/transactor/LocalTextTransactor.java index c6d4fd0..dddfcdb 100644 --- a/MLKit-Sample/app/src/main/java/com/mlkit/sample/transactor/LocalTextTransactor.java +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/transactor/LocalTextTransactor.java @@ -67,7 +67,7 @@ public LocalTextTransactor(Handler handler, Context context) { } private String getLanguage() { - String position = SharedPreferencesUtil.getInstance(this.mContext).getStringValue(Constant.POSITION_KEY); + String position = SharedPreferencesUtil.getInstance(mContext).getStringValue(Constant.POSITION_KEY); Log.d(LocalTextTransactor.TAG, "position: " + position); String language = ""; switch (position){ diff --git a/MLKit-Sample/app/src/main/java/com/mlkit/sample/transactor/RemoteTextTransactor.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/transactor/RemoteTextTransactor.java similarity index 94% rename from MLKit-Sample/app/src/main/java/com/mlkit/sample/transactor/RemoteTextTransactor.java rename to MLKit-Sample/module-text/src/main/java/com/mlkit/sample/transactor/RemoteTextTransactor.java index 5396d1f..99839e1 100644 --- a/MLKit-Sample/app/src/main/java/com/mlkit/sample/transactor/RemoteTextTransactor.java +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/transactor/RemoteTextTransactor.java @@ -23,7 +23,7 @@ import androidx.annotation.Nullable; import com.huawei.hmf.tasks.Task; -import com.mlkit.sample.callback.CloudInfoResultCallBack; +import com.mlkit.sample.callback.CouldInfoResultCallBack; import com.mlkit.sample.camera.FrameMetadata; import com.mlkit.sample.util.Constant; import com.mlkit.sample.views.overlay.GraphicOverlay; @@ -39,7 +39,7 @@ public class RemoteTextTransactor extends BaseTransactor { private final MLTextAnalyzer detector; - private CloudInfoResultCallBack callBack; + private CouldInfoResultCallBack callBack; private Handler handler; @@ -56,7 +56,7 @@ protected Task detectInImage(MLFrame image) { return this.detector.asyncAnalyseFrame(image); } - public void addCouldTextResultCallBack(CloudInfoResultCallBack callBack) { + public void addCouldTextResultCallBack(CouldInfoResultCallBack callBack) { this.callBack = callBack; } diff --git a/MLKit-Sample/app/src/main/java/com/mlkit/sample/util/BitmapUtils.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/util/BitmapUtils.java similarity index 90% rename from MLKit-Sample/app/src/main/java/com/mlkit/sample/util/BitmapUtils.java rename to MLKit-Sample/module-text/src/main/java/com/mlkit/sample/util/BitmapUtils.java index b98a504..e6a31b9 100644 --- a/MLKit-Sample/app/src/main/java/com/mlkit/sample/util/BitmapUtils.java +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/util/BitmapUtils.java @@ -62,9 +62,9 @@ public static Bitmap getBitmap(ByteBuffer data, FrameMetadata metadata) { yuvImage.compressToJpeg(new Rect(0, 0, metadata.getWidth(), metadata.getHeight()), 80, stream); Bitmap bitmap = BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.size()); stream.close(); - return BitmapUtils.rotateBitmap(bitmap, metadata.getRotation(), metadata.getCameraFacing()); + return rotateBitmap(bitmap, metadata.getRotation(), metadata.getCameraFacing()); } catch (Exception e) { - Log.e(BitmapUtils.TAG, "Error: " + e.getMessage()); + Log.e(TAG, "Error: " + e.getMessage()); } return null; } @@ -108,14 +108,14 @@ public static Bitmap loadFromPath(Activity activity, Uri uri, int width, int hei BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; - String path = BitmapUtils.getImagePath(activity, uri); + String path = getImagePath(activity, uri); BitmapFactory.decodeFile(path, options); - int sampleSize = BitmapUtils.calculateInSampleSize(options, width, height); + int sampleSize = calculateInSampleSize(options, width, height); options.inSampleSize = sampleSize; options.inJustDecodeBounds = false; - Bitmap bitmap = BitmapUtils.zoomImage(BitmapFactory.decodeFile(path, options), width, height); - return BitmapUtils.rotateBitmap(bitmap, BitmapUtils.getRotationAngle(path)); + Bitmap bitmap = zoomImage(BitmapFactory.decodeFile(path, options), width, height); + return rotateBitmap(bitmap, getRotationAngle(path)); } private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { @@ -173,7 +173,7 @@ public static int getRotationAngle(String path) { break; } } catch (IOException e) { - SmartLog.e(BitmapUtils.TAG, "Failed to get rotation: " + e.getMessage()); + SmartLog.e(TAG, "Failed to get rotation: " + e.getMessage()); } return rotation; } @@ -185,7 +185,7 @@ public static Bitmap rotateBitmap(Bitmap bitmap, int angle) { try { result = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); } catch (OutOfMemoryError e) { - SmartLog.e(BitmapUtils.TAG, "Failed to rotate bitmap: " + e.getMessage()); + SmartLog.e(TAG, "Failed to rotate bitmap: " + e.getMessage()); } if (result == null) { return bitmap; diff --git a/MLKit-Sample/app/src/main/java/com/mlkit/sample/util/CommonUtils.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/util/CommonUtils.java similarity index 92% rename from MLKit-Sample/app/src/main/java/com/mlkit/sample/util/CommonUtils.java rename to MLKit-Sample/module-text/src/main/java/com/mlkit/sample/util/CommonUtils.java index 798fc8c..60e27df 100644 --- a/MLKit-Sample/app/src/main/java/com/mlkit/sample/util/CommonUtils.java +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/util/CommonUtils.java @@ -67,7 +67,7 @@ public static void handleByteBuffer(ByteBuffer src, ByteBuffer dst, try { dst.put((x + dst_y_slice), src.get(src_y_slice + srcx)); } catch (Exception e) { - Log.d(CommonUtils.TAG, "nv12_Resize Exception1" + e.getMessage()); + Log.d(TAG, "nv12_Resize Exception1" + e.getMessage()); } if ((y & 1) == 0) { @@ -78,14 +78,14 @@ public static void handleByteBuffer(ByteBuffer src, ByteBuffer dst, try { dst.put(sp, src.get(dp)); } catch (Exception e) { - Log.d(CommonUtils.TAG, "nv12_Resize Exception2" + e.getMessage()); + Log.d(TAG, "nv12_Resize Exception2" + e.getMessage()); } ++sp; ++dp; try { dst.put(sp, src.get(dp)); } catch (Exception e) { - Log.d(CommonUtils.TAG, "nv12_Resize Exception3" + e.getMessage()); + Log.d(TAG, "nv12_Resize Exception3" + e.getMessage()); } } } diff --git a/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/util/Constant.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/util/Constant.java new file mode 100644 index 0000000..9c05e12 --- /dev/null +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/util/Constant.java @@ -0,0 +1,58 @@ +/** + * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mlkit.sample.util; + +import android.graphics.Color; + +import com.mlkit.sample.R; + +public class Constant { + + public static final String POSITION_KEY = "positionkey"; + + public static final String POSITION_CN = "0"; + + public static final String POSITION_EN = "1"; + + public static final String POSITION_JA = "2"; + + public static final String POSITION_KO = "3"; + + public static final String POSITION_LA = "4"; + + public static final int GET_DATA_SUCCESS = 100; + + public static final int GET_DATA_FAILED = 101; + + public static final int SHOW_TAKE_PHOTO_BUTTON = 102; + + public static final int HIDE_TAKE_PHOTO_BUTTON = 103; + + public static final String CAMERA_FACING = "facing"; + + public static final String CLOUD_TEXT_DETECTION = "Cloud Text"; + public static final String CLOUD_DOCUMENT_TEXT_DETECTION = "Doc Text"; + public static final String MODEL_TYPE = "model_type"; + + public static final String ADD_PICTURE_TYPE = "picture_type"; + public static final String TYPE_TAKE_PHOTO = "take photo"; + public static final String TYPE_SELECT_IMAGE = "select image"; + + public static final String DEFAULT_VERSION = "1.0.3.300"; + public static final boolean IS_CHINESE = false; + +} diff --git a/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/util/FileUtils.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/util/FileUtils.java new file mode 100644 index 0000000..7fc6204 --- /dev/null +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/util/FileUtils.java @@ -0,0 +1,115 @@ +/** + * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mlkit.sample.util; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.file.Files; + +public class FileUtils { + + public static boolean isSymlink(final File file) throws IOException { + if (file == null) { + throw new NullPointerException("File must not be null"); + } + return Files.isSymbolicLink(file.toPath()); + } + + public static void deleteDirectory(final File directory) throws IOException { + if (!directory.exists()) { + return; + } + + if (!isSymlink(directory)) { + cleanDirectory(directory); + } + + if (!directory.delete()) { + final String message = "Unable to delete directory " + directory + "."; + throw new IOException(message); + } + } + + public static void forceDelete(final File file) throws IOException { + if (file.isDirectory()) { + deleteDirectory(file); + } else { + final boolean filePresent = file.exists(); + if (!file.delete()) { + if (!filePresent) { + throw new FileNotFoundException("File does not exist: " + file); + } + final String message = "Unable to delete file: " + file; + throw new IOException(message); + } + } + } + + private static File[] verifiedListFiles(final File directory) throws IOException { + if (!directory.exists()) { + final String message = directory + " does not exist"; + throw new IllegalArgumentException(message); + } + + if (!directory.isDirectory()) { + final String message = directory + " is not a directory"; + throw new IllegalArgumentException(message); + } + + final File[] files = directory.listFiles(); + if (files == null) { // null if security restricted + throw new IOException("Failed to list contents of " + directory); + } + return files; + } + + public static void cleanDirectory(final File directory) throws IOException { + final File[] files = verifiedListFiles(directory); + + IOException exception = null; + for (final File file : files) { + try { + forceDelete(file); + } catch (final IOException ioe) { + exception = ioe; + } + } + + if (null != exception) { + throw exception; + } + } + + public static boolean deleteQuietly(final File file) { + if (file == null) { + return false; + } + try { + if (file.isDirectory()) { + cleanDirectory(file); + } + } catch (final Exception ignored) { + } + + try { + return file.delete(); + } catch (final Exception ignored) { + return false; + } + } +} diff --git a/MLKit-Sample/app/src/main/java/com/mlkit/sample/util/ImageUtils.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/util/ImageUtils.java similarity index 93% rename from MLKit-Sample/app/src/main/java/com/mlkit/sample/util/ImageUtils.java rename to MLKit-Sample/module-text/src/main/java/com/mlkit/sample/util/ImageUtils.java index 76b002a..c8752d2 100644 --- a/MLKit-Sample/app/src/main/java/com/mlkit/sample/util/ImageUtils.java +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/util/ImageUtils.java @@ -62,23 +62,23 @@ public void saveToAlbum(Bitmap bitmap){ os.flush(); } catch (FileNotFoundException e) { - SmartLog.e(ImageUtils.TAG, e.getMessage()); + SmartLog.e(TAG, e.getMessage()); } catch (IOException e) { - SmartLog.e(ImageUtils.TAG, e.getMessage()); + SmartLog.e(TAG, e.getMessage()); }finally { try { if(os != null) { os.close(); } }catch (IOException e){ - SmartLog.e(ImageUtils.TAG, e.getMessage()); + SmartLog.e(TAG, e.getMessage()); } } if(file == null){ return; } - if(this.imageUtilCallBack != null) { - this.imageUtilCallBack.callSavePath(file.getAbsolutePath()); + if(imageUtilCallBack != null) { + imageUtilCallBack.callSavePath(file.getAbsolutePath()); } // Gallery refresh. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { @@ -86,7 +86,7 @@ public void saveToAlbum(Bitmap bitmap){ try { path = file.getCanonicalPath(); } catch (IOException e) { - SmartLog.e(ImageUtils.TAG, e.getMessage()); + SmartLog.e(TAG, e.getMessage()); } MediaScannerConnection.scanFile(this.context, new String[]{path}, null, new MediaScannerConnection.OnScanCompletedListener() { diff --git a/MLKit-Sample/app/src/main/java/com/mlkit/sample/util/SharedPreferencesUtil.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/util/SharedPreferencesUtil.java similarity index 67% rename from MLKit-Sample/app/src/main/java/com/mlkit/sample/util/SharedPreferencesUtil.java rename to MLKit-Sample/module-text/src/main/java/com/mlkit/sample/util/SharedPreferencesUtil.java index 554ea42..9f11466 100644 --- a/MLKit-Sample/app/src/main/java/com/mlkit/sample/util/SharedPreferencesUtil.java +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/util/SharedPreferencesUtil.java @@ -27,36 +27,36 @@ public class SharedPreferencesUtil { public SharedPreferencesUtil(Context context) { - this.mPreferences = context.getSharedPreferences(SharedPreferencesUtil.TAG, Context.MODE_PRIVATE); - this.mEditor = this.mPreferences.edit(); + mPreferences = context.getSharedPreferences(TAG, Context.MODE_PRIVATE); + mEditor = mPreferences.edit(); } public static SharedPreferencesUtil getInstance(Context context) { - if (SharedPreferencesUtil.mSharedPreferencesUtil == null) { + if (mSharedPreferencesUtil == null) { synchronized (SharedPreferencesUtil.class) { - if(SharedPreferencesUtil.mSharedPreferencesUtil == null) { - SharedPreferencesUtil.mSharedPreferencesUtil = new SharedPreferencesUtil(context); + if(mSharedPreferencesUtil == null) { + mSharedPreferencesUtil = new SharedPreferencesUtil(context); } } } - return SharedPreferencesUtil.mSharedPreferencesUtil; + return mSharedPreferencesUtil; } public void putStringValue(String key, String value) { - this.mEditor.putString(key, value); - this.mEditor.commit(); + mEditor.putString(key, value); + mEditor.commit(); } public String getStringValue(String key) { - return this.mPreferences.getString(key, Constant.POSITION_EN); + return mPreferences.getString(key, Constant.POSITION_EN); } public void putIntValue(String key, int value) { - this.mEditor.putInt(key, value); - this.mEditor.commit(); + mEditor.putInt(key, value); + mEditor.commit(); } public int getIntValue(String key) { - return this.mPreferences.getInt(key, -1); + return mPreferences.getInt(key, -1); } } diff --git a/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/util/StringUtils.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/util/StringUtils.java new file mode 100644 index 0000000..0f5e8c0 --- /dev/null +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/util/StringUtils.java @@ -0,0 +1,381 @@ +/** + * Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mlkit.sample.util; + +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class StringUtils { + private static Map letterNumberMap = new HashMap<>(); + private static Map numberLetterMap = new HashMap<>(); + + static { + letterNumberMap.put("i", "1"); + letterNumberMap.put("I", "1"); + letterNumberMap.put("o", "0"); + letterNumberMap.put("O", "0"); + letterNumberMap.put("z", "2"); + letterNumberMap.put("Z", "2"); + + numberLetterMap.put("1", "I"); + numberLetterMap.put("0", "O"); + numberLetterMap.put("2", "Z"); + numberLetterMap.put("8", "B"); + } + + /** + * Filter strings based on regular expressions + */ + + public static String filterString(String origin, String filterStr) { + if (origin == null || origin.isEmpty()) { + return ""; + } + if (filterStr == null || filterStr.isEmpty()) { + return origin; + } + + Pattern pattern = Pattern.compile(filterStr); + Matcher matcher = pattern.matcher(origin); + return matcher.replaceAll("").trim(); + } + + /** + * Get date in specified date format. + */ + public static String getCorrectDate(String origin, String splitter, int[] formatter) { + if (origin == null || origin.isEmpty()) { + return ""; + } + if (splitter == null) { + return ""; + } + + int targetLength = 0; + for (int i : formatter) { + targetLength += i; + } + + // Convert letters to numbers first. + String newStr = correctLetterToNumber(origin); + + // Filter strings, keeping only numbers and separators. + newStr = filterString(newStr, "[^0-9,.-]"); + // If the length is less than the minimum length of the date 8, return the empty string directly. + if (newStr.length() < targetLength) { + return ""; + } + + int length = formatter.length; + String[] strings = newStr.split(splitter); + + if (strings.length < 2 || strings.length > 3) { + if (splitter.equals("\\.")) { + strings = newStr.split(","); + if (strings.length < 2 || strings.length > 3) { + return ""; + } + } else { + return ""; + } + } + + // If both the length and the number of delimiters are satisfied, the result is returned directly. + if (strings.length == length && newStr.length() == (targetLength + 2)) { + return newStr; + } + + // Fill in the separator. + char target = splitter.toCharArray()[1]; + return fixMissingDelimiter(newStr, target, formatter); + } + + /** + * Completion of missing delimiters in the specified format. + */ + public static String fixMissingDelimiter(String origin, char target, int[] format) { + if (origin == null || origin.isEmpty()) { + return ""; + } + if (format == null ) { + return ""; + } + + int newCharsLen = 0; + for (int temp : format) { + newCharsLen += temp; + } + + String temp = filterString(origin, "[^0-9a-zA-Z]"); + if (temp.length() < newCharsLen) { + return ""; + } + + char[] oldChars = origin.toCharArray(); + char[] newChars = new char[newCharsLen + (format.length - 1)]; + + if (oldChars.length < newCharsLen) { + return ""; + } + + int oldIndex = 0; + int newIndex = 0; + + for (int i = 0; i < format.length; i++) { + int tmp = format[i]; + + while (tmp-- > 0) { + newChars[newIndex++] = oldChars[oldIndex++]; + } + if (i != format.length - 1) { + if (blurMatchDelimiter(oldChars[oldIndex], target)) { + oldIndex++; + if (oldIndex >= oldChars.length) { + return ""; + } + } + newChars[newIndex++] = target; + } + } + return String.valueOf(newChars); + } + + /** + * Get a string of validity in the format xxxx.xx.xx-xxxx.xx.xx. + */ + public static String getCorrectValidDate(String origin) { + if (origin == null || origin.isEmpty()) { + return ""; + } + + // Convert letters to numbers. + String newStr = correctLetterToNumber(origin); + newStr = newStr.replaceAll("\\s{1,}", " "); + String[] strings = null; + + if (newStr.split("-").length == 2) { + // Standard case, with '-' split between validity periods. + newStr = filterString(newStr, "[^0-9,.-]"); + if (newStr.length() < 18) { + return ""; + } + strings = newStr.split("-"); + } + + if (newStr.split(" ").length == 2) { + // Exception, missing separator between validity periods. + strings = newStr.split(" "); + } + + if (strings == null || strings.length != 2) { + return ""; + } + + int[] formatter = {4, 2, 2}; + String startDate = getCorrectDate(strings[0], "\\.", formatter); + String endDate = getCorrectDate(strings[1], "\\.", formatter); + if (startDate.isEmpty() || endDate.isEmpty()) { + return ""; + } + return startDate + " - " + endDate; + } + + /** + * Get the ID number of Hong Kong, Macau, Taiwan Pass. + */ + public static String getPassCardNumber(String origin) { + if (origin == null || origin.isEmpty()) { + return ""; + } + + String newStr = origin.trim(); + newStr = newStr.toUpperCase(Locale.ENGLISH); + newStr = filterString(newStr, "[^0-9A-Z<]"); + + if (newStr.length() < 27 || newStr.length() > 30) { + return ""; + } + + String[] splits = newStr.split("[<]"); + if (splits.length == 4) { + // Meet the requirements and return the results directly. + return newStr; + } + + int[] formatter = {12, 7, 7, 1}; + return fixMissingDelimiter(newStr, '<', formatter); + } + + /** + * Get the ID number of Hong Kong Resident Permanent Identity Card. + */ + public static String getHKIdCardNum(String origin) { + if (origin == null || origin.isEmpty()) { + return ""; + } + + origin = filterString(origin, "[^0-9a-zA-Z()]"); + + if (origin.length() < 10) { + return ""; + } + + // The first letter must be a letter. + String firstChar = origin.substring(0, 1); + if (!Character.isLowerCase(firstChar.charAt(0)) && !Character.isUpperCase(firstChar.charAt(0))) { + if (firstChar.equalsIgnoreCase("2")) { + firstChar = "Z"; + } else { + return ""; + } + } + + // 6 digits behind. + String number = origin.substring(1, 7); + number = correctLetterToNumber(number); + + // Finally contains (). + String firstField = origin.substring(7, 8); + String middleField = origin.substring(8, 9); + String lastField = origin.substring(9, 10); + + if (!firstField.equals("(") && !lastField.equals(")")) { + return ""; + } + if (!firstField.equals("(")) { + if (firstField.equalsIgnoreCase("C") || firstField.equalsIgnoreCase("G")) { + firstField = "("; + } else { + return ""; + } + } + + String ret = firstChar + number + firstField + middleField + lastField; + return ret.toUpperCase(Locale.ENGLISH); + } + + /** + * Get the ID number of the Homecoming Permit, Hong Kong, Macau and Taiwan have different rules. + */ + public static String getHomeCardNumber(String origin) { + if (origin == null || origin.isEmpty()) { + return ""; + } + + // Remove blank space. + origin = filterString(origin, "[\\s]"); + if (origin.length() != 8 && origin.length() != 9) { + return ""; + } + + // Determine whether the first character is a letter. + String firstLetter = origin.substring(0, 1); + if (Character.isLetter(firstLetter.charAt(0))) { + if (firstLetter.equalsIgnoreCase("H") || firstLetter.equalsIgnoreCase("M")) { + if (origin.length() < 9) { + return ""; + } + firstLetter = firstLetter.toUpperCase(Locale.ENGLISH); + String number = origin.substring(1, 9); + // Keep numbers only. + number = filterString(number, "[^0-9]"); + number = correctLetterToNumber(number); + if (number.length() != 8) { + return ""; + } + return firstLetter + number; + } else { + return ""; + } + } + + // Taiwan cell card has no initial, only 8 digits. + if (origin.length() != 8) { + return ""; + } + + String number = origin.substring(0, 8); + number = filterString(number, "[^0-9]"); + number = correctLetterToNumber(number); + if (number.length() != 8) { + return ""; + } + return number; + } + + /** + * Letters corrected to numbers. + */ + public static String correctLetterToNumber(String str) { + if (str == null || str.isEmpty()) { + return ""; + } + char[] chars = str.toCharArray(); + + int length = chars.length; + for (int index = 0; index < length; index++) { + String tmp = letterNumberMap.get(Character.toString(chars[index])); + if (tmp != null) { + char[] tempChars = tmp.toCharArray(); + chars[index] = tempChars[0]; + } + } + + return String.valueOf(chars); + } + + /** + * Numbers corrected to letters. + */ + public static String correctNumberToLetter(String str) { + if (str == null || str.isEmpty()) { + return ""; + } + char[] chars = str.toCharArray(); + + int length = chars.length; + for (int index = 0; index < length; index++) { + String tmp = numberLetterMap.get(Character.toString(chars[index])); + if (tmp != null) { + char[] tempChars = tmp.toCharArray(); + chars[index] = tempChars[0]; + } + } + + return String.valueOf(chars); + } + + /** + * Fuzzy match delimiter. + */ + private static boolean blurMatchDelimiter(char origin, char target) { + if (target == '.') { + if (origin == '.' || origin == ',') { + return true; + } + } + if (target == '<') { + if (origin == 'K' || origin == 'X') { + return true; + } + } + return origin == target; + } +} \ No newline at end of file diff --git a/MLKit-Sample/app/src/main/java/com/mlkit/sample/views/SwitchButton.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/views/SwitchButton.java similarity index 99% rename from MLKit-Sample/app/src/main/java/com/mlkit/sample/views/SwitchButton.java rename to MLKit-Sample/module-text/src/main/java/com/mlkit/sample/views/SwitchButton.java index 42dd4ca..11bb039 100644 --- a/MLKit-Sample/app/src/main/java/com/mlkit/sample/views/SwitchButton.java +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/views/SwitchButton.java @@ -20,7 +20,6 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; -import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.util.AttributeSet; diff --git a/MLKit-Sample/app/src/main/java/com/mlkit/sample/views/graphic/BaseGraphic.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/views/graphic/BaseGraphic.java similarity index 100% rename from MLKit-Sample/app/src/main/java/com/mlkit/sample/views/graphic/BaseGraphic.java rename to MLKit-Sample/module-text/src/main/java/com/mlkit/sample/views/graphic/BaseGraphic.java diff --git a/MLKit-Sample/app/src/main/java/com/mlkit/sample/views/graphic/CameraImageGraphic.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/views/graphic/CameraImageGraphic.java similarity index 100% rename from MLKit-Sample/app/src/main/java/com/mlkit/sample/views/graphic/CameraImageGraphic.java rename to MLKit-Sample/module-text/src/main/java/com/mlkit/sample/views/graphic/CameraImageGraphic.java diff --git a/MLKit-Sample/app/src/main/java/com/mlkit/sample/views/graphic/LocalTextGraphic.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/views/graphic/LocalTextGraphic.java similarity index 100% rename from MLKit-Sample/app/src/main/java/com/mlkit/sample/views/graphic/LocalTextGraphic.java rename to MLKit-Sample/module-text/src/main/java/com/mlkit/sample/views/graphic/LocalTextGraphic.java index eb8aa12..fc6f38b 100644 --- a/MLKit-Sample/app/src/main/java/com/mlkit/sample/views/graphic/LocalTextGraphic.java +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/views/graphic/LocalTextGraphic.java @@ -22,8 +22,8 @@ import android.graphics.Path; import android.graphics.Point; -import com.mlkit.sample.views.overlay.GraphicOverlay; import com.huawei.hms.mlsdk.text.MLText; +import com.mlkit.sample.views.overlay.GraphicOverlay; public class LocalTextGraphic extends BaseGraphic { diff --git a/MLKit-Sample/app/src/main/java/com/mlkit/sample/views/overlay/GraphicOverlay.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/views/overlay/GraphicOverlay.java similarity index 100% rename from MLKit-Sample/app/src/main/java/com/mlkit/sample/views/overlay/GraphicOverlay.java rename to MLKit-Sample/module-text/src/main/java/com/mlkit/sample/views/overlay/GraphicOverlay.java diff --git a/MLKit-Sample/app/src/main/java/com/mlkit/sample/views/overlay/ZoomImageView.java b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/views/overlay/ZoomImageView.java similarity index 99% rename from MLKit-Sample/app/src/main/java/com/mlkit/sample/views/overlay/ZoomImageView.java rename to MLKit-Sample/module-text/src/main/java/com/mlkit/sample/views/overlay/ZoomImageView.java index c66ac49..7f36597 100644 --- a/MLKit-Sample/app/src/main/java/com/mlkit/sample/views/overlay/ZoomImageView.java +++ b/MLKit-Sample/module-text/src/main/java/com/mlkit/sample/views/overlay/ZoomImageView.java @@ -37,7 +37,6 @@ import android.os.Bundle; import android.os.Parcelable; import android.util.AttributeSet; -import android.util.Log; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.ScaleGestureDetector; diff --git a/MLKit-Sample/app/src/main/res/anim/anim_in.xml b/MLKit-Sample/module-text/src/main/res/anim/anim_in.xml similarity index 81% rename from MLKit-Sample/app/src/main/res/anim/anim_in.xml rename to MLKit-Sample/module-text/src/main/res/anim/anim_in.xml index 57dadb4..125637b 100644 --- a/MLKit-Sample/app/src/main/res/anim/anim_in.xml +++ b/MLKit-Sample/module-text/src/main/res/anim/anim_in.xml @@ -4,5 +4,6 @@ + android:duration="300" + /> \ No newline at end of file diff --git a/MLKit-Sample/app/src/main/res/drawable-xxhdpi/add_image.png b/MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/add_image.png similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable-xxhdpi/add_image.png rename to MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/add_image.png diff --git a/MLKit-Sample/app/src/main/res/drawable-xxhdpi/black_back.png b/MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/black_back.png similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable-xxhdpi/black_back.png rename to MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/black_back.png diff --git a/MLKit-Sample/app/src/main/res/drawable-xxhdpi/close.png b/MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/close.png similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable-xxhdpi/close.png rename to MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/close.png diff --git a/MLKit-Sample/app/src/main/res/drawable-xxhdpi/facingswitch.png b/MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/facingswitch.png similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable-xxhdpi/facingswitch.png rename to MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/facingswitch.png diff --git a/MLKit-Sample/app/src/main/res/drawable-xxhdpi/facingswitch_stroke.png b/MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/facingswitch_stroke.png similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable-xxhdpi/facingswitch_stroke.png rename to MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/facingswitch_stroke.png diff --git a/MLKit-Sample/app/src/main/res/drawable-xxhdpi/icon.png b/MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/icon.png similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable-xxhdpi/icon.png rename to MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/icon.png diff --git a/MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/icon_bcr_background.png b/MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/icon_bcr_background.png new file mode 100644 index 0000000..e80b108 Binary files /dev/null and b/MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/icon_bcr_background.png differ diff --git a/MLKit-Sample/app/src/main/res/drawable-xxhdpi/icon_idcard_addto.png b/MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/icon_card_add.png similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable-xxhdpi/icon_idcard_addto.png rename to MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/icon_card_add.png diff --git a/MLKit-Sample/app/src/main/res/drawable-xxhdpi/icon_idcard_off.png b/MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/icon_card_off.png similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable-xxhdpi/icon_idcard_off.png rename to MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/icon_card_off.png diff --git a/MLKit-Sample/app/src/main/res/drawable-xxhdpi/icon_cut.png b/MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/icon_cut.png similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable-xxhdpi/icon_cut.png rename to MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/icon_cut.png diff --git a/MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/icon_gcr_background.png b/MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/icon_gcr_background.png new file mode 100644 index 0000000..a75d9e9 Binary files /dev/null and b/MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/icon_gcr_background.png differ diff --git a/MLKit-Sample/app/src/main/res/drawable-xxhdpi/icon_idcard_nationalemblem.png b/MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/icon_idcard_nationalemblem.png similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable-xxhdpi/icon_idcard_nationalemblem.png rename to MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/icon_idcard_nationalemblem.png diff --git a/MLKit-Sample/app/src/main/res/drawable-xxhdpi/icon_idcard_portrait.png b/MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/icon_idcard_portrait.png similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable-xxhdpi/icon_idcard_portrait.png rename to MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/icon_idcard_portrait.png diff --git a/MLKit-Sample/app/src/main/res/drawable-xxhdpi/icon_new.png b/MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/icon_new.png similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable-xxhdpi/icon_new.png rename to MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/icon_new.png diff --git a/MLKit-Sample/app/src/main/res/drawable-xxhdpi/icons_background.png b/MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/icons_background.png similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable-xxhdpi/icons_background.png rename to MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/icons_background.png diff --git a/MLKit-Sample/app/src/main/res/drawable-xxhdpi/take_picture.png b/MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/take_picture.png similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable-xxhdpi/take_picture.png rename to MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/take_picture.png diff --git a/MLKit-Sample/app/src/main/res/drawable-xxhdpi/take_picture_solid.png b/MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/take_picture_solid.png similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable-xxhdpi/take_picture_solid.png rename to MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/take_picture_solid.png diff --git a/MLKit-Sample/app/src/main/res/drawable-xxhdpi/take_picture_stroke.png b/MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/take_picture_stroke.png similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable-xxhdpi/take_picture_stroke.png rename to MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/take_picture_stroke.png diff --git a/MLKit-Sample/app/src/main/res/drawable-xxhdpi/translate_switch.png b/MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/translate_switch.png similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable-xxhdpi/translate_switch.png rename to MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/translate_switch.png diff --git a/MLKit-Sample/app/src/main/res/drawable-xxhdpi/white_back.png b/MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/white_back.png similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable-xxhdpi/white_back.png rename to MLKit-Sample/module-text/src/main/res/drawable-xxhdpi/white_back.png diff --git a/MLKit-Sample/module-text/src/main/res/drawable-xxxhdpi/icon_aft.png b/MLKit-Sample/module-text/src/main/res/drawable-xxxhdpi/icon_aft.png new file mode 100644 index 0000000..a9c320a Binary files /dev/null and b/MLKit-Sample/module-text/src/main/res/drawable-xxxhdpi/icon_aft.png differ diff --git a/MLKit-Sample/module-text/src/main/res/drawable-xxxhdpi/icon_bcr.png b/MLKit-Sample/module-text/src/main/res/drawable-xxxhdpi/icon_bcr.png new file mode 100644 index 0000000..8bcba91 Binary files /dev/null and b/MLKit-Sample/module-text/src/main/res/drawable-xxxhdpi/icon_bcr.png differ diff --git a/MLKit-Sample/module-text/src/main/res/drawable-xxxhdpi/icon_document.png b/MLKit-Sample/module-text/src/main/res/drawable-xxxhdpi/icon_document.png new file mode 100644 index 0000000..ac4739c Binary files /dev/null and b/MLKit-Sample/module-text/src/main/res/drawable-xxxhdpi/icon_document.png differ diff --git a/MLKit-Sample/module-text/src/main/res/drawable-xxxhdpi/icon_gcr.png b/MLKit-Sample/module-text/src/main/res/drawable-xxxhdpi/icon_gcr.png new file mode 100644 index 0000000..1c699fe Binary files /dev/null and b/MLKit-Sample/module-text/src/main/res/drawable-xxxhdpi/icon_gcr.png differ diff --git a/MLKit-Sample/app/src/main/res/drawable-xxxhdpi/icon_idcard.png b/MLKit-Sample/module-text/src/main/res/drawable-xxxhdpi/icon_icr.png similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable-xxxhdpi/icon_idcard.png rename to MLKit-Sample/module-text/src/main/res/drawable-xxxhdpi/icon_icr.png diff --git a/MLKit-Sample/module-text/src/main/res/drawable-xxxhdpi/icon_idcard.png b/MLKit-Sample/module-text/src/main/res/drawable-xxxhdpi/icon_idcard.png new file mode 100644 index 0000000..a2e2865 Binary files /dev/null and b/MLKit-Sample/module-text/src/main/res/drawable-xxxhdpi/icon_idcard.png differ diff --git a/MLKit-Sample/app/src/main/res/drawable-xxxhdpi/icon_logo.png b/MLKit-Sample/module-text/src/main/res/drawable-xxxhdpi/icon_logo.png similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable-xxxhdpi/icon_logo.png rename to MLKit-Sample/module-text/src/main/res/drawable-xxxhdpi/icon_logo.png diff --git a/MLKit-Sample/app/src/main/res/drawable-xxxhdpi/icon_text.png b/MLKit-Sample/module-text/src/main/res/drawable-xxxhdpi/icon_text.png similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable-xxxhdpi/icon_text.png rename to MLKit-Sample/module-text/src/main/res/drawable-xxxhdpi/icon_text.png diff --git a/MLKit-Sample/app/src/main/res/drawable-xxxhdpi/icon_translate.png b/MLKit-Sample/module-text/src/main/res/drawable-xxxhdpi/icon_translate.png similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable-xxxhdpi/icon_translate.png rename to MLKit-Sample/module-text/src/main/res/drawable-xxxhdpi/icon_translate.png diff --git a/MLKit-Sample/app/src/main/res/drawable-xxxhdpi/swich_slider_new.png b/MLKit-Sample/module-text/src/main/res/drawable-xxxhdpi/swich_slider_new.png similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable-xxxhdpi/swich_slider_new.png rename to MLKit-Sample/module-text/src/main/res/drawable-xxxhdpi/swich_slider_new.png diff --git a/MLKit-Sample/app/src/main/res/drawable/app_loading001.webp b/MLKit-Sample/module-text/src/main/res/drawable/app_loading001.webp similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable/app_loading001.webp rename to MLKit-Sample/module-text/src/main/res/drawable/app_loading001.webp diff --git a/MLKit-Sample/app/src/main/res/drawable/app_loading002.webp b/MLKit-Sample/module-text/src/main/res/drawable/app_loading002.webp similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable/app_loading002.webp rename to MLKit-Sample/module-text/src/main/res/drawable/app_loading002.webp diff --git a/MLKit-Sample/app/src/main/res/drawable/app_loading003.webp b/MLKit-Sample/module-text/src/main/res/drawable/app_loading003.webp similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable/app_loading003.webp rename to MLKit-Sample/module-text/src/main/res/drawable/app_loading003.webp diff --git a/MLKit-Sample/app/src/main/res/drawable/app_loading004.webp b/MLKit-Sample/module-text/src/main/res/drawable/app_loading004.webp similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable/app_loading004.webp rename to MLKit-Sample/module-text/src/main/res/drawable/app_loading004.webp diff --git a/MLKit-Sample/app/src/main/res/drawable/app_loading005.webp b/MLKit-Sample/module-text/src/main/res/drawable/app_loading005.webp similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable/app_loading005.webp rename to MLKit-Sample/module-text/src/main/res/drawable/app_loading005.webp diff --git a/MLKit-Sample/app/src/main/res/drawable/app_loading006.webp b/MLKit-Sample/module-text/src/main/res/drawable/app_loading006.webp similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable/app_loading006.webp rename to MLKit-Sample/module-text/src/main/res/drawable/app_loading006.webp diff --git a/MLKit-Sample/app/src/main/res/drawable/app_loading007.webp b/MLKit-Sample/module-text/src/main/res/drawable/app_loading007.webp similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable/app_loading007.webp rename to MLKit-Sample/module-text/src/main/res/drawable/app_loading007.webp diff --git a/MLKit-Sample/app/src/main/res/drawable/app_loading008.webp b/MLKit-Sample/module-text/src/main/res/drawable/app_loading008.webp similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable/app_loading008.webp rename to MLKit-Sample/module-text/src/main/res/drawable/app_loading008.webp diff --git a/MLKit-Sample/app/src/main/res/drawable/app_loading009.webp b/MLKit-Sample/module-text/src/main/res/drawable/app_loading009.webp similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable/app_loading009.webp rename to MLKit-Sample/module-text/src/main/res/drawable/app_loading009.webp diff --git a/MLKit-Sample/app/src/main/res/drawable/app_loading010.webp b/MLKit-Sample/module-text/src/main/res/drawable/app_loading010.webp similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable/app_loading010.webp rename to MLKit-Sample/module-text/src/main/res/drawable/app_loading010.webp diff --git a/MLKit-Sample/app/src/main/res/drawable/app_loading011.webp b/MLKit-Sample/module-text/src/main/res/drawable/app_loading011.webp similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable/app_loading011.webp rename to MLKit-Sample/module-text/src/main/res/drawable/app_loading011.webp diff --git a/MLKit-Sample/app/src/main/res/drawable/app_loading012.webp b/MLKit-Sample/module-text/src/main/res/drawable/app_loading012.webp similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable/app_loading012.webp rename to MLKit-Sample/module-text/src/main/res/drawable/app_loading012.webp diff --git a/MLKit-Sample/app/src/main/res/drawable/app_loading013.webp b/MLKit-Sample/module-text/src/main/res/drawable/app_loading013.webp similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable/app_loading013.webp rename to MLKit-Sample/module-text/src/main/res/drawable/app_loading013.webp diff --git a/MLKit-Sample/app/src/main/res/drawable/app_loading014.webp b/MLKit-Sample/module-text/src/main/res/drawable/app_loading014.webp similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable/app_loading014.webp rename to MLKit-Sample/module-text/src/main/res/drawable/app_loading014.webp diff --git a/MLKit-Sample/app/src/main/res/drawable/bg_edit_text.xml b/MLKit-Sample/module-text/src/main/res/drawable/bg_edit_text.xml similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable/bg_edit_text.xml rename to MLKit-Sample/module-text/src/main/res/drawable/bg_edit_text.xml diff --git a/MLKit-Sample/app/src/main/res/drawable/btn_back.xml b/MLKit-Sample/module-text/src/main/res/drawable/btn_back.xml similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable/btn_back.xml rename to MLKit-Sample/module-text/src/main/res/drawable/btn_back.xml diff --git a/MLKit-Sample/module-text/src/main/res/drawable/btn_gray_back.xml b/MLKit-Sample/module-text/src/main/res/drawable/btn_gray_back.xml new file mode 100644 index 0000000..9a75b95 --- /dev/null +++ b/MLKit-Sample/module-text/src/main/res/drawable/btn_gray_back.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/MLKit-Sample/app/src/main/res/drawable/button_circle_background.xml b/MLKit-Sample/module-text/src/main/res/drawable/button_circle_background.xml similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable/button_circle_background.xml rename to MLKit-Sample/module-text/src/main/res/drawable/button_circle_background.xml diff --git a/MLKit-Sample/app/src/main/res/drawable/dialog_background.xml b/MLKit-Sample/module-text/src/main/res/drawable/dialog_background.xml similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable/dialog_background.xml rename to MLKit-Sample/module-text/src/main/res/drawable/dialog_background.xml diff --git a/MLKit-Sample/app/src/main/res/drawable/logo_circle_background.xml b/MLKit-Sample/module-text/src/main/res/drawable/logo_circle_background.xml similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable/logo_circle_background.xml rename to MLKit-Sample/module-text/src/main/res/drawable/logo_circle_background.xml diff --git a/MLKit-Sample/module-text/src/main/res/drawable/progress_background.xml b/MLKit-Sample/module-text/src/main/res/drawable/progress_background.xml new file mode 100644 index 0000000..a16afe5 --- /dev/null +++ b/MLKit-Sample/module-text/src/main/res/drawable/progress_background.xml @@ -0,0 +1,22 @@ + + + +    + + + + diff --git a/MLKit-Sample/app/src/main/res/drawable/progress_drawable_white.xml b/MLKit-Sample/module-text/src/main/res/drawable/progress_drawable_white.xml similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable/progress_drawable_white.xml rename to MLKit-Sample/module-text/src/main/res/drawable/progress_drawable_white.xml diff --git a/MLKit-Sample/module-text/src/main/res/drawable/record_dailog_background.xml b/MLKit-Sample/module-text/src/main/res/drawable/record_dailog_background.xml new file mode 100644 index 0000000..03e8612 --- /dev/null +++ b/MLKit-Sample/module-text/src/main/res/drawable/record_dailog_background.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/MLKit-Sample/app/src/main/res/drawable/rn_dashed_box.xml b/MLKit-Sample/module-text/src/main/res/drawable/rn_dashed_box.xml similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable/rn_dashed_box.xml rename to MLKit-Sample/module-text/src/main/res/drawable/rn_dashed_box.xml diff --git a/MLKit-Sample/app/src/main/res/drawable/text_selector.xml b/MLKit-Sample/module-text/src/main/res/drawable/text_selector.xml similarity index 100% rename from MLKit-Sample/app/src/main/res/drawable/text_selector.xml rename to MLKit-Sample/module-text/src/main/res/drawable/text_selector.xml diff --git a/MLKit-Sample/module-text/src/main/res/layout-land/activity_start.xml b/MLKit-Sample/module-text/src/main/res/layout-land/activity_start.xml new file mode 100644 index 0000000..fa48ef5 --- /dev/null +++ b/MLKit-Sample/module-text/src/main/res/layout-land/activity_start.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + diff --git a/MLKit-Sample/app/src/main/res/layout-land/activity_text_recognition.xml b/MLKit-Sample/module-text/src/main/res/layout-land/activity_text_recognition.xml similarity index 100% rename from MLKit-Sample/app/src/main/res/layout-land/activity_text_recognition.xml rename to MLKit-Sample/module-text/src/main/res/layout-land/activity_text_recognition.xml diff --git a/MLKit-Sample/module-text/src/main/res/layout/activity_bank_card_recognition.xml b/MLKit-Sample/module-text/src/main/res/layout/activity_bank_card_recognition.xml new file mode 100644 index 0000000..7ef3787 --- /dev/null +++ b/MLKit-Sample/module-text/src/main/res/layout/activity_bank_card_recognition.xml @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MLKit-Sample/module-text/src/main/res/layout/activity_general_card_recognition.xml b/MLKit-Sample/module-text/src/main/res/layout/activity_general_card_recognition.xml new file mode 100644 index 0000000..711fbce --- /dev/null +++ b/MLKit-Sample/module-text/src/main/res/layout/activity_general_card_recognition.xml @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MLKit-Sample/app/src/main/res/layout/activity_idcard_recognition.xml b/MLKit-Sample/module-text/src/main/res/layout/activity_idcard_recognition.xml similarity index 74% rename from MLKit-Sample/app/src/main/res/layout/activity_idcard_recognition.xml rename to MLKit-Sample/module-text/src/main/res/layout/activity_idcard_recognition.xml index 457e031..8b3da29 100644 --- a/MLKit-Sample/app/src/main/res/layout/activity_idcard_recognition.xml +++ b/MLKit-Sample/module-text/src/main/res/layout/activity_idcard_recognition.xml @@ -26,7 +26,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" - android:text="@string/idcard_recognition_s" + android:text="@string/icr_s" android:textColor="@color/secondary_text_color" android:textSize="17sp" /> @@ -35,7 +35,6 @@ android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="right" - android:visibility="gone" android:layout_marginRight="15dp" android:orientation="horizontal"> @@ -59,39 +58,14 @@ - - - - - - - @@ -107,14 +81,12 @@ android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginStart="@dimen/margin_l" - android:layout_marginLeft="@dimen/margin_l" android:layout_marginTop="@dimen/margin_l" android:layout_marginEnd="@dimen/margin_l" - android:layout_marginRight="@dimen/margin_l" android:fontFamily="HwChinese-regular" android:gravity="center_horizontal" - android:text="@string/rn_eid_upload_self_photo" - android:textColor="?android:attr/textColorPrimary" + android:text="@string/icr_upload_self_photo" + android:textColor="@color/text_color" android:textSize="15sp" /> @@ -131,7 +103,6 @@ android:layout_width="170dp" android:layout_height="108dp" android:layout_marginStart="35dp" - android:layout_marginLeft="35dp" android:layout_marginTop="21dp" android:adjustViewBounds="true" android:src="@drawable/icon_idcard_portrait" /> @@ -160,7 +131,7 @@ android:layout_height="40dp" android:layout_gravity="center_horizontal" android:gravity="center_horizontal" - android:src="@drawable/icon_idcard_addto" /> + android:src="@drawable/icon_card_add" /> @@ -186,12 +155,10 @@ android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:layout_marginStart="12dp" - android:layout_marginLeft="12dp" android:layout_marginEnd="12dp" - android:layout_marginRight="12dp" android:fontFamily="HwChinese-regular" android:gravity="center_horizontal" - android:text="@string/rn_eid_hint_upload_valid_photo" + android:text="@string/icr_hint_upload_valid_photo" android:textColor="@color/color_red_card" android:textSize="12sp" android:visibility="gone" /> @@ -205,7 +172,7 @@ android:layout_marginTop="4dp" android:layout_marginEnd="4dp" android:layout_marginRight="4dp" - android:src="@drawable/icon_idcard_off" + android:src="@drawable/icon_card_off" android:visibility="gone" /> @@ -215,13 +182,11 @@ android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginStart="@dimen/margin_l" - android:layout_marginLeft="@dimen/margin_l" android:layout_marginTop="@dimen/margin_m" android:layout_marginEnd="@dimen/margin_l" - android:layout_marginRight="@dimen/margin_l" android:fontFamily="HwChinese-regular" android:gravity="center_horizontal" - android:text="@string/rn_eid_hint_image_not_complete" + android:text="@string/icr_hint_image_not_complete" android:textColor="@color/color_red_card" android:textSize="12sp" android:visibility="gone" /> @@ -230,7 +195,7 @@ android:layout_width="240dp" android:layout_height="151dp" android:layout_gravity="center_horizontal" - android:layout_marginTop="@dimen/idcard_result_margin" + android:layout_marginTop="@dimen/icr_result_margin" android:background="@drawable/rn_dashed_box" android:gravity="center_horizontal"> @@ -267,7 +232,7 @@ android:layout_height="40dp" android:layout_gravity="center_horizontal" android:gravity="center_horizontal" - android:src="@drawable/icon_idcard_addto" /> + android:src="@drawable/icon_card_add" /> @@ -298,7 +261,7 @@ android:layout_marginRight="12dp" android:fontFamily="HwChinese-regular" android:gravity="center_horizontal" - android:text="@string/rn_eid_hint_upload_valid_photo" + android:text="@string/icr_hint_upload_valid_photo" android:textColor="@color/color_red_card" android:textSize="12sp" android:visibility="gone" /> @@ -312,40 +275,21 @@ android:layout_marginTop="4dp" android:layout_marginEnd="4dp" android:layout_marginRight="4dp" - android:src="@drawable/icon_idcard_off" + android:src="@drawable/icon_card_off" android:visibility="gone" /> - - @@ -356,23 +300,20 @@ android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginStart="24dp" - android:layout_marginLeft="24dp" - android:layout_marginTop="@dimen/idcard_result_margin" + android:layout_marginTop="@dimen/icr_result_margin" android:layout_marginEnd="24dp" - android:layout_marginRight="24dp" android:fontFamily="HwChinese-medium" - android:text="@string/rn_eid_take_origin_card" - android:textColor="?android:attr/textColorPrimary" + android:text="@string/recognition_results" + android:textColor="@color/text_color" android:textSize="16sp" /> - + + android:layout_marginStart="@dimen/icr_margin" + android:layout_marginTop="@dimen/icr_result_margin" + android:layout_marginEnd="@dimen/icr_margin" + android:layout_marginRight="@dimen/icr_margin"> - - + android:textSize="12sp"> diff --git a/MLKit-Sample/app/src/main/res/layout/activity_remote_detection.xml b/MLKit-Sample/module-text/src/main/res/layout/activity_remote_detection.xml similarity index 96% rename from MLKit-Sample/app/src/main/res/layout/activity_remote_detection.xml rename to MLKit-Sample/module-text/src/main/res/layout/activity_remote_detection.xml index a7e9377..311dc7c 100644 --- a/MLKit-Sample/app/src/main/res/layout/activity_remote_detection.xml +++ b/MLKit-Sample/module-text/src/main/res/layout/activity_remote_detection.xml @@ -9,8 +9,7 @@ + android:layout_height="@dimen/toolbar_height"> - + android:background="@color/white"> + android:textSize="@dimen/toolbar_back_size" /> + android:textSize="@dimen/toolbar_title_size" /> @@ -55,7 +53,7 @@ android:text="@string/versions" android:textColor="@color/secondary_text_color" android:textSize="16sp" /> -s + - + + diff --git a/MLKit-Sample/module-text/src/main/res/layout/activity_start.xml b/MLKit-Sample/module-text/src/main/res/layout/activity_start.xml new file mode 100644 index 0000000..492b69c --- /dev/null +++ b/MLKit-Sample/module-text/src/main/res/layout/activity_start.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + diff --git a/MLKit-Sample/app/src/main/res/layout/activity_text_recognition.xml b/MLKit-Sample/module-text/src/main/res/layout/activity_text_recognition.xml similarity index 71% rename from MLKit-Sample/app/src/main/res/layout/activity_text_recognition.xml rename to MLKit-Sample/module-text/src/main/res/layout/activity_text_recognition.xml index 777007b..272f42c 100644 --- a/MLKit-Sample/app/src/main/res/layout/activity_text_recognition.xml +++ b/MLKit-Sample/module-text/src/main/res/layout/activity_text_recognition.xml @@ -24,45 +24,20 @@ android:layout_alignParentBottom="true" /> - - - - - - - - - @@ -100,8 +75,8 @@ diff --git a/MLKit-Sample/app/src/main/res/layout/dialog.xml b/MLKit-Sample/module-text/src/main/res/layout/dialog.xml similarity index 100% rename from MLKit-Sample/app/src/main/res/layout/dialog.xml rename to MLKit-Sample/module-text/src/main/res/layout/dialog.xml diff --git a/MLKit-Sample/app/src/main/res/layout/dialog_add_picture.xml b/MLKit-Sample/module-text/src/main/res/layout/dialog_add_picture.xml similarity index 83% rename from MLKit-Sample/app/src/main/res/layout/dialog_add_picture.xml rename to MLKit-Sample/module-text/src/main/res/layout/dialog_add_picture.xml index 43913a5..4b5f59b 100644 --- a/MLKit-Sample/app/src/main/res/layout/dialog_add_picture.xml +++ b/MLKit-Sample/module-text/src/main/res/layout/dialog_add_picture.xml @@ -12,7 +12,7 @@ android:gravity="center" android:text="@string/take_photo" android:textColor="@drawable/text_selector" - android:textSize="@dimen/setting_languagetext_size"> + android:textSize="@dimen/dialog_text_size"> @@ -23,19 +23,19 @@ android:gravity="center" android:text="@string/select_from_album" android:textColor="@drawable/text_selector" - android:textSize="@dimen/setting_languagetext_size"> + android:textSize="@dimen/dialog_text_size"> + android:textSize="@dimen/dialog_text_size"> \ No newline at end of file diff --git a/MLKit-Sample/app/src/main/res/layout/dialog_language_setting.xml b/MLKit-Sample/module-text/src/main/res/layout/dialog_language_setting.xml similarity index 86% rename from MLKit-Sample/app/src/main/res/layout/dialog_language_setting.xml rename to MLKit-Sample/module-text/src/main/res/layout/dialog_language_setting.xml index fa31052..e1ce679 100644 --- a/MLKit-Sample/app/src/main/res/layout/dialog_language_setting.xml +++ b/MLKit-Sample/module-text/src/main/res/layout/dialog_language_setting.xml @@ -7,7 +7,7 @@ android:id="@+id/english" android:layout_width="match_parent" android:layout_height="@dimen/start_icon_width" - android:textSize="@dimen/setting_languagetext_size" + android:textSize="@dimen/dialog_text_size" android:gravity="center" android:textColor="@drawable/text_selector" android:text="@string/english_choose"> @@ -18,7 +18,7 @@ android:id="@+id/simple_cn" android:layout_width="match_parent" android:layout_height="@dimen/start_icon_width" - android:textSize="@dimen/setting_languagetext_size" + android:textSize="@dimen/dialog_text_size" android:gravity="center" android:textColor="@drawable/text_selector" android:text="@string/simplified_chinese"> @@ -29,7 +29,7 @@ android:id="@+id/japanese" android:layout_width="match_parent" android:layout_height="@dimen/start_icon_width" - android:textSize="@dimen/setting_languagetext_size" + android:textSize="@dimen/dialog_text_size" android:gravity="center" android:textColor="@drawable/text_selector" android:text="@string/japanese_choose"> @@ -40,7 +40,7 @@ android:id="@+id/korean" android:layout_width="match_parent" android:layout_height="@dimen/start_icon_width" - android:textSize="@dimen/setting_languagetext_size" + android:textSize="@dimen/dialog_text_size" android:gravity="center" android:textColor="@drawable/text_selector" android:text="@string/korean_choose"> @@ -51,7 +51,7 @@ android:id="@+id/latin" android:layout_width="match_parent" android:layout_height="@dimen/start_icon_width" - android:textSize="@dimen/setting_languagetext_size" + android:textSize="@dimen/dialog_text_size" android:gravity="center" android:textColor="@drawable/text_selector" android:text="@string/latin_choose"> diff --git a/MLKit-Sample/app/src/main/res/layout/gridview_item.xml b/MLKit-Sample/module-text/src/main/res/layout/gridview_item.xml similarity index 81% rename from MLKit-Sample/app/src/main/res/layout/gridview_item.xml rename to MLKit-Sample/module-text/src/main/res/layout/gridview_item.xml index 7f61656..ff1bc8d 100644 --- a/MLKit-Sample/app/src/main/res/layout/gridview_item.xml +++ b/MLKit-Sample/module-text/src/main/res/layout/gridview_item.xml @@ -2,7 +2,7 @@ + android:layout_marginTop="50dp"> - + - 24dp - 8dp + 24dp + 8dp 160dp 140dp 30dp diff --git a/MLKit-Sample/app/src/main/res/values-1280x720/dimens.xml b/MLKit-Sample/module-text/src/main/res/values-1280x720/dimens.xml similarity index 64% rename from MLKit-Sample/app/src/main/res/values-1280x720/dimens.xml rename to MLKit-Sample/module-text/src/main/res/values-1280x720/dimens.xml index 2ae3544..b392dda 100644 --- a/MLKit-Sample/app/src/main/res/values-1280x720/dimens.xml +++ b/MLKit-Sample/module-text/src/main/res/values-1280x720/dimens.xml @@ -1,6 +1,6 @@ - 24dp - 10dp + 24dp + 10dp 200dp 180dp 50dp diff --git a/MLKit-Sample/app/src/main/res/values-1920x1080/dimens.xml b/MLKit-Sample/module-text/src/main/res/values-1920x1080/dimens.xml similarity index 64% rename from MLKit-Sample/app/src/main/res/values-1920x1080/dimens.xml rename to MLKit-Sample/module-text/src/main/res/values-1920x1080/dimens.xml index efbe52c..f8332eb 100644 --- a/MLKit-Sample/app/src/main/res/values-1920x1080/dimens.xml +++ b/MLKit-Sample/module-text/src/main/res/values-1920x1080/dimens.xml @@ -1,6 +1,6 @@ - 24dp - 24dp + 24dp + 24dp 250dp 230dp 70dp diff --git a/MLKit-Sample/module-text/src/main/res/values-zh-rCN/strings.xml b/MLKit-Sample/module-text/src/main/res/values-zh-rCN/strings.xml new file mode 100644 index 0000000..07bb051 --- /dev/null +++ b/MLKit-Sample/module-text/src/main/res/values-zh-rCN/strings.xml @@ -0,0 +1,71 @@ + + + ML Kit + 示例应用需要相机和存储权限 + + OK + 设置 + 取消 + + 云端文字识别 + 从相册选择图片 + 视频流 + 拍照 + 身份证识别 + + 版本号: + 简体中文 + 英文 + 日文 + 韩文 + 拉丁文 + 获取数据失败 + 加载中… + + + 文档识别 + 文字识别 + 身份证识别 + 银行卡识别 + 通用卡证识别 + + 文本翻译 + 银行卡识别 + 通用卡证识别 + 文字识别 + 文档识别 + 所有 + 敬请期待 + 返回 + 翻译 + 语种识别 + 耗时: + 0 字符 + 机器学习 + + + "请上传本人身份证照片" + "上传人像面" + "上传国徽面" + "请上传有效身份证照片" + "智能检测识别到图片可能存在部分遮挡,如果清晰可见请忽略" + "我们将依法保护您的个人信息安全" + "检测结果" + 注:只用于中国大陆地区 + 端侧 + 云侧 + + "请上传卡证" + "上传卡证" + 港澳台通行证 + "香港身份证" + 港澳台居民来往大陆通行证 + 点击切换 + "正在识别,请对齐边缘" + "正在拍照,请对齐边缘" + + + "请上传银行卡" + "上传银行卡" + + diff --git a/MLKit-Sample/app/src/main/res/values/attrs.xml b/MLKit-Sample/module-text/src/main/res/values/attrs.xml similarity index 100% rename from MLKit-Sample/app/src/main/res/values/attrs.xml rename to MLKit-Sample/module-text/src/main/res/values/attrs.xml diff --git a/MLKit-Sample/module-text/src/main/res/values/colors.xml b/MLKit-Sample/module-text/src/main/res/values/colors.xml new file mode 100644 index 0000000..a8d8236 --- /dev/null +++ b/MLKit-Sample/module-text/src/main/res/values/colors.xml @@ -0,0 +1,16 @@ + + + #000000 + #D9D9D9 + #A9A9A9 + #626262 + #1d1d1d + #003853 + #f2f2f2 + #5CACEE + #ffffff + + #FFFA2A2D + #EE6A50 + + diff --git a/MLKit-Sample/module-text/src/main/res/values/dimens.xml b/MLKit-Sample/module-text/src/main/res/values/dimens.xml new file mode 100644 index 0000000..6071d06 --- /dev/null +++ b/MLKit-Sample/module-text/src/main/res/values/dimens.xml @@ -0,0 +1,59 @@ + + + + 45dp + 35dp + 18dp + 15dp + 45dp + + 13sp + 17sp + 14sp + + 15sp + 16dp + + 240dp + 150dp + 16dp + + 170dp + 108dp + 35dp + 21dp + + 232dp + 142dp + 4dp + + 38dp + 38dp + + 24dp + 24dp + + 16dp + 8dp + 13sp + + 24dp + 20dp + 14sp + + 30dp + 30dp + 15dp + + 16sp + + 5dp + + 24dp + 24dp + 65dp + + 250dp + 230dp + 70dp + diff --git a/MLKit-Sample/module-text/src/main/res/values/strings.xml b/MLKit-Sample/module-text/src/main/res/values/strings.xml new file mode 100644 index 0000000..ce7a6c8 --- /dev/null +++ b/MLKit-Sample/module-text/src/main/res/values/strings.xml @@ -0,0 +1,74 @@ + + + ML Kit + + This sample app requires camera and storage access in order to + demo the API. + + OK + Settings + cancel + + Cloud Text Recognition + + Select image from album + Take photo + Video stream + Version: + Simplified chinese + English + Japanese + Korean + Latin + Failed to get data. + Loading… + + + ID Card Recognition + Text Recognition + Document Recognition + Bank Card Recognition + General Card Recognition + + + Document + Translation + BCR + GCR + ICR + Text + + all + coming soon + back + Translate + Language Recognition + Elapsed Time: + 0 character + Machine Learning + + + Upload photos of your ID card + Photo side + Other side + Upload photos of your valid ID card. + Something may be blocking important information in the photo. Retake the photo if needed. + Your personal information will be protected in accordance with the law. + Recognition results: + Note: For Mainland China Only + Device Side + Cloud + + Upload photos of your card + Upload card + Hong Kong, Macao and Taiwan pass + Hong Kong Identity Card + Mainland Travel Permit for Hong Kong、Macao and Taiwan residents + Click to switch + Recognizing, please align the edges. + Taking a picture, please align the edge. + + "Please upload the bank card" + Upload card + + diff --git a/MLKit-Sample/app/src/main/res/values/styles.xml b/MLKit-Sample/module-text/src/main/res/values/styles.xml similarity index 79% rename from MLKit-Sample/app/src/main/res/values/styles.xml rename to MLKit-Sample/module-text/src/main/res/values/styles.xml index e3f977a..20314c0 100644 --- a/MLKit-Sample/app/src/main/res/values/styles.xml +++ b/MLKit-Sample/module-text/src/main/res/values/styles.xml @@ -2,6 +2,11 @@ + + + + + + + + + + + + + + + diff --git a/MLKit-Sample/module-vision/src/main/res/xml/apk_file_provider.xml b/MLKit-Sample/module-vision/src/main/res/xml/apk_file_provider.xml new file mode 100644 index 0000000..ffa74ab --- /dev/null +++ b/MLKit-Sample/module-vision/src/main/res/xml/apk_file_provider.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/MLKit-Sample/settings.gradle b/MLKit-Sample/settings.gradle index e7b4def..079bf18 100644 --- a/MLKit-Sample/settings.gradle +++ b/MLKit-Sample/settings.gradle @@ -1 +1 @@ -include ':app' +include ':module-text', 'module-vision' diff --git a/Photo-Translate/README.md b/Photo-Translate/README.md index f728995..a30ecda 100644 --- a/Photo-Translate/README.md +++ b/Photo-Translate/README.md @@ -12,7 +12,7 @@ ## Introduction The sample code mainly shows the use of Huawei Machine Learning SDK. -It uses text recognition and translation of Huawei Machine Learning SDK. It uses still image of text to translate words in the photo into the language you want. Currently, the following languages are supported: Simplified Chinese (zh), English (en), French (fr), Arabic (ar), Thai (th), Spanish (es), and Turkish (tr). +It uses text recognition and translation of Huawei Machine Learning SDK. It uses still image of text to translate words in the photo into the language you want. Currently, the following languages are supported: Simplified Chinese (zh), English (en), French (fr), Arabic (ar), Thai (th), Spanish (es), and Turkish (tr). You need to use cloud analyzer, such as cloud text analyzer and translator. So you need to apply for an agconnect-services.json file in the developer alliance(https://developer.huawei.com/consumer/en/doc/development/HMS-Guides/ml-preparations-4), replacing the sample-agconnect-services.json in the project. @@ -26,8 +26,8 @@ You only need to modify the applicationId in app Photo-Translate ## Configuration To use functions provided by packages in examples, You need to add the dependencies to the build.gradle file as follows: - implementation 'com.huawei.hms:ml-computer-vision:1.0.2.300' - implementation 'com.huawei.hms:ml-computer-translate:1.0.2.300' + implementation 'com.huawei.hms:ml-computer-vision-cloud:1.0.3.300' + implementation 'com.huawei.hms:ml-computer-translate:1.0.3.300' ## Supported Environments android 4.4 or a later version is recommended. @@ -51,7 +51,7 @@ Sample code majors activitys as follows: 2. Translation - MLTranslatorFactory.getInstance().getRemoteTranslator(settings):Create a translator. - MLRemoteTranslator.asyncTranslate(sourceText): Parse out text from source language to target language, sourceText indicates the language to be detected. - + ## License HUAWEI-HMS-MLKit-Sample/Photo-Translate is licensed under the [Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0). diff --git a/Photo-Translate/app/build.gradle b/Photo-Translate/app/build.gradle index 828aff8..7a37b0b 100644 --- a/Photo-Translate/app/build.gradle +++ b/Photo-Translate/app/build.gradle @@ -32,6 +32,6 @@ dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' - implementation 'com.huawei.hms:ml-computer-vision:1.0.2.300' - implementation 'com.huawei.hms:ml-computer-translate:1.0.2.300' + implementation 'com.huawei.hms:ml-computer-vision-cloud:1.0.3.300' + implementation 'com.huawei.hms:ml-computer-translate:1.0.3.300' } diff --git a/Photo-Translate/app/sample-agconnect-services.json b/Photo-Translate/app/sample-agconnect-services.json index 1326374..69e8ca7 100644 --- a/Photo-Translate/app/sample-agconnect-services.json +++ b/Photo-Translate/app/sample-agconnect-services.json @@ -9,7 +9,7 @@ "client_id":"268600551012363200", "client_secret":"4819981CE7939A526B71AC3092D35C5CB77DF8341C6986559AA9211", "app_id":"1015883", - "package_name":"com.mlkit.sample", + "package_name":"com.mlkit.sample.phototranslate", "api_key":"CV46Xu0Y3+YFDS832xvOY69LHiAtZ2SviYUSZyELicm2NrxUesZE1TO" }, "service":{ diff --git a/Smile-Camera/README.md b/Smile-Camera/README.md index 75ca4a6..bf37e24 100644 --- a/Smile-Camera/README.md +++ b/Smile-Camera/README.md @@ -18,8 +18,8 @@ It uses face detection function of Huawei Machine Learning SDK. It uses real-tim ## Configuration To use functions provided by packages in examples, You need to add the dependencies to the build.gradle file as follows: - implementation 'com.huawei.hms:ml-computer-vision-face-recognition-model:1.0.2.300' - implementation 'com.huawei.hms:ml-computer-vision:1.0.2.300' + implementation 'com.huawei.hms:ml-computer-vision-face-recognition-model:1.0.3.300' + implementation 'com.huawei.hms:ml-computer-vision-face:1.0.3.300' ## Supported Environments android 4.4 or a later version is recommended. diff --git a/Smile-Camera/app/build.gradle b/Smile-Camera/app/build.gradle index d8c9485..7b16f71 100644 --- a/Smile-Camera/app/build.gradle +++ b/Smile-Camera/app/build.gradle @@ -44,7 +44,7 @@ dependencies { implementation fileTree(dir: 'libs', include: ['*.aar']) implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' - implementation 'com.huawei.hms:ml-computer-vision-face-recognition-model:1.0.2.300' - implementation 'com.huawei.hms:ml-computer-vision:1.0.2.300' + implementation 'com.huawei.hms:ml-computer-vision-face-recognition-model:1.0.3.300' + implementation 'com.huawei.hms:ml-computer-vision-face:1.0.3.300' } diff --git a/buildCI.sh b/buildCI.sh index 304c7cf..08b7c35 100644 --- a/buildCI.sh +++ b/buildCI.sh @@ -5,9 +5,11 @@ echo "Begine build." set -e # Move agconnect-services.json in apps. -cp MLKit-Sample/app/sample-agconnect-services.json MLKit-Sample/app/agconnect-services.json -cp MLKit-Sample/app/sample-agconnect-services.json ID-Photo-DIY/app/agconnect-services.json -cp MLKit-Sample/app/sample-agconnect-services.json Smile-Camera/app/agconnect-services.json +cp MLKit-Sample/module-text/sample-agconnect-services.json MLKit-Sample/module-text/agconnect-services.json +cp MLKit-Sample/module-vision/sample-agconnect-services.json MLKit-Sample/module-vision/agconnect-services.json +cp ID-Photo-DIY/app/sample-agconnect-services.json ID-Photo-DIY/app/agconnect-services.json +cp Smile-Camera/app/sample-agconnect-services.json Smile-Camera/app/agconnect-services.json +cp Photo-Translate/app/sample-agconnect-services.json Photo-Translate/app/agconnect-services.json echo "Copy agc file end." # Build diff --git a/settings.gradle b/settings.gradle index 5e1a6c1..e87524a 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,4 +1,5 @@ include 'ID-Photo-DIY:app' -include 'MLKit-Sample:app' include 'Smile-Camera:app' -include 'Photo-Translate:app' \ No newline at end of file +include 'Photo-Translate:app' +include 'MLKit-Sample:module-vision' +include 'MLKit-Sample:module-text' \ No newline at end of file