Commit 70af6e722357e53e284e9f140c351ab8a594d297

Authored by YangShuai
2 parents 367b38f0 6d09dcc5
Showing 37 changed files with 0 additions and 4646 deletions

Too many changes to show.

To preserve performance only 37 of 178 files are displayed.

.idea/gradle.xml
... ... @@ -24,7 +24,6 @@
24 24 <option value="$PROJECT_DIR$/core/app_qr" />
25 25 <option value="$PROJECT_DIR$/core/base" />
26 26 <option value="$PROJECT_DIR$/core/database" />
27   - <option value="$PROJECT_DIR$/core/dentity_verfication" />
28 27 <option value="$PROJECT_DIR$/core/imageload" />
29 28 <option value="$PROJECT_DIR$/core/network" />
30 29 <option value="$PROJECT_DIR$/library_baidumap" />
... ...
app/strike/build.gradle
... ... @@ -187,7 +187,6 @@ dependencies {
187 187 // implementation project(path: ':core:encipher')
188 188 // implementation project(path: ':cloud:user')
189 189 implementation project(path: ':cloud:wjj_lib')
190   - implementation project(path: ':core:dentity_verfication')
191 190 implementation "androidx.viewpager2:viewpager2:1.0.0"
192 191  
193 192  
... ...
app/strike/src/main/AndroidManifest.xml
... ... @@ -17,7 +17,6 @@
17 17 android:roundIcon="@mipmap/ic_launcher_round"
18 18 android:supportsRtl="true"
19 19 android:theme="@style/AppTheme">
20   - <activity android:name="com.cnlive.strike.imgutil.UgcActivity"></activity>
21 20 <activity android:name="com.cnlive.strike.imgutil.SimplePrevActivity" />
22 21 <activity android:name="com.cnlive.strike.demo.activity.HappyChinaActivity" />
23 22  
... ...
app/strike/src/main/java/com/cnlive/strike/MainActivity.java
... ... @@ -10,7 +10,6 @@ import android.view.View;
10 10 import com.cnlive.cloud.R;
11 11 import com.cnlive.strike.demo.activity.DemoMvpActivity;
12 12 import com.cnlive.strike.imgutil.ImgActivity;
13   -import com.cnlive.strike.imgutil.UgcActivity;
14 13  
15 14 import androidx.annotation.NonNull;
16 15 import androidx.annotation.Nullable;
... ... @@ -31,7 +30,6 @@ public class MainActivity extends AppCompatActivity {
31 30 }
32 31 });
33 32 findViewById(R.id.to_img).setOnClickListener(view -> startActivity(new Intent(this, ImgActivity.class)));
34   - findViewById(R.id.ugc_btn).setOnClickListener(view -> startActivity(new Intent(this, UgcActivity.class)));
35 33 }
36 34  
37 35 @Nullable
... ...
app/strike/src/main/java/com/cnlive/strike/imgutil/UgcActivity.java deleted 100644 → 0
1   -package com.cnlive.strike.imgutil;
2   -
3   -import android.content.Intent;
4   -import android.os.Bundle;
5   -
6   -import com.cnlive.cloud.R;
7   -import com.cnlive.core.company_verfication.ui.activity.FillInCompanyDataActivity;
8   -import com.cnlive.core.company_verfication.ui.activity.SelectCompanyDataActivity;
9   -import com.cnlive.core.people_verfication.activity.CheckResultActivity;
10   -import com.cnlive.core.people_verfication.activity.PersonCheckActivity;
11   -import com.cnlive.core.people_verfication.activity.TakeIdentityPictureActivity;
12   -
13   -import androidx.appcompat.app.AppCompatActivity;
14   -
15   -public class UgcActivity extends AppCompatActivity {
16   -
17   - @Override
18   - protected void onCreate(Bundle savedInstanceState) {
19   - super.onCreate(savedInstanceState);
20   - setContentView(R.layout.activity_ugc);
21   -
22   - findViewById(R.id.people_denty).setOnClickListener(view -> startActivity(new Intent(this, TakeIdentityPictureActivity.class)));
23   - findViewById(R.id.company_denty).setOnClickListener(view -> startActivity(new Intent(this, FillInCompanyDataActivity.class)));
24   - findViewById(R.id.company_denty_list).setOnClickListener(view -> startActivity(new Intent(this, SelectCompanyDataActivity.class)));
25   -
26   - findViewById(R.id.btn1).setOnClickListener(view ->PersonCheckActivity.startActivity(this,"","-1"));
27   - findViewById(R.id.btn2).setOnClickListener(view ->PersonCheckActivity.startActivity(this,"","0"));
28   - findViewById(R.id.btn3).setOnClickListener(view ->PersonCheckActivity.startActivity(this,"","2"));
29   - findViewById(R.id.btn4).setOnClickListener(view ->PersonCheckActivity.startActivity(this,"","1"));
30   -
31   - findViewById(R.id.btn01).setOnClickListener(view -> CheckResultActivity.startActivity(this,"","person","-1"));
32   - findViewById(R.id.btn02).setOnClickListener(view ->CheckResultActivity.startActivity(this,"","person","0"));
33   - findViewById(R.id.btn03).setOnClickListener(view ->CheckResultActivity.startActivity(this,"","person","2"));
34   - findViewById(R.id.btn04).setOnClickListener(view ->CheckResultActivity.startActivity(this,"","person","1"));
35   -
36   - findViewById(R.id.btn11).setOnClickListener(view -> CheckResultActivity.startActivity(this,"","company","-1"));
37   - findViewById(R.id.btn12).setOnClickListener(view ->CheckResultActivity.startActivity(this,"","company","0"));
38   - findViewById(R.id.btn13).setOnClickListener(view ->CheckResultActivity.startActivity(this,"","company","2"));
39   - findViewById(R.id.btn14).setOnClickListener(view ->CheckResultActivity.startActivity(this,"","company","1"));
40   - }
41   -}
app/strike/src/main/res/layout/activity_main.xml
... ... @@ -21,11 +21,5 @@
21 21 android:layout_height="wrap_content"
22 22 android:text="图片加载测试"/>
23 23  
24   - <Button
25   - android:id="@+id/ugc_btn"
26   - android:layout_width="wrap_content"
27   - android:layout_height="wrap_content"
28   - android:text="ugc直播认证"
29   - />
30 24 </LinearLayout>
31 25 </layout>
32 26 \ No newline at end of file
... ...
app/strike/src/main/res/layout/activity_ugc.xml deleted 100644 → 0
1   -<?xml version="1.0" encoding="utf-8"?>
2   -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3   - xmlns:app="http://schemas.android.com/apk/res-auto"
4   - xmlns:tools="http://schemas.android.com/tools"
5   - android:layout_width="match_parent"
6   - android:layout_height="match_parent"
7   - android:orientation="vertical"
8   - tools:context="com.cnlive.strike.imgutil.UgcActivity">
9   -
10   - <Button
11   - android:id="@+id/people_denty"
12   - android:layout_width="match_parent"
13   - android:layout_height="wrap_content"
14   - android:layout_margin="@dimen/dp_10"
15   - android:text="个人认证" />
16   -
17   - <TextView
18   - android:layout_width="wrap_content"
19   - android:layout_height="wrap_content"
20   - android:text="身份校验" />
21   -
22   - <LinearLayout
23   - android:layout_width="match_parent"
24   - android:layout_height="wrap_content"
25   - android:orientation="horizontal">
26   -
27   - <Button
28   - android:id="@+id/btn1"
29   - android:layout_width="wrap_content"
30   - android:layout_height="wrap_content"
31   - android:text="未校验" />
32   -
33   - <Button
34   - android:id="@+id/btn2"
35   - android:layout_width="wrap_content"
36   - android:layout_height="wrap_content"
37   - android:text="审核中" />
38   -
39   - <Button
40   - android:id="@+id/btn3"
41   - android:layout_width="wrap_content"
42   - android:layout_height="wrap_content"
43   - android:text="失败" />
44   -
45   - <Button
46   - android:id="@+id/btn4"
47   - android:layout_width="wrap_content"
48   - android:layout_height="wrap_content"
49   - android:text="成功" />
50   - </LinearLayout>
51   -
52   - <TextView
53   - android:layout_width="wrap_content"
54   - android:layout_height="wrap_content"
55   - android:text="个人认证" />
56   -
57   - <LinearLayout
58   - android:layout_width="match_parent"
59   - android:layout_height="wrap_content"
60   - android:orientation="horizontal">
61   -
62   - <Button
63   - android:id="@+id/btn01"
64   - android:layout_width="wrap_content"
65   - android:layout_height="wrap_content"
66   - android:text="未认证" />
67   -
68   - <Button
69   - android:id="@+id/btn02"
70   - android:layout_width="wrap_content"
71   - android:layout_height="wrap_content"
72   - android:text="审核中" />
73   -
74   - <Button
75   - android:id="@+id/btn03"
76   - android:layout_width="wrap_content"
77   - android:layout_height="wrap_content"
78   - android:text="失败" />
79   -
80   - <Button
81   - android:id="@+id/btn04"
82   - android:layout_width="wrap_content"
83   - android:layout_height="wrap_content"
84   - android:text="成功" />
85   - </LinearLayout>
86   -
87   -
88   -
89   - <Button
90   - android:id="@+id/company_denty"
91   - android:layout_width="match_parent"
92   - android:layout_height="wrap_content"
93   - android:layout_margin="@dimen/dp_10"
94   - android:text="机构认证" />
95   -
96   - <TextView
97   - android:layout_width="wrap_content"
98   - android:layout_height="wrap_content"
99   - android:text="机构认证" />
100   -
101   - <LinearLayout
102   - android:layout_width="match_parent"
103   - android:layout_height="wrap_content"
104   - android:orientation="horizontal">
105   -
106   - <Button
107   - android:id="@+id/btn11"
108   - android:layout_width="wrap_content"
109   - android:layout_height="wrap_content"
110   - android:text="未认证" />
111   -
112   - <Button
113   - android:id="@+id/btn12"
114   - android:layout_width="wrap_content"
115   - android:layout_height="wrap_content"
116   - android:text="审核中" />
117   -
118   - <Button
119   - android:id="@+id/btn13"
120   - android:layout_width="wrap_content"
121   - android:layout_height="wrap_content"
122   - android:text="失败" />
123   -
124   - <Button
125   - android:id="@+id/btn14"
126   - android:layout_width="wrap_content"
127   - android:layout_height="wrap_content"
128   - android:text="成功" />
129   - </LinearLayout>
130   -
131   - <Button
132   - android:id="@+id/company_denty_list"
133   - android:layout_width="match_parent"
134   - android:layout_height="wrap_content"
135   - android:layout_margin="@dimen/dp_10"
136   - android:text="机构认证列表" />
137   -</LinearLayout>
core/dentity_verfication/.gitignore deleted 100644 → 0
1   -/build
core/dentity_verfication/build.gradle deleted 100644 → 0
1   -apply plugin: 'com.android.library'
2   -
3   -android {
4   -
5   -}
6   -
7   -dependencies {
8   - implementation fileTree(include: ['*.jar'], dir: 'libs')
9   - implementation 'androidx.appcompat:appcompat:1.0.2'
10   - implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
11   - implementation 'androidx.legacy:legacy-support-v4:1.0.0'
12   - testImplementation 'junit:junit:4.12'
13   - androidTestImplementation 'androidx.test.ext:junit:1.1.1'
14   - androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
15   - implementation "com.cnlive.libs:mediapicker:$rootProject.libMediaPicker"
16   - implementation files('libs/license.jar')
17   -}
core/dentity_verfication/consumer-rules.pro deleted 100644 → 0
core/dentity_verfication/libs/license.jar deleted 100644 → 0
No preview for this file type
core/dentity_verfication/libs/ocr-sdk.jar deleted 100644 → 0
No preview for this file type
core/dentity_verfication/proguard-rules.pro deleted 100644 → 0
1   -# Add project specific ProGuard rules here.
2   -# You can control the set of applied configuration files using the
3   -# proguardFiles setting in build.gradle.
4   -#
5   -# For more details, see
6   -# http://developer.android.com/guide/developing/tools/proguard.html
7   -
8   -# If your project uses WebView with JS, uncomment the following
9   -# and specify the fully qualified class name to the JavaScript interface
10   -# class:
11   -#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12   -# public *;
13   -#}
14   -
15   -# Uncomment this to preserve the line number information for
16   -# debugging stack traces.
17   -#-keepattributes SourceFile,LineNumberTable
18   -
19   -# If you keep the line number information, uncomment this to
20   -# hide the original source file name.
21   -#-renamesourcefileattribute SourceFile
core/dentity_verfication/src/main/AndroidManifest.xml deleted 100644 → 0
1   -<?xml version="1.0" encoding="utf-8"?>
2   -<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3   - package="com.cnlive.core.people_verfication">
4   -
5   - <uses-permission android:name="android.permission.CAMERA" />
6   - <uses-permission android:name="android.permission.INTERNET" />
7   - <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
8   - <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
9   -
10   - <uses-feature android:name="android.hardware.camera2.full" />
11   - <uses-feature android:name="android.hardware.camera" />
12   - <uses-feature android:name="android.hardware.camera.autofocus" />
13   -
14   - <application>
15   - <activity android:name=".activity.PersonCheckActivity"></activity>
16   - <activity android:name=".activity.CheckResultActivity" />
17   - <activity android:name="com.cnlive.core.company_verfication.ui.activity.FillInCompanyDataActivity"></activity>
18   - <activity android:name="com.cnlive.core.company_verfication.ui.activity.SelectCompanyDataActivity" />
19   - <activity android:name=".activity.TakeIdentityPictureActivity" />
20   - <activity
21   - android:name="com.cnlive.core.ocr.ui.camera.CameraActivity"
22   - android:configChanges="screenSize|orientation"
23   - android:launchMode="singleTop"
24   - android:screenOrientation="portrait"
25   - android:theme="@android:style/Theme.Holo.NoActionBar.Fullscreen" />
26   - </application>
27   -
28   -</manifest>
29 0 \ No newline at end of file
core/dentity_verfication/src/main/assets/models/integrity_model_secret.bin deleted 100644 → 0
No preview for this file type
core/dentity_verfication/src/main/assets/models/quality_model_secret.bin deleted 100644 → 0
No preview for this file type
core/dentity_verfication/src/main/java/com/cnlive/core/company_verfication/ui/activity/FillInCompanyDataActivity.java deleted 100644 → 0
1   -package com.cnlive.core.company_verfication.ui.activity;
2   -
3   -import com.cnlive.core.company_verfication.ui.fragment.FillInCompanyDataFragment;
4   -import com.cnlive.core.libs.base.frame.activity.BaseActivity;
5   -import com.cnlive.core.people_verfication.R;
6   -
7   -public class FillInCompanyDataActivity extends BaseActivity {
8   -
9   - @Override
10   - protected void initView() {
11   - loadRootFragment(new FillInCompanyDataFragment());
12   - }
13   -}
core/dentity_verfication/src/main/java/com/cnlive/core/company_verfication/ui/activity/SelectCompanyDataActivity.java deleted 100644 → 0
1   -package com.cnlive.core.company_verfication.ui.activity;
2   -
3   -import androidx.databinding.ViewDataBinding;
4   -import androidx.recyclerview.widget.LinearLayoutManager;
5   -
6   -import com.cnlive.core.company_verfication.ui.adapter.CompanyDataAdapter;
7   -import com.cnlive.core.company_verfication.ui.fragment.SelectCompanyDataFragment;
8   -import com.cnlive.core.libs.base.frame.activity.BaseActivity;
9   -import com.cnlive.core.people_verfication.R;
10   -import com.cnlive.core.people_verfication.databinding.FragmentFillInCompanyDataBinding;
11   -
12   -import java.util.ArrayList;
13   -import java.util.List;
14   -
15   -public class SelectCompanyDataActivity extends BaseActivity {
16   -
17   - @Override
18   - protected void initView() {
19   - loadRootFragment(new SelectCompanyDataFragment());
20   - }
21   -}
core/dentity_verfication/src/main/java/com/cnlive/core/company_verfication/ui/adapter/CompanyDataAdapter.java deleted 100644 → 0
1   -package com.cnlive.core.company_verfication.ui.adapter;
2   -
3   -import android.content.Context;
4   -import android.view.LayoutInflater;
5   -import android.view.View;
6   -import android.view.ViewGroup;
7   -import android.widget.TextView;
8   -
9   -import androidx.annotation.NonNull;
10   -import androidx.databinding.DataBindingUtil;
11   -import androidx.recyclerview.widget.RecyclerView;
12   -
13   -import com.cnlive.core.people_verfication.R;
14   -import com.cnlive.core.people_verfication.databinding.ItemCompanyDateBinding;
15   -
16   -import java.util.List;
17   -
18   -public class CompanyDataAdapter extends RecyclerView.Adapter {
19   - private Context context;
20   - private List<String> data;
21   -
22   - public CompanyDataAdapter(Context context, List<String> data) {
23   - this.context = context;
24   - this.data = data;
25   - }
26   -
27   - @NonNull
28   - @Override
29   - public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
30   - LayoutInflater inflater = LayoutInflater.from(context);
31   - ItemCompanyDateBinding binding = DataBindingUtil.inflate(inflater, R.layout.item_company_date, parent, false);
32   - return new MyViewHolder(binding);
33   - }
34   -
35   - @Override
36   - public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
37   - ItemCompanyDateBinding binding = ((MyViewHolder) holder).binding;
38   - binding.includeAccountChild.llRoot.getBaselineAlignedChildIndex();
39   - binding.includeAccountChild.llChildAccountDelete.setVisibility(View.GONE);
40   - }
41   -
42   - @Override
43   - public int getItemCount() {
44   - return data.size();
45   - }
46   -
47   - private class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
48   - private ItemCompanyDateBinding binding;
49   -
50   - public MyViewHolder(@NonNull ItemCompanyDateBinding binding) {
51   - super(binding.getRoot());
52   - this.binding = binding;
53   - binding.includeAddCircle.btnAddChildCircle.setOnClickListener(this);
54   - binding.includeAddChildAccount.btnAddChildAccount.setOnClickListener(this);
55   - }
56   -
57   -
58   - @Override
59   - public void onClick(View v) {
60   - //添加圈子
61   - if (v.getId() == R.id.btn_addChildCircle) {
62   - View child = LayoutInflater.from(context).inflate(R.layout.item_company_data_type_circle_child, null);
63   - binding.includeCircleChild.llRoot.addView(child);
64   - }
65   - //添加群组
66   - else if (v.getId() == R.id.btn_addChildAccount) {
67   - View child = LayoutInflater.from(context).inflate(R.layout.item_company_data_type_child_account, null);
68   - int index=binding.includeAccountChild.llRoot.getChildCount() - 1;
69   - binding.includeAccountChild.llRoot.addView(child, index);
70   - TextView textView = child.findViewById(R.id.ll_child_account_delete);
71   - textView.setVisibility(View.VISIBLE);
72   - textView.setOnClickListener(this);
73   - textView.setTag(child);
74   -// textView.setOnClickListener(new View.OnClickListener() {
75   -// @Override
76   -// public void onClick(View v) {
77   -// binding.includeAccountChild.llRoot.removeView(child);
78   -// }
79   -// });
80   - } else if (v.getId() == R.id.ll_child_account_delete) {
81   - if (null!=v&&null!=v.getTag()){
82   - View child= (View) v.getTag();
83   - //获取当前子类
84   - binding.includeAccountChild.llRoot.removeView(child);
85   - }
86   -
87   - }
88   - }
89   - }
90   -}
core/dentity_verfication/src/main/java/com/cnlive/core/company_verfication/ui/adapter/CompanyItemDataAdapter.java deleted 100644 → 0
1   -package com.cnlive.core.company_verfication.ui.adapter;
2   -
3   -import android.content.Context;
4   -import android.view.LayoutInflater;
5   -import android.view.View;
6   -import android.view.ViewGroup;
7   -import android.widget.TextView;
8   -
9   -import com.cnlive.core.company_verfication.ui.model.CompanyItemData;
10   -import com.cnlive.core.people_verfication.R;
11   -import com.cnlive.core.people_verfication.databinding.ItemCompanyDataTypeAddChildAccountBinding;
12   -import com.cnlive.core.people_verfication.databinding.ItemCompanyDataTypeAddCircleBinding;
13   -import com.cnlive.core.people_verfication.databinding.ItemCompanyDataTypeAddOrganizationBinding;
14   -import com.cnlive.core.people_verfication.databinding.ItemCompanyDataTypeChildAccountBinding;
15   -import com.cnlive.core.people_verfication.databinding.ItemCompanyDataTypeCircleChildBinding;
16   -import com.cnlive.core.people_verfication.databinding.ItemCompanyDataTypeOrganizationBinding;
17   -
18   -import java.util.List;
19   -
20   -import androidx.annotation.NonNull;
21   -import androidx.databinding.DataBindingUtil;
22   -import androidx.recyclerview.widget.RecyclerView;
23   -
24   -/*
25   - *@date:2020/4/7 16:29
26   - *@author:杨帅
27   - */public class CompanyItemDataAdapter extends RecyclerView.Adapter {
28   - private Context context;
29   - private List<CompanyItemData> dataList;
30   - private OnClickListener onClickListener;
31   -
32   - public CompanyItemDataAdapter(Context context, List<CompanyItemData> dataList) {
33   - this.context = context;
34   - this.dataList = dataList;
35   - }
36   -
37   - public void setOnClickListener(OnClickListener onClickListener) {
38   - this.onClickListener = onClickListener;
39   - }
40   -
41   - @NonNull
42   - @Override
43   - public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
44   - switch (viewType) {
45   - case CompanyItemData.TYPE_ORGANIZATION:
46   - ItemCompanyDataTypeOrganizationBinding organizationBinding = DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.item_company_data_type_organization, parent, false);
47   - OrganizactionHolder organizactionHolder = new OrganizactionHolder(organizationBinding);
48   - return organizactionHolder;
49   - case CompanyItemData.TYPE_CIRCLE:
50   - ItemCompanyDataTypeCircleChildBinding circleChildBinding = DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.item_company_data_type_circle_child, parent, false);
51   - CircleHolder circleHolder = new CircleHolder(circleChildBinding);
52   - return circleHolder;
53   - case CompanyItemData.TYPE_ADD_CIRCLE:
54   - ItemCompanyDataTypeAddCircleBinding addCircleBinding = DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.item_company_data_type_add_circle, parent, false);
55   - AddCircleHolder addCircleHolder = new AddCircleHolder(addCircleBinding);
56   - return addCircleHolder;
57   - case CompanyItemData.TYPE_CHILD_ACCOUNT:
58   - ItemCompanyDataTypeChildAccountBinding childAccountBinding = DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.item_company_data_type_child_account, parent, false);
59   - ChildAccountHolder childAccountHolder = new ChildAccountHolder(childAccountBinding);
60   - return childAccountHolder;
61   - case CompanyItemData.TYPE_ADD_CHILD_ACCOUNT:
62   - ItemCompanyDataTypeAddChildAccountBinding addChildAccountBinding = DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.item_company_data_type_add_child_account, parent, false);
63   - AddChildAccountHolder addChildAccountHolder = new AddChildAccountHolder(addChildAccountBinding);
64   - return addChildAccountHolder;
65   - case CompanyItemData.TYPE_ADD_ORGANIZATION:
66   - ItemCompanyDataTypeAddOrganizationBinding addOrganizationBinding = DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.item_company_data_type_add_organization, parent, false);
67   - AddOrganizactionHolder addOrganizactionHolder = new AddOrganizactionHolder(addOrganizationBinding);
68   - return addOrganizactionHolder;
69   - }
70   - return null;
71   - }
72   -
73   - @Override
74   - public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
75   - switch (getItemViewType(position)) {
76   - case CompanyItemData.TYPE_ORGANIZATION:
77   - OrganizactionHolder organizactionHolder = (OrganizactionHolder) holder;
78   - organizactionHolder.binding.llTopLine.setVisibility(dataList.get(position).isShowTopLine() ? View.VISIBLE : View.GONE);
79   - organizactionHolder.binding.ivOrganizationDelete.setVisibility(dataList.get(position).isShowOrganizactionDelete() ? View.VISIBLE : View.GONE);
80   -
81   - break;
82   - case CompanyItemData.TYPE_CIRCLE:
83   - CircleHolder circleHolder = (CircleHolder) holder;
84   - circleHolder.binding.llCircleDelete.setVisibility(dataList.get(position).isShowDelete() ? View.VISIBLE : View.GONE);
85   - break;
86   - case CompanyItemData.TYPE_ADD_CIRCLE:
87   - break;
88   - case CompanyItemData.TYPE_CHILD_ACCOUNT:
89   - ChildAccountHolder childAccountHolder = (ChildAccountHolder) holder;
90   - childAccountHolder.binding.llChildAccountDelete.setVisibility(dataList.get(position).isShowDelete() ? View.VISIBLE : View.GONE);
91   - break;
92   - case CompanyItemData.TYPE_ADD_CHILD_ACCOUNT:
93   - break;
94   - case CompanyItemData.TYPE_ADD_ORGANIZATION:
95   -
96   - break;
97   - }
98   - }
99   -
100   - @Override
101   - public int getItemCount() {
102   - return dataList.size();
103   - }
104   -
105   - @Override
106   - public int getItemViewType(int position) {
107   - return dataList.get(position).getType();
108   - }
109   -
110   -
111   - /**
112   - * 所属机构
113   - */
114   - public class OrganizactionHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
115   - private ItemCompanyDataTypeOrganizationBinding binding;
116   -
117   - public OrganizactionHolder(@NonNull ItemCompanyDataTypeOrganizationBinding binding) {
118   - super(binding.getRoot());
119   - this.binding = binding;
120   - binding.ivOrganizationDelete.setOnClickListener(this);
121   - binding.tvOrganization.setOnClickListener(this);
122   - }
123   -
124   - @Override
125   - public void onClick(View v) {
126   - //删除机构
127   - if (v.getId() == R.id.iv_organization_delete) {
128   - //获取当前所在逻辑位置
129   - int logicPosition = dataList.get(getLayoutPosition()).getLogicPosition();
130   - deleteLogicItem(logicPosition);
131   - dataList.add(new CompanyItemData(CompanyItemData.TYPE_ADD_ORGANIZATION, dataList.get(dataList.size() - 1).getLogicPosition()));
132   - notifyDataSetChanged();
133   - }
134   - //选中机构
135   - else if (v.getId() == R.id.tv_organization) {
136   - if (null != onClickListener) {
137   - onClickListener.onClick(binding.tvOrganization);
138   - }
139   - }
140   - }
141   - }
142   -
143   - private void deleteLogicItem(int logicPosition) {
144   - if (dataList.size() == 0) {
145   - return;
146   - }
147   - for (int i = dataList.size() - 1; i >= 0; i--) {
148   - if (dataList.get(i).getLogicPosition() == logicPosition) {
149   - dataList.remove(i);
150   - }
151   - }
152   - }
153   -
154   - /**
155   - * 所属机构圈子
156   - */
157   - public class CircleHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
158   - private ItemCompanyDataTypeCircleChildBinding binding;
159   -
160   - public CircleHolder(@NonNull ItemCompanyDataTypeCircleChildBinding binding) {
161   - super(binding.getRoot());
162   - this.binding = binding;
163   - binding.llCircleDelete.setOnClickListener(this);
164   - }
165   -
166   - @Override
167   - public void onClick(View v) {
168   - if (v.getId() == R.id.ll_circle_delete) {
169   - int removeIndex = getLayoutPosition();
170   - dataList.remove(removeIndex);
171   - notifyItemRemoved(removeIndex);
172   - }
173   - }
174   - }
175   -
176   - /**
177   - * 添加圈子
178   - */
179   - public class AddCircleHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
180   - private ItemCompanyDataTypeAddCircleBinding binding;
181   -
182   - public AddCircleHolder(@NonNull ItemCompanyDataTypeAddCircleBinding binding) {
183   - super(binding.getRoot());
184   - this.binding = binding;
185   - binding.btnAddChildCircle.setOnClickListener(this);
186   - }
187   -
188   - @Override
189   - public void onClick(View v) {
190   - if (v.getId() == R.id.btn_addChildCircle) {
191   - //获取当前逻辑上的数量
192   - int logicSize = dataList.get(getLayoutPosition()).getLogicPosition();
193   - dataList.add(getLayoutPosition(), new CompanyItemData(CompanyItemData.TYPE_CIRCLE, logicSize, true));
194   - notifyItemInserted(getLayoutPosition() + 1);
195   - }
196   - }
197   - }
198   -
199   - /**
200   - * 所属子账号
201   - */
202   - public class ChildAccountHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
203   - private ItemCompanyDataTypeChildAccountBinding binding;
204   -
205   - public ChildAccountHolder(@NonNull ItemCompanyDataTypeChildAccountBinding binding) {
206   - super(binding.getRoot());
207   - this.binding = binding;
208   - binding.llChildAccountDelete.setOnClickListener(this);
209   - }
210   -
211   - @Override
212   - public void onClick(View v) {
213   - if (v.getId() == R.id.ll_child_account_delete) {
214   - int removeIndex = getLayoutPosition();
215   - dataList.remove(removeIndex);
216   - notifyItemRemoved(removeIndex);
217   -
218   - }
219   - }
220   - }
221   -
222   - /**
223   - * 添加子账号
224   - */
225   - public class AddChildAccountHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
226   - private ItemCompanyDataTypeAddChildAccountBinding binding;
227   -
228   - public AddChildAccountHolder(@NonNull ItemCompanyDataTypeAddChildAccountBinding binding) {
229   - super(binding.getRoot());
230   - this.binding = binding;
231   - binding.btnAddChildAccount.setOnClickListener(this);
232   - }
233   -
234   - @Override
235   - public void onClick(View v) {
236   - if (v.getId() == R.id.btn_addChildAccount) {
237   - //获取当前逻辑上的数量
238   - int logicSize = dataList.get(getLayoutPosition()).getLogicPosition();
239   - dataList.add(getAdapterPosition(), new CompanyItemData(CompanyItemData.TYPE_CHILD_ACCOUNT, logicSize, true));
240   - notifyItemInserted(getLayoutPosition() + 1);
241   -
242   - }
243   - }
244   - }
245   -
246   - /**
247   - * 添加机构
248   - */
249   - public class AddOrganizactionHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
250   - private ItemCompanyDataTypeAddOrganizationBinding binding;
251   -
252   - public AddOrganizactionHolder(@NonNull ItemCompanyDataTypeAddOrganizationBinding binding) {
253   - super(binding.getRoot());
254   - this.binding = binding;
255   - binding.btnAddOrganization.setOnClickListener(this);
256   - }
257   -
258   - @Override
259   - public void onClick(View v) {
260   - if (v.getId() == R.id.btn_addOrganization) {
261   - //获取当前逻辑上的数量
262   - int logicSize = dataList.get(getLayoutPosition()).getLogicPosition();
263   - int selectIndex = getLayoutPosition();
264   - dataList.remove(dataList.size() - 1);
265   - dataList.add(new CompanyItemData(CompanyItemData.TYPE_ORGANIZATION, logicSize + 1, true, true));
266   - dataList.add(new CompanyItemData(CompanyItemData.TYPE_CIRCLE, logicSize + 1));
267   - dataList.add(new CompanyItemData(CompanyItemData.TYPE_ADD_CIRCLE, logicSize + 1));
268   - dataList.add(new CompanyItemData(CompanyItemData.TYPE_CHILD_ACCOUNT, logicSize + 1));
269   - dataList.add(new CompanyItemData(CompanyItemData.TYPE_ADD_CHILD_ACCOUNT, logicSize + 1));
270   - dataList.add(new CompanyItemData(CompanyItemData.TYPE_ADD_ORGANIZATION, logicSize + 1));
271   - notifyItemInserted(selectIndex);
272   - }
273   - }
274   - }
275   -
276   - public interface OnClickListener {
277   - void onClick(TextView textView);
278   - }
279   -}
core/dentity_verfication/src/main/java/com/cnlive/core/company_verfication/ui/fragment/BottomSheetDialog.java deleted 100644 → 0
1   -package com.cnlive.core.company_verfication.ui.fragment;
2   -
3   -import android.os.Bundle;
4   -import android.view.LayoutInflater;
5   -import android.view.View;
6   -import android.view.ViewGroup;
7   -
8   -import androidx.annotation.NonNull;
9   -import androidx.annotation.Nullable;
10   -
11   -import com.cnlive.core.people_verfication.R;
12   -import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
13   -
14   -public class BottomSheetDialog extends BottomSheetDialogFragment {
15   - @Nullable
16   - @Override
17   - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
18   -
19   - return inflater.inflate(R.layout.fragment_bottom, container, false);
20   - }
21   -
22   - @Override
23   - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
24   - super.onViewCreated(view, savedInstanceState);
25   -
26   -
27   - }
28   -}
29 0 \ No newline at end of file
core/dentity_verfication/src/main/java/com/cnlive/core/company_verfication/ui/fragment/FillInCompanyDataFragment.java deleted 100644 → 0
1   -package com.cnlive.core.company_verfication.ui.fragment;
2   -
3   -import android.os.Bundle;
4   -import android.view.View;
5   -
6   -import com.cnlive.core.libs.base.frame.fragment.BaseFragment;
7   -import com.cnlive.core.people_verfication.R;
8   -import com.cnlive.core.people_verfication.databinding.FragmentFillInCompanyDataBinding;
9   -
10   -import androidx.databinding.ViewDataBinding;
11   -
12   -/*
13   - *@date:2020/4/7 14:50
14   - *@author:杨帅
15   - */public class FillInCompanyDataFragment extends BaseFragment {
16   - private FragmentFillInCompanyDataBinding binding;
17   -
18   - public static FillInCompanyDataFragment newInstance(String userId) {
19   - FillInCompanyDataFragment fragment = new FillInCompanyDataFragment();
20   - Bundle args = new Bundle();
21   - args.putString("userId", userId);
22   - fragment.setArguments(args);
23   - return fragment;
24   - }
25   -
26   - @Override
27   - protected int getBindLayoutId() {
28   - return R.layout.fragment_fill_in_company_data;
29   - }
30   -
31   - @Override
32   - protected void initBindingLayoutData(ViewDataBinding baseBinding) {
33   - super.initBindingLayoutData(baseBinding);
34   - binding = (FragmentFillInCompanyDataBinding) baseBinding;
35   - }
36   -
37   - @Override
38   - protected void initView() {
39   - showDefaultWhiteStatusBar();
40   - binding.topbar.setTitle("填写公司信息");
41   - binding.topbar.addLeftImageButton(R.drawable.icon_verficat_back,R.id.back_btn).setOnClickListener(new View.OnClickListener() {
42   - @Override
43   - public void onClick(View v) {
44   - me.finish();
45   - }
46   - });
47   - }
48   -}
core/dentity_verfication/src/main/java/com/cnlive/core/company_verfication/ui/fragment/SelectCompanyDataFragment.java deleted 100644 → 0
1   -package com.cnlive.core.company_verfication.ui.fragment;
2   -
3   -import android.view.Gravity;
4   -import android.view.View;
5   -import android.view.ViewGroup;
6   -import android.widget.LinearLayout;
7   -import android.widget.RelativeLayout;
8   -import android.widget.TextView;
9   -
10   -import com.cnlive.core.company_verfication.ui.adapter.CompanyDataAdapter;
11   -import com.cnlive.core.company_verfication.ui.adapter.CompanyItemDataAdapter;
12   -import com.cnlive.core.company_verfication.ui.model.CompanyItemData;
13   -import com.cnlive.core.libs.base.frame.fragment.BaseFragment;
14   -import com.cnlive.core.libs.base.util.StatusBarConfig;
15   -import com.cnlive.core.libs.base.util.StatusBarUtil;
16   -import com.cnlive.core.people_verfication.R;
17   -import com.cnlive.core.people_verfication.databinding.FragmentSelectInCompanyDataBinding;
18   -import com.google.android.material.bottomsheet.BottomSheetBehavior;
19   -
20   -import java.util.ArrayList;
21   -import java.util.List;
22   -
23   -import androidx.annotation.NonNull;
24   -import androidx.coordinatorlayout.widget.CoordinatorLayout;
25   -import androidx.databinding.ViewDataBinding;
26   -import androidx.recyclerview.widget.LinearLayoutManager;
27   -
28   -/*
29   - *@date:2020/4/7 14:54
30   - *@author:杨帅
31   - */public class SelectCompanyDataFragment extends BaseFragment {
32   - private List<String> data = new ArrayList<>();
33   - private FragmentSelectInCompanyDataBinding binding;
34   - private CompanyItemDataAdapter itemDataAdapter;
35   - private BottomSheetBehavior behavior;
36   -
37   - @Override
38   - protected int getBindLayoutId() {
39   - return R.layout.fragment_select_in_company_data;
40   - }
41   -
42   - @Override
43   - protected void initBindingLayoutData(ViewDataBinding baseBinding) {
44   - super.initBindingLayoutData(baseBinding);
45   - binding = (FragmentSelectInCompanyDataBinding) baseBinding;
46   - }
47   -
48   - @Override
49   - protected void initView() {
50   - //设置沉浸式状态栏
51   - showImmersiveStatusBar();
52   - //设置状态栏提示文字颜色
53   - setStatusBarTextColor(StatusBarConfig.BLACK);
54   - initTopBar();
55   - List<CompanyItemData> list = new ArrayList<>();
56   - list.add(new CompanyItemData(CompanyItemData.TYPE_ORGANIZATION, 0));
57   - list.add(new CompanyItemData(CompanyItemData.TYPE_CIRCLE, 0));
58   - list.add(new CompanyItemData(CompanyItemData.TYPE_ADD_CIRCLE, 0));
59   - list.add(new CompanyItemData(CompanyItemData.TYPE_CHILD_ACCOUNT, 0));
60   - list.add(new CompanyItemData(CompanyItemData.TYPE_ADD_CHILD_ACCOUNT, 0));
61   - list.add(new CompanyItemData(CompanyItemData.TYPE_ADD_ORGANIZATION, 0));
62   - itemDataAdapter = new CompanyItemDataAdapter(me, list);
63   - binding.recyclerView.setLayoutManager(new LinearLayoutManager(me));
64   - binding.recyclerView.setAdapter(itemDataAdapter);
65   - binding.viewMask.setVisibility(View.GONE);
66   - behavior = BottomSheetBehavior.from(binding.llBottom);
67   - behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
68   - @Override
69   - public void onStateChanged(@NonNull View bottomSheet, @BottomSheetBehavior.State int newState) {
70   - String state = "null";
71   - switch (newState) {
72   - case 1:
73   - state = "STATE_DRAGGING";//过渡状态此时用户正在向上或者向下拖动bottom sheet
74   - break;
75   - case 2:
76   - state = "STATE_SETTLING"; // 视图从脱离手指自由滑动到最终停下的这一小段时间
77   - break;
78   - case 3:
79   - state = "STATE_EXPANDED"; //处于完全展开的状态
80   -
81   - break;
82   - case 4:
83   - state = "STATE_COLLAPSED"; //默认的折叠状态
84   - binding.viewMask.setVisibility(View.GONE);
85   - break;
86   - case 5:
87   - state = "STATE_HIDDEN"; //下滑动完全隐藏 bottom sheet
88   - binding.viewMask.setVisibility(View.GONE);
89   - break;
90   - }
91   -
92   - }
93   -
94   - @Override
95   - public void onSlide(@NonNull View view, float v) {
96   -
97   - }
98   - });
99   - //蒙版点击
100   - binding.viewMask.setOnClickListener(new View.OnClickListener() {
101   - @Override
102   - public void onClick(View v) {
103   - if (!isNull(behavior)) {
104   - binding.viewMask.setVisibility(View.GONE);
105   - behavior.setState(BottomSheetBehavior.STATE_HIDDEN);
106   - }
107   - }
108   - });
109   -
110   - itemDataAdapter.setOnClickListener(new CompanyItemDataAdapter.OnClickListener() {
111   - @Override
112   - public void onClick(TextView textView) {
113   - if (!isNull(behavior)) {
114   - binding.viewMask.setVisibility(View.VISIBLE);
115   - behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
116   - }
117   -// BottomSheetDialog bottomSheetDialog=new BottomSheetDialog();
118   -// bottomSheetDialog.show(getFragmentManager(),TAG);
119   - }
120   - });
121   - }
122   -
123   - private void initTopBar() {
124   - // 设置标题栏的内容在状态栏之下
125   - binding.topbar.setTitle("填写公司信息");
126   - // 设置标题栏 + 状态栏的高度
127   - setTitleViewAdjustImmersiveStatusBar(binding.llTop);
128   - binding.topbar.addLeftImageButton(R.drawable.icon_verficat_back, R.id.back_btn).setOnClickListener(new View.OnClickListener() {
129   - @Override
130   - public void onClick(View v) {
131   - me.finish();
132   - }
133   - });
134   - }
135   -}
core/dentity_verfication/src/main/java/com/cnlive/core/company_verfication/ui/model/CompanyItemData.java deleted 100644 → 0
1   -package com.cnlive.core.company_verfication.ui.model;
2   -
3   -/*机构数据
4   - *@date:2020/4/7 16:24
5   - *@author:杨帅
6   - */public class CompanyItemData {
7   - public static final int TYPE_ORGANIZATION = 0;//所属机构
8   - public static final int TYPE_CIRCLE = 1;//您的圈子
9   - public static final int TYPE_ADD_CIRCLE = 2;//添加圈子
10   - public static final int TYPE_CHILD_ACCOUNT = 3;//相关账号
11   - public static final int TYPE_ADD_CHILD_ACCOUNT = 4;//添加子账号
12   - public static final int TYPE_ADD_ORGANIZATION = 5;//添加机构
13   -
14   - private int type;
15   - private boolean showDelete;
16   - private int logicPosition;//逻辑上数量
17   - private boolean showTopLine;
18   - private boolean showOrganizactionDelete;
19   -
20   - public int getType() {
21   - return type;
22   - }
23   -
24   - public void setType(int type) {
25   - this.type = type;
26   - }
27   -
28   - public boolean isShowDelete() {
29   - return showDelete;
30   - }
31   -
32   - public void setShowDelete(boolean showDelete) {
33   - this.showDelete = showDelete;
34   - }
35   - public CompanyItemData(int type, int logicPosition) {
36   - this.type = type;
37   - this.logicPosition = logicPosition;
38   - }
39   -
40   - public CompanyItemData(int type, int logicPosition, boolean showTopLine, boolean showOrganizactionDelete) {
41   - this.type = type;
42   - this.logicPosition = logicPosition;
43   - this.showTopLine = showTopLine;
44   - this.showOrganizactionDelete = showOrganizactionDelete;
45   - }
46   -
47   - public CompanyItemData(int type, int logicPosition, boolean showDelete) {
48   - this.type = type;
49   - this.logicPosition = logicPosition;
50   - this.showDelete = showDelete;
51   - }
52   -
53   - public boolean isShowTopLine() {
54   - return showTopLine;
55   - }
56   -
57   - public void setShowTopLine(boolean showTopLine) {
58   - this.showTopLine = showTopLine;
59   - }
60   -
61   - public int getLogicPosition() {
62   - return logicPosition;
63   - }
64   -
65   - public void setLogicPosition(int logicPosition) {
66   - this.logicPosition = logicPosition;
67   - }
68   -
69   - public boolean isShowOrganizactionDelete() {
70   - return showOrganizactionDelete;
71   - }
72   -
73   - public void setShowOrganizactionDelete(boolean showOrganizactionDelete) {
74   - this.showOrganizactionDelete = showOrganizactionDelete;
75   - }
76   -}
core/dentity_verfication/src/main/java/com/cnlive/core/ocr/RecognizeService.java deleted 100644 → 0
1   -package com.cnlive.core.ocr;
2   -
3   -import android.content.Context;
4   -import android.util.Log;
5   -
6   -import com.baidu.ocr.sdk.OCR;
7   -import com.baidu.ocr.sdk.OnResultListener;
8   -import com.baidu.ocr.sdk.exception.OCRError;
9   -import com.baidu.ocr.sdk.model.AccessToken;
10   -import com.baidu.ocr.sdk.model.BankCardParams;
11   -import com.baidu.ocr.sdk.model.BankCardResult;
12   -import com.baidu.ocr.sdk.model.IDCardParams;
13   -import com.baidu.ocr.sdk.model.IDCardResult;
14   -
15   -import java.io.File;
16   -
17   -/**
18   - * @author Lynn
19   - * @date 2018/1/4
20   - */
21   -
22   -public class RecognizeService {
23   -
24   - /**
25   - * 识别银行卡
26   - *
27   - * @param filePath 文件路径
28   - * @param listener 回调
29   - */
30   - public static void recBankCard(String filePath, OnResultListener<BankCardResult> listener) {
31   - BankCardParams params = new BankCardParams();
32   - params.setImageFile(new File(filePath));
33   - OCR.getInstance().recognizeBankCard(params, listener);
34   - }
35   -
36   - /**
37   - * 识别身份证
38   - *
39   - * @param idCardSide 身份证正反面
40   - * @param filePath 文件路径
41   - * @param listener 回调
42   - */
43   - public static void recIDCard(String idCardSide, String filePath, OnResultListener<IDCardResult> listener) {
44   - IDCardParams param = new IDCardParams();
45   - param.setImageFile(new File(filePath));
46   - // 设置身份证正反面
47   - param.setIdCardSide(idCardSide);
48   - // 设置方向检测
49   - param.setDetectDirection(true);
50   - // 设置图像参数压缩质量0-100, 越大图像质量越好但是请求时间越长。 不设置则默认值为20
51   - param.setImageQuality(20);
52   - OCR.getInstance().recognizeIDCard(param, listener);
53   - }
54   -
55   - /**
56   - * 初始化 with AK & SK
57   - *
58   - * @param context context
59   - */
60   - public static void initAccessTokenWithAkSk(final Context context) {
61   - OCR.getInstance().initAccessTokenWithAkSk(new OnResultListener<AccessToken>() {
62   - @Override
63   - public void onResult(AccessToken result) {
64   - String token = result.getAccessToken();
65   - Log.e("LynnTest", result.toString());
66   - }
67   -
68   - @Override
69   - public void onError(OCRError error) {
70   - error.printStackTrace();
71   - Log.e("LynnTest", error.getMessage());
72   - }
73   - }, context, "YIGsVzdh35y3GCaNUDsxM3cC", "neAe1orXgeTaiHkAbygrgCevKe1fPrG1");
74   - }
75   -
76   - /**
77   - * 初始化 授权文件(安全模式)
78   - *
79   - * @param context
80   - */
81   - public static void initAccessToken(Context context) {
82   - OCR.getInstance().initAccessToken(new OnResultListener<AccessToken>() {
83   - @Override
84   - public void onResult(AccessToken accessToken) {
85   - String token = accessToken.getAccessToken();
86   - }
87   -
88   - @Override
89   - public void onError(OCRError ocrError) {
90   -
91   - }
92   - }, context);
93   - }
94   -}
core/dentity_verfication/src/main/java/com/cnlive/core/ocr/idcardquality/IDcardQualityProcess.java deleted 100644 → 0
1   -/*
2   - * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
3   - */
4   -package com.cnlive.core.ocr.idcardquality;
5   -
6   -import android.content.res.AssetManager;
7   -import android.graphics.Bitmap;
8   -
9   -import com.baidu.idl.authority.AlgorithmOnMainThreadException;
10   -import com.baidu.idl.authority.IDLAuthorityException;
11   -import com.baidu.idl.license.License;
12   -import com.baidu.idl.util.UIThread;
13   -
14   -
15   -public class IDcardQualityProcess {
16   -
17   - private static IDcardQualityProcess mInstance;
18   - private static String tokenString;
19   - private static int mAuthorityStatus;
20   - private static Throwable loadNativeException = null;
21   - private static volatile boolean hasReleased;
22   -
23   - public IDcardQualityProcess() {
24   - }
25   -
26   - public static synchronized IDcardQualityProcess getInstance() {
27   - if (null == mInstance) {
28   - mInstance = new IDcardQualityProcess();
29   - }
30   -
31   - return mInstance;
32   - }
33   -
34   - public native byte[] convertRGBImage(int[] colors, int width, int height);
35   -
36   - public native int idcardQualityModelInit(AssetManager var1, String var2);
37   -
38   - public native int idcardQualityCaptchaRelease();
39   -
40   - public native int idcardQualityProcess(byte[] var1, int var2, int var3, boolean var4, int var5);
41   -
42   - public static synchronized int init(String token) throws AlgorithmOnMainThreadException, IDLAuthorityException {
43   - if (UIThread.isUITread()) {
44   - throw new AlgorithmOnMainThreadException();
45   - } else {
46   - tokenString = token;
47   -
48   - try {
49   - mAuthorityStatus = License.getInstance().init(tokenString);
50   - } catch (Exception var2) {
51   - if (var2!=null)
52   - var2.printStackTrace();
53   - }
54   -
55   - return mAuthorityStatus;
56   - }
57   - }
58   -
59   - public int idcardQualityInit(AssetManager assetManager, String modelPath) {
60   - if (mAuthorityStatus == 0) {
61   - hasReleased = false;
62   - return this.idcardQualityModelInit(assetManager, modelPath);
63   - } else {
64   - return mAuthorityStatus;
65   - }
66   - }
67   -
68   - public int idcardQualityRelease() {
69   - if (mAuthorityStatus == 0) {
70   - hasReleased = true;
71   - this.idcardQualityCaptchaRelease();
72   - return 0;
73   - } else {
74   - return mAuthorityStatus;
75   - }
76   - }
77   -
78   - public int idcardQualityDetectionImg(Bitmap img, boolean isfont) {
79   - if (mAuthorityStatus == 0) {
80   - if (hasReleased) {
81   - return -1;
82   - }
83   - int imgHeight = img.getHeight();
84   - int imgWidth = img.getWidth();
85   - byte[] imageData = this.getRGBImageData(img);
86   - return this.idcardQualityProcess(imageData, imgHeight, imgWidth, isfont, 3);
87   - } else {
88   - return mAuthorityStatus;
89   - }
90   - }
91   -
92   - public static Throwable getLoadSoException() {
93   - return loadNativeException;
94   - }
95   -
96   - public byte[] getRGBImageData(Bitmap img) {
97   - int imgWidth = img.getWidth();
98   - int imgHeight = img.getHeight();
99   - int[] pixels = new int[imgWidth * imgHeight];
100   - img.getPixels(pixels, 0, imgWidth, 0, 0, imgWidth, imgHeight);
101   - byte[] imageData = convertRGBImage(pixels, imgWidth, imgHeight);
102   - return imageData;
103   - }
104   -
105   - public void releaseModel() {
106   - this.idcardQualityRelease();
107   - }
108   -
109   - static {
110   - try {
111   - System.loadLibrary("idl_license");
112   - System.loadLibrary("idcard_quality.1.1.1");
113   - } catch (Throwable e) {
114   - loadNativeException = e;
115   - }
116   - mInstance = null;
117   - mAuthorityStatus = 256;
118   - }
119   -}
core/dentity_verfication/src/main/java/com/cnlive/core/ocr/ui/camera/Camera1Control.java deleted 100644 → 0
1   -/*
2   - * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
3   - */
4   -package com.cnlive.core.ocr.ui.camera;
5   -
6   -import android.Manifest;
7   -import android.content.Context;
8   -import android.content.pm.FeatureInfo;
9   -import android.content.pm.PackageManager;
10   -import android.graphics.ImageFormat;
11   -import android.graphics.Rect;
12   -import android.graphics.SurfaceTexture;
13   -import android.graphics.YuvImage;
14   -import android.hardware.Camera;
15   -import android.os.Build;
16   -import android.util.Log;
17   -import android.view.TextureView;
18   -import android.view.View;
19   -import android.widget.FrameLayout;
20   -
21   -import com.cnlive.core.libs.base.util.AlertUtil;
22   -
23   -import java.io.ByteArrayOutputStream;
24   -import java.io.IOException;
25   -import java.util.ArrayList;
26   -import java.util.Collections;
27   -import java.util.Comparator;
28   -import java.util.List;
29   -import java.util.concurrent.atomic.AtomicBoolean;
30   -
31   -import androidx.core.app.ActivityCompat;
32   -
33   -/**
34   - * 5.0以下相机API的封装。
35   - */
36   -@SuppressWarnings("deprecation")
37   -public class Camera1Control implements ICameraControl {
38   -
39   - private int displayOrientation = 0;
40   - private int cameraId = 0;
41   - private int flashMode;
42   - private AtomicBoolean takingPicture = new AtomicBoolean(false);
43   - private AtomicBoolean abortingScan = new AtomicBoolean(false);
44   - private Context context;
45   - private Camera camera;
46   -
47   - private Camera.Parameters parameters;
48   - private PermissionCallback permissionCallback;
49   - private Rect previewFrame = new Rect();
50   -
51   - private PreviewView previewView;
52   - private View displayView;
53   - private int rotation = 0;
54   - private OnDetectPictureCallback detectCallback;
55   - private int previewFrameCount = 0;
56   - private Camera.Size optSize;
57   -
58   - /*
59   - * 非扫描模式
60   - */
61   - private final int MODEL_NOSCAN = 0;
62   -
63   - /*
64   - * 本地质量控制扫描模式
65   - */
66   - private final int MODEL_SCAN = 1;
67   -
68   - private int detectType = MODEL_NOSCAN;
69   -
70   - public int getCameraRotation() {
71   - return rotation;
72   - }
73   -
74   - public AtomicBoolean getAbortingScan() {
75   - return abortingScan;
76   - }
77   -
78   - @Override
79   - public void setDetectCallback(OnDetectPictureCallback callback) {
80   - detectType = MODEL_SCAN;
81   - detectCallback = callback;
82   - }
83   -
84   - private void onRequestDetect(byte[] data) {
85   - // 相机已经关闭
86   - if (camera == null || data == null) {
87   - return;
88   - }
89   -
90   - YuvImage img = new YuvImage(data, ImageFormat.NV21, optSize.width, optSize.height, null);
91   - ByteArrayOutputStream os = null;
92   - try {
93   - os = new ByteArrayOutputStream(data.length);
94   - img.compressToJpeg(new Rect(0, 0, optSize.width, optSize.height), 80, os);
95   - byte[] jpeg = os.toByteArray();
96   - int status = detectCallback.onDetect(jpeg, getCameraRotation());
97   -
98   - if (status == 0) {
99   - clearPreviewCallback();
100   - }
101   - } catch (OutOfMemoryError e) {
102   - // 内存溢出则取消当次操作
103   - } finally {
104   - try {
105   - os.close();
106   - } catch (Throwable e) {
107   - e.printStackTrace();
108   - }
109   - }
110   -
111   - }
112   -
113   - @Override
114   - public void setDisplayOrientation(@CameraView.Orientation int displayOrientation) {
115   - this.displayOrientation = displayOrientation;
116   - switch (displayOrientation) {
117   - case CameraView.ORIENTATION_PORTRAIT:
118   - rotation = 90;
119   - break;
120   - case CameraView.ORIENTATION_HORIZONTAL:
121   - rotation = 0;
122   - break;
123   - case CameraView.ORIENTATION_INVERT:
124   - rotation = 180;
125   - break;
126   - default:
127   - rotation = 0;
128   - }
129   - previewView.requestLayout();
130   - }
131   -
132   - /**
133   - * {@inheritDoc}
134   - */
135   - @Override
136   - public void refreshPermission() {
137   - startPreview(true);
138   - }
139   -
140   - /**
141   - * {@inheritDoc}
142   - */
143   - @Override
144   - public void setFlashMode(@FlashMode int flashMode) {
145   - if (this.flashMode == flashMode) {
146   - return;
147   - }
148   - this.flashMode = flashMode;
149   - updateFlashMode(flashMode);
150   - }
151   -
152   - @Override
153   - public int getFlashMode() {
154   - return flashMode;
155   - }
156   -
157   - @Override
158   - public void start() {
159   -
160   - }
161   -
162   - @Override
163   - public void stop() {
164   - if (camera != null) {
165   - camera.setPreviewCallback(null);
166   - stopPreview();
167   - // 避免同步代码,为了先设置null后release
168   - Camera tempC = camera;
169   - camera = null;
170   - tempC.release();
171   - camera = null;
172   - buffer = null;
173   - }
174   - }
175   -
176   - private void stopPreview() {
177   - if (camera != null) {
178   - camera.stopPreview();
179   - }
180   - }
181   -
182   - @Override
183   - public void pause() {
184   - if (camera != null) {
185   - stopPreview();
186   - }
187   - setFlashMode(FLASH_MODE_OFF);
188   - }
189   -
190   - @Override
191   - public void resume() {
192   - takingPicture.set(false);
193   - if (camera == null) {
194   - openCamera();
195   - } else {
196   - previewView.textureView.setSurfaceTextureListener(surfaceTextureListener);
197   - if (previewView.textureView.isAvailable()) {
198   - startPreview(false);
199   - }
200   - }
201   - }
202   -
203   - @Override
204   - public View getDisplayView() {
205   - return displayView;
206   - }
207   -
208   - @Override
209   - public void takePicture(final OnTakePictureCallback onTakePictureCallback) {
210   - if (takingPicture.get()) {
211   - return;
212   - }
213   - try {
214   - switch (displayOrientation) {
215   - case CameraView.ORIENTATION_PORTRAIT:
216   - parameters.setRotation(90);
217   - break;
218   - case CameraView.ORIENTATION_HORIZONTAL:
219   - parameters.setRotation(0);
220   - break;
221   - case CameraView.ORIENTATION_INVERT:
222   - parameters.setRotation(180);
223   - break;
224   - }
225   - Camera.Size picSize = getOptimalSize(camera.getParameters().getSupportedPictureSizes());
226   - parameters.setPictureSize(picSize.width, picSize.height);
227   - camera.setParameters(parameters);
228   - takingPicture.set(true);
229   -
230   - camera.takePicture(null, null, new Camera.PictureCallback() {
231   - @Override
232   - public void onPictureTaken(byte[] data, Camera camera) {
233   - startPreview(false);
234   - takingPicture.set(false);
235   - if (onTakePictureCallback != null) {
236   - onTakePictureCallback.onPictureTaken(data);
237   - }
238   - }
239   - });
240   - } catch (RuntimeException e) {
241   - e.printStackTrace();
242   - startPreview(false);
243   - ;
244   - takingPicture.set(false);
245   - }
246   - }
247   -
248   - @Override
249   - public void setPermissionCallback(PermissionCallback callback) {
250   - this.permissionCallback = callback;
251   - }
252   -
253   - public Camera1Control(Context context) {
254   - this.context = context;
255   - previewView = new PreviewView(context);
256   - openCamera();
257   - }
258   -
259   - private void openCamera() {
260   - setupDisplayView();
261   - }
262   -
263   - private void setupDisplayView() {
264   - final TextureView textureView = new TextureView(context);
265   - previewView.textureView = textureView;
266   - previewView.setTextureView(textureView);
267   - displayView = previewView;
268   - textureView.setSurfaceTextureListener(surfaceTextureListener);
269   - }
270   -
271   - private SurfaceTexture surfaceCache;
272   -
273   - private byte[] buffer = null;
274   -
275   - private void setPreviewCallbackImpl() {
276   - if (buffer == null) {
277   - buffer = new byte[displayView.getWidth()
278   - * displayView.getHeight() * ImageFormat.getBitsPerPixel(ImageFormat.NV21) / 8];
279   - }
280   - if (camera != null && detectType == MODEL_SCAN) {
281   - camera.addCallbackBuffer(buffer);
282   - camera.setPreviewCallback(previewCallback);
283   - }
284   - }
285   -
286   - private void clearPreviewCallback() {
287   - if (camera != null && detectType == MODEL_SCAN) {
288   - camera.setPreviewCallback(null);
289   - stopPreview();
290   - }
291   - }
292   -
293   - Camera.PreviewCallback previewCallback = new Camera.PreviewCallback() {
294   - @Override
295   - public void onPreviewFrame(final byte[] data, Camera camera) {
296   - // 扫描成功阻止打开新线程处理
297   - if (abortingScan.get()) {
298   - return;
299   - }
300   - // 节流
301   - if (previewFrameCount++ % 5 != 0) {
302   - return;
303   - }
304   -
305   - // 在某些机型和某项项目中,某些帧的data的数据不符合nv21的格式,需要过滤,否则后续处理会导致crash
306   - if (data.length != parameters.getPreviewSize().width * parameters.getPreviewSize().height * 1.5) {
307   - return;
308   - }
309   -
310   - camera.addCallbackBuffer(buffer);
311   -
312   - CameraThreadPool.execute(new Runnable() {
313   - @Override
314   - public void run() {
315   - Camera1Control.this.onRequestDetect(data);
316   - }
317   - });
318   - }
319   - };
320   -
321   -
322   - private void initCamera() {
323   - try {
324   - if (camera == null) {
325   - Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
326   - for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
327   - Camera.getCameraInfo(i, cameraInfo);
328   - if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
329   - cameraId = i;
330   - }
331   - }
332   - try {
333   - camera = Camera.open(cameraId);
334   - } catch (Throwable e) {
335   - e.printStackTrace();
336   - startPreview(true);
337   - return;
338   - }
339   -
340   - }
341   - if (parameters == null) {
342   - parameters = camera.getParameters();
343   - parameters.setPreviewFormat(ImageFormat.NV21);
344   - }
345   - opPreviewSize(previewView.getWidth(), previewView.getHeight());
346   - camera.setPreviewTexture(surfaceCache);
347   - setPreviewCallbackImpl();
348   - startPreview(false);
349   - } catch (IOException e) {
350   - e.printStackTrace();
351   - }
352   - }
353   -
354   - private TextureView.SurfaceTextureListener surfaceTextureListener = new TextureView.SurfaceTextureListener() {
355   - @Override
356   - public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
357   - surfaceCache = surface;
358   - initCamera();
359   - }
360   -
361   - @Override
362   - public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
363   - opPreviewSize(previewView.getWidth(), previewView.getHeight());
364   - setPreviewCallbackImpl();
365   - }
366   -
367   - @Override
368   - public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
369   - return false;
370   - }
371   -
372   - @Override
373   - public void onSurfaceTextureUpdated(SurfaceTexture surface) {
374   - setPreviewCallbackImpl();
375   - }
376   - };
377   -
378   - // 开启预览
379   - private void startPreview(boolean checkPermission) {
380   - if (ActivityCompat.checkSelfPermission(context, Manifest.permission.CAMERA)
381   - != PackageManager.PERMISSION_GRANTED) {
382   - if (checkPermission && permissionCallback != null) {
383   - permissionCallback.onRequestPermission();
384   - }
385   - return;
386   - }
387   - if (camera == null) {
388   - initCamera();
389   - } else {
390   - try {
391   - camera.startPreview();
392   - CameraThreadPool.createAutoFocusTimerTask(new Runnable() {
393   - @Override
394   - public void run() {
395   - synchronized (Camera1Control.this) {
396   - if (camera != null && !takingPicture.get()) {
397   - try {
398   - camera.autoFocus(new Camera.AutoFocusCallback() {
399   - @Override
400   - public void onAutoFocus(boolean success, Camera camera) {
401   - }
402   - });
403   - } catch (Throwable e) {
404   - // startPreview是异步实现,可能在某些机器上前几次调用会autofocus failß
405   - }
406   - }
407   - }
408   - }
409   - });
410   - } catch (Exception e) {
411   - Log.e("ocr_ui startPreview", "startPreview: " + (e == null ? "" : e.getMessage()));
412   - }
413   - }
414   - }
415   -
416   - private void opPreviewSize(int width, @SuppressWarnings("unused") int height) {
417   -
418   - if (parameters != null && camera != null && width > 0) {
419   - try {
420   - optSize = getOptimalSize(camera.getParameters().getSupportedPreviewSizes());
421   - }catch (Exception e){
422   - e.printStackTrace();
423   - }
424   - optSize = getOptimalSize(camera.getParameters().getSupportedPreviewSizes());
425   - parameters.setPreviewSize(optSize.width, optSize.height);
426   - previewView.setRatio(1.0f * optSize.width / optSize.height);
427   -
428   - camera.setDisplayOrientation(getSurfaceOrientation());
429   - stopPreview();
430   - try {
431   - camera.setParameters(parameters);
432   - } catch (RuntimeException e) {
433   - e.printStackTrace();
434   -
435   - }
436   - startPreview(false);
437   - }
438   - }
439   -
440   - private Camera.Size getOptimalSize(List<Camera.Size> sizes) {
441   - int width = previewView.textureView.getWidth();
442   - int height = previewView.textureView.getHeight();
443   - Camera.Size pictureSize = sizes.get(0);
444   -
445   - List<Camera.Size> candidates = new ArrayList<>();
446   -
447   - for (Camera.Size size : sizes) {
448   - if (size.width >= width && size.height >= height && size.width * height == size.height * width) {
449   - // 比例相同
450   - candidates.add(size);
451   - } else if (size.height >= width && size.width >= height && size.width * width == size.height * height) {
452   - // 反比例
453   - candidates.add(size);
454   - }
455   - }
456   - if (!candidates.isEmpty()) {
457   - return Collections.min(candidates, sizeComparator);
458   - }
459   -
460   - for (Camera.Size size : sizes) {
461   - if (size.width > width && size.height > height) {
462   - return size;
463   - }
464   - }
465   -
466   - return pictureSize;
467   - }
468   -
469   - private Comparator<Camera.Size> sizeComparator = new Comparator<Camera.Size>() {
470   - @Override
471   - public int compare(Camera.Size lhs, Camera.Size rhs) {
472   - return Long.signum((long) lhs.width * lhs.height - (long) rhs.width * rhs.height);
473   - }
474   - };
475   -
476   - private void updateFlashMode(int flashMode) {
477   - switch (flashMode) {
478   - case FLASH_MODE_TORCH:
479   - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
480   - try {
481   - parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
482   - } catch (Exception e) {
483   - e.printStackTrace();
484   - }
485   - }else {
486   - boolean isUse = false;
487   - PackageManager packageManager = context.getPackageManager();
488   - FeatureInfo[] features = packageManager.getSystemAvailableFeatures();
489   - for (FeatureInfo featureInfo : features) {
490   - if (PackageManager.FEATURE_CAMERA_FLASH.equals(featureInfo.name)) { // 断设备是否支持闪光灯
491   - try {
492   - parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
493   - isUse = true;
494   - } catch (Exception e) {
495   - e.printStackTrace();
496   - }
497   - }
498   - }
499   - if(!isUse) AlertUtil.showDeftToast(context,"该设备不支持闪光灯");
500   - }
501   - break;
502   - case FLASH_MODE_OFF:
503   - parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
504   - break;
505   - case ICameraControl.FLASH_MODE_AUTO:
506   - parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
507   - break;
508   - default:
509   - parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
510   - break;
511   - }
512   - if (parameters == null || camera == null)
513   - return;
514   - camera.setParameters(parameters);
515   - }
516   -
517   - private int getSurfaceOrientation() {
518   - @CameraView.Orientation
519   - int orientation = displayOrientation;
520   - switch (orientation) {
521   - case CameraView.ORIENTATION_PORTRAIT:
522   - return 90;
523   - case CameraView.ORIENTATION_HORIZONTAL:
524   - return 0;
525   - case CameraView.ORIENTATION_INVERT:
526   - return 180;
527   - default:
528   - return 90;
529   - }
530   - }
531   -
532   - /**
533   - * 有些相机匹配不到完美的比例。比如。我们的layout是4:3的。预览只有16:9
534   - * 的,如果直接显示图片会拉伸,变形。缩放的话,又有黑边。所以我们采取的策略
535   - * 是,等比例放大。这样预览的有一部分会超出屏幕。拍照后再进行裁剪处理。
536   - */
537   - private class PreviewView extends FrameLayout {
538   -
539   - private TextureView textureView;
540   -
541   - private float ratio = 0.75f;
542   -
543   - void setTextureView(TextureView textureView) {
544   - this.textureView = textureView;
545   - removeAllViews();
546   - addView(textureView);
547   - }
548   -
549   - void setRatio(float ratio) {
550   - this.ratio = ratio;
551   - requestLayout();
552   - relayout(getWidth(), getHeight());
553   - }
554   -
555   - public PreviewView(Context context) {
556   - super(context);
557   - }
558   -
559   - @Override
560   - protected void onSizeChanged(int w, int h, int oldw, int oldh) {
561   - super.onSizeChanged(w, h, oldw, oldh);
562   - relayout(w, h);
563   - }
564   -
565   - private void relayout(int w, int h) {
566   - int width = w;
567   - int height = h;
568   - if (w < h) {
569   - // 垂直模式,高度固定。
570   - height = (int) (width * ratio);
571   - } else {
572   - // 水平模式,宽度固定。
573   - width = (int) (height * ratio);
574   - }
575   -
576   - int l = (getWidth() - width) / 2;
577   - int t = (getHeight() - height) / 2;
578   -
579   - previewFrame.left = l;
580   - previewFrame.top = t;
581   - previewFrame.right = l + width;
582   - previewFrame.bottom = t + height;
583   - }
584   -
585   - @Override
586   - protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
587   - super.onLayout(changed, left, top, right, bottom);
588   - textureView.layout(previewFrame.left, previewFrame.top, previewFrame.right, previewFrame.bottom);
589   - }
590   - }
591   -
592   - @Override
593   - public Rect getPreviewFrame() {
594   - return previewFrame;
595   - }
596   -}
core/dentity_verfication/src/main/java/com/cnlive/core/ocr/ui/camera/Camera2Control.java deleted 100644 → 0
1   -/*
2   - * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
3   - */
4   -
5   -package com.cnlive.core.ocr.ui.camera;
6   -
7   -import android.Manifest;
8   -import android.annotation.SuppressLint;
9   -import android.annotation.TargetApi;
10   -import android.content.Context;
11   -import android.content.pm.PackageManager;
12   -import android.graphics.ImageFormat;
13   -import android.graphics.Matrix;
14   -import android.graphics.Point;
15   -import android.graphics.Rect;
16   -import android.graphics.RectF;
17   -import android.graphics.SurfaceTexture;
18   -import android.hardware.camera2.CameraAccessException;
19   -import android.hardware.camera2.CameraCaptureSession;
20   -import android.hardware.camera2.CameraCharacteristics;
21   -import android.hardware.camera2.CameraDevice;
22   -import android.hardware.camera2.CameraManager;
23   -import android.hardware.camera2.CameraMetadata;
24   -import android.hardware.camera2.CaptureFailure;
25   -import android.hardware.camera2.CaptureRequest;
26   -import android.hardware.camera2.CaptureResult;
27   -import android.hardware.camera2.TotalCaptureResult;
28   -import android.hardware.camera2.params.StreamConfigurationMap;
29   -import android.media.Image;
30   -import android.media.ImageReader;
31   -import android.os.Build;
32   -import android.os.Handler;
33   -import android.os.HandlerThread;
34   -import android.util.Size;
35   -import android.util.SparseIntArray;
36   -import android.view.Surface;
37   -import android.view.TextureView;
38   -import android.view.View;
39   -import android.view.WindowManager;
40   -
41   -import java.nio.ByteBuffer;
42   -import java.util.ArrayList;
43   -import java.util.Arrays;
44   -import java.util.Collections;
45   -import java.util.Comparator;
46   -import java.util.List;
47   -import java.util.concurrent.Semaphore;
48   -import java.util.concurrent.TimeUnit;
49   -import java.util.concurrent.atomic.AtomicBoolean;
50   -
51   -import androidx.annotation.NonNull;
52   -import androidx.core.content.ContextCompat;
53   -
54   -@TargetApi(Build.VERSION_CODES.LOLLIPOP)
55   -public class Camera2Control implements ICameraControl {
56   - @Override
57   - public void setDetectCallback(OnDetectPictureCallback callback) {
58   - // TODO 暂时只用camera
59   - }
60   -
61   - @Override
62   - public AtomicBoolean getAbortingScan() {
63   - // TODO 暂时只用camera
64   - return null;
65   - }
66   -
67   - /**
68   - * Conversion from screen rotation to JPEG orientation.
69   - */
70   - private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
71   - private static final int MAX_PREVIEW_SIZE = 2048;
72   -
73   - static {
74   - ORIENTATIONS.append(Surface.ROTATION_0, 90);
75   - ORIENTATIONS.append(Surface.ROTATION_90, 0);
76   - ORIENTATIONS.append(Surface.ROTATION_180, 270);
77   - ORIENTATIONS.append(Surface.ROTATION_270, 180);
78   - }
79   -
80   - private static final int STATE_PREVIEW = 0;
81   - private static final int STATE_WAITING_FOR_LOCK = 1;
82   - private static final int STATE_WAITING_FOR_CAPTURE = 2;
83   - private static final int STATE_CAPTURING = 3;
84   - private static final int STATE_PICTURE_TAKEN = 4;
85   -
86   - private static final int MAX_PREVIEW_WIDTH = 1920;
87   - private static final int MAX_PREVIEW_HEIGHT = 1080;
88   -
89   - private int flashMode;
90   - private int orientation = 0;
91   - private int state = STATE_PREVIEW;
92   -
93   - private Context context;
94   - private OnTakePictureCallback onTakePictureCallback;
95   - private PermissionCallback permissionCallback;
96   -
97   - private String cameraId;
98   - private TextureView textureView;
99   - private Size previewSize;
100   - private Rect previewFrame = new Rect();
101   -
102   - private HandlerThread backgroundThread;
103   - private Handler backgroundHandler;
104   - private ImageReader imageReader;
105   - private CameraCaptureSession captureSession;
106   - private CameraDevice cameraDevice;
107   -
108   - private CaptureRequest.Builder previewRequestBuilder;
109   - private CaptureRequest previewRequest;
110   -
111   - private Semaphore cameraLock = new Semaphore(1);
112   - private int sensorOrientation;
113   -
114   - @Override
115   - public void start() {
116   - startBackgroundThread();
117   - if (textureView.isAvailable()) {
118   - openCamera(textureView.getWidth(), textureView.getHeight());
119   - textureView.setSurfaceTextureListener(surfaceTextureListener);
120   - } else {
121   - textureView.setSurfaceTextureListener(surfaceTextureListener);
122   - }
123   - }
124   -
125   - @Override
126   - public void stop() {
127   - textureView.setSurfaceTextureListener(null);
128   - closeCamera();
129   - stopBackgroundThread();
130   - }
131   -
132   - @Override
133   - public void pause() {
134   - setFlashMode(FLASH_MODE_OFF);
135   - }
136   -
137   - @Override
138   - public void resume() {
139   - state = STATE_PREVIEW;
140   - }
141   -
142   - @Override
143   - public View getDisplayView() {
144   - return textureView;
145   - }
146   -
147   - @Override
148   - public Rect getPreviewFrame() {
149   - return previewFrame;
150   - }
151   -
152   - @Override
153   - public void takePicture(OnTakePictureCallback callback) {
154   - this.onTakePictureCallback = callback;
155   - // 拍照第一步,对焦
156   - lockFocus();
157   - }
158   -
159   - @Override
160   - public void setPermissionCallback(PermissionCallback callback) {
161   - this.permissionCallback = callback;
162   - }
163   -
164   - @Override
165   - public void setDisplayOrientation(@CameraView.Orientation int displayOrientation) {
166   - this.orientation = displayOrientation / 90;
167   - }
168   -
169   - @Override
170   - public void refreshPermission() {
171   - openCamera(textureView.getWidth(), textureView.getHeight());
172   - }
173   -
174   - @Override
175   - public void setFlashMode(@FlashMode int flashMode) {
176   - if (this.flashMode == flashMode) {
177   - return;
178   - }
179   - this.flashMode = flashMode;
180   - try {
181   - previewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
182   - CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
183   - updateFlashMode(flashMode, previewRequestBuilder);
184   - previewRequest = previewRequestBuilder.build();
185   - captureSession.setRepeatingRequest(previewRequest, captureCallback, backgroundHandler);
186   - } catch (Exception e) {
187   - if (e!=null)
188   - e.printStackTrace();
189   - }
190   - }
191   -
192   - @Override
193   - public int getFlashMode() {
194   - return flashMode;
195   - }
196   -
197   - public Camera2Control(Context activity) {
198   - this.context = activity;
199   - textureView = new TextureView(activity);
200   - }
201   -
202   - private final TextureView.SurfaceTextureListener surfaceTextureListener =
203   - new TextureView.SurfaceTextureListener() {
204   - @Override
205   - public void onSurfaceTextureAvailable(SurfaceTexture texture, int width, int height) {
206   - openCamera(width, height);
207   - }
208   -
209   - @Override
210   - public void onSurfaceTextureSizeChanged(SurfaceTexture texture, int width, int height) {
211   - configureTransform(width, height);
212   - previewFrame.left = 0;
213   - previewFrame.top = 0;
214   - previewFrame.right = width;
215   - previewFrame.bottom = height;
216   - }
217   -
218   - @Override
219   - public boolean onSurfaceTextureDestroyed(SurfaceTexture texture) {
220   - stop();
221   - return true;
222   - }
223   -
224   - @Override
225   - public void onSurfaceTextureUpdated(SurfaceTexture texture) {
226   - }
227   - };
228   -
229   - @SuppressLint("MissingPermission")
230   - private void openCamera(int width, int height) {
231   - // 6.0+的系统需要检查系统权限 。
232   - if (ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA)
233   - != PackageManager.PERMISSION_GRANTED) {
234   - requestCameraPermission();
235   - return;
236   - }
237   - setUpCameraOutputs(width, height);
238   - configureTransform(width, height);
239   - CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
240   - try {
241   - if (!cameraLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {
242   - throw new RuntimeException("Time out waiting to lock camera opening.");
243   - }
244   - manager.openCamera(cameraId, deviceStateCallback, backgroundHandler);
245   - } catch (CameraAccessException e) {
246   - if (e!=null)
247   - e.printStackTrace();
248   - } catch (InterruptedException e) {
249   - if (e!=null)
250   - throw new RuntimeException("Interrupted while trying to lock camera opening.", e);
251   - }
252   - }
253   -
254   - private final CameraDevice.StateCallback deviceStateCallback = new CameraDevice.StateCallback() {
255   - @Override
256   - public void onOpened(@NonNull CameraDevice cameraDevice) {
257   - cameraLock.release();
258   - Camera2Control.this.cameraDevice = cameraDevice;
259   - createCameraPreviewSession();
260   - }
261   -
262   - @Override
263   - public void onDisconnected(@NonNull CameraDevice cameraDevice) {
264   - cameraLock.release();
265   - cameraDevice.close();
266   - Camera2Control.this.cameraDevice = null;
267   - }
268   -
269   - @Override
270   - public void onError(@NonNull CameraDevice cameraDevice, int error) {
271   - cameraLock.release();
272   - cameraDevice.close();
273   - Camera2Control.this.cameraDevice = null;
274   - }
275   - };
276   -
277   - private void createCameraPreviewSession() {
278   - try {
279   - SurfaceTexture texture = textureView.getSurfaceTexture();
280   - assert texture != null;
281   - texture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());
282   - Surface surface = new Surface(texture);
283   - previewRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
284   - previewRequestBuilder.addTarget(surface);
285   - updateFlashMode(this.flashMode, previewRequestBuilder);
286   - cameraDevice.createCaptureSession(Arrays.asList(surface, imageReader.getSurface()),
287   - new CameraCaptureSession.StateCallback() {
288   -
289   - @Override
290   - public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
291   - // The camera is already closed
292   - if (null == cameraDevice) {
293   - return;
294   - }
295   - captureSession = cameraCaptureSession;
296   - try {
297   - previewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
298   - CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
299   - previewRequest = previewRequestBuilder.build();
300   - captureSession.setRepeatingRequest(previewRequest,
301   - captureCallback, backgroundHandler);
302   - } catch (CameraAccessException e) {
303   - if (e!=null)
304   - e.printStackTrace();
305   - }
306   - }
307   -
308   - @Override
309   - public void onConfigureFailed(
310   - @NonNull CameraCaptureSession cameraCaptureSession) {
311   - // TODO
312   - }
313   - }, null
314   - );
315   - } catch (CameraAccessException e) {
316   - if (e!=null)
317   - e.printStackTrace();
318   - }
319   - }
320   -
321   - private final ImageReader.OnImageAvailableListener onImageAvailableListener =
322   - new ImageReader.OnImageAvailableListener() {
323   - @Override
324   - public void onImageAvailable(ImageReader reader) {
325   - if (onTakePictureCallback != null) {
326   - Image image = reader.acquireNextImage();
327   - ByteBuffer buffer = image.getPlanes()[0].getBuffer();
328   - byte[] bytes = new byte[buffer.remaining()];
329   - buffer.get(bytes);
330   -
331   - image.close();
332   - onTakePictureCallback.onPictureTaken(bytes);
333   - }
334   - }
335   - };
336   -
337   - private CameraCaptureSession.CaptureCallback captureCallback =
338   - new CameraCaptureSession.CaptureCallback() {
339   - private void process(CaptureResult result) {
340   - switch (state) {
341   - case STATE_PREVIEW: {
342   - break;
343   - }
344   - case STATE_WAITING_FOR_LOCK: {
345   - Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
346   - if (afState == null) {
347   - captureStillPicture();
348   - return;
349   - }
350   - switch (afState) {
351   - case CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED:
352   - case CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
353   - case CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED: {
354   - Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
355   - if (aeState == null
356   - || aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED) {
357   - captureStillPicture();
358   - } else {
359   - runPreCaptureSequence();
360   - }
361   - break;
362   - }
363   - default:
364   - captureStillPicture();
365   - }
366   - break;
367   - }
368   - case STATE_WAITING_FOR_CAPTURE: {
369   - Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
370   - if (aeState == null
371   - || aeState == CaptureResult.CONTROL_AE_STATE_PRECAPTURE
372   - || aeState == CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED) {
373   - state = STATE_CAPTURING;
374   - } else {
375   - if (aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED) {
376   - captureStillPicture();
377   - }
378   - }
379   - break;
380   - }
381   - case STATE_CAPTURING: {
382   - Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
383   - if (aeState == null || aeState != CaptureResult.CONTROL_AE_STATE_PRECAPTURE) {
384   - captureStillPicture();
385   - }
386   - break;
387   - }
388   - default:
389   - break;
390   - }
391   - }
392   -
393   - @Override
394   - public void onCaptureProgressed(@NonNull CameraCaptureSession session,
395   - @NonNull CaptureRequest request,
396   - @NonNull CaptureResult partialResult) {
397   - process(partialResult);
398   - }
399   -
400   - @Override
401   - public void onCaptureCompleted(@NonNull CameraCaptureSession session,
402   - @NonNull CaptureRequest request,
403   - @NonNull TotalCaptureResult result) {
404   - process(result);
405   - }
406   -
407   - };
408   -
409   - private Size getOptimalSize(Size[] choices, int textureViewWidth,
410   - int textureViewHeight, int maxWidth, int maxHeight, Size aspectRatio) {
411   - List<Size> bigEnough = new ArrayList<>();
412   - List<Size> notBigEnough = new ArrayList<>();
413   - int w = aspectRatio.getWidth();
414   - int h = aspectRatio.getHeight();
415   - for (Size option : choices) {
416   - if (option.getWidth() <= maxWidth && option.getHeight() <= maxHeight
417   - && option.getHeight() == option.getWidth() * h / w) {
418   - if (option.getWidth() >= textureViewWidth
419   - && option.getHeight() >= textureViewHeight) {
420   - bigEnough.add(option);
421   - } else {
422   - notBigEnough.add(option);
423   - }
424   - }
425   - }
426   -
427   - // Pick the smallest of those big enough. If there is no one big enough, pick the
428   - // largest of those not big enough.
429   - if (bigEnough.size() > 0) {
430   - return Collections.min(bigEnough, sizeComparator);
431   - }
432   -
433   - for (Size option : choices) {
434   - if (option.getWidth() >= maxWidth && option.getHeight() >= maxHeight) {
435   - return option;
436   - }
437   - }
438   -
439   - if (notBigEnough.size() > 0) {
440   - return Collections.max(notBigEnough, sizeComparator);
441   - }
442   -
443   - return choices[0];
444   - }
445   -
446   - private Comparator<Size> sizeComparator = new Comparator<Size>() {
447   - @Override
448   - public int compare(Size lhs, Size rhs) {
449   - return Long.signum((long) lhs.getWidth() * lhs.getHeight() - (long) rhs.getWidth() * rhs.getHeight());
450   - }
451   - };
452   -
453   - private void requestCameraPermission() {
454   - if (permissionCallback != null) {
455   - permissionCallback.onRequestPermission();
456   - }
457   - }
458   -
459   - @SuppressWarnings("SuspiciousNameCombination")
460   - private void setUpCameraOutputs(int width, int height) {
461   - CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
462   - try {
463   - for (String cameraId : manager.getCameraIdList()) {
464   - CameraCharacteristics characteristics =
465   - manager.getCameraCharacteristics(cameraId);
466   -
467   - Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
468   - if (facing != null && facing == CameraCharacteristics.LENS_FACING_FRONT) {
469   - continue;
470   - }
471   -
472   - StreamConfigurationMap map = characteristics.get(
473   - CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
474   - if (map == null) {
475   - continue;
476   - }
477   -
478   - // int preferredPictureSize = (int) (Math.max(textureView.getWidth(), textureView
479   - // .getHeight()) * 1.5);
480   - // preferredPictureSize = Math.min(preferredPictureSize, 2560);
481   -
482   - WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
483   - Point screenSize = new Point();
484   - windowManager.getDefaultDisplay().getSize(screenSize);
485   - int maxImageSize = Math.max(MAX_PREVIEW_SIZE, screenSize.y * 3 / 2);
486   -
487   - Size size = getOptimalSize(map.getOutputSizes(ImageFormat.JPEG), textureView.getWidth(),
488   - textureView.getHeight(), maxImageSize, maxImageSize, new Size(4, 3));
489   -
490   - imageReader = ImageReader.newInstance(size.getWidth(), size.getHeight(),
491   - ImageFormat.JPEG, 1);
492   - imageReader.setOnImageAvailableListener(
493   - onImageAvailableListener, backgroundHandler);
494   -
495   - int displayRotation = orientation;
496   - // noinspection ConstantConditions
497   - sensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
498   - boolean swappedDimensions = false;
499   - switch (displayRotation) {
500   - case Surface.ROTATION_0:
501   - case Surface.ROTATION_180:
502   - if (sensorOrientation == 90 || sensorOrientation == 270) {
503   - swappedDimensions = true;
504   - }
505   - break;
506   - case Surface.ROTATION_90:
507   - case Surface.ROTATION_270:
508   - if (sensorOrientation == 0 || sensorOrientation == 180) {
509   - swappedDimensions = true;
510   - }
511   - break;
512   - default:
513   - }
514   -
515   - int rotatedPreviewWidth = width;
516   - int rotatedPreviewHeight = height;
517   - int maxPreviewWidth = screenSize.x;
518   - int maxPreviewHeight = screenSize.y;
519   -
520   - if (swappedDimensions) {
521   - rotatedPreviewWidth = height;
522   - rotatedPreviewHeight = width;
523   - maxPreviewWidth = screenSize.y;
524   - maxPreviewHeight = screenSize.x;
525   - }
526   -
527   - maxPreviewWidth = Math.min(maxPreviewWidth, MAX_PREVIEW_WIDTH);
528   - maxPreviewHeight = Math.min(maxPreviewHeight, MAX_PREVIEW_HEIGHT);
529   -
530   - previewSize = getOptimalSize(map.getOutputSizes(SurfaceTexture.class),
531   - rotatedPreviewWidth, rotatedPreviewHeight, maxPreviewWidth,
532   - maxPreviewHeight, size);
533   - this.cameraId = cameraId;
534   - return;
535   - }
536   - } catch (CameraAccessException | NullPointerException e) {
537   - if (e!=null)
538   - e.printStackTrace();
539   - }
540   - }
541   -
542   - private void closeCamera() {
543   - try {
544   - cameraLock.acquire();
545   - if (null != captureSession) {
546   - captureSession.close();
547   - captureSession = null;
548   - }
549   - if (null != cameraDevice) {
550   - cameraDevice.close();
551   - cameraDevice = null;
552   - }
553   - if (null != imageReader) {
554   - imageReader.close();
555   - imageReader = null;
556   - }
557   - } catch (InterruptedException e) {
558   - throw new RuntimeException("Interrupted while trying to lock camera closing.", e);
559   - } finally {
560   - cameraLock.release();
561   - }
562   - }
563   -
564   - private void startBackgroundThread() {
565   - backgroundThread = new HandlerThread("ocr_camera");
566   - backgroundThread.start();
567   - backgroundHandler = new Handler(backgroundThread.getLooper());
568   - }
569   -
570   - private void stopBackgroundThread() {
571   - if (backgroundThread != null) {
572   - backgroundThread.quitSafely();
573   - backgroundThread = null;
574   - backgroundHandler = null;
575   - }
576   - }
577   -
578   - private void configureTransform(int viewWidth, int viewHeight) {
579   - if (null == textureView || null == previewSize || null == context) {
580   - return;
581   - }
582   - int rotation = orientation;
583   - Matrix matrix = new Matrix();
584   - RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);
585   - RectF bufferRect = new RectF(0, 0, previewSize.getHeight(), previewSize.getWidth());
586   - float centerX = viewRect.centerX();
587   - float centerY = viewRect.centerY();
588   - if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {
589   - bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());
590   - matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);
591   - float scale = Math.max(
592   - (float) viewHeight / previewSize.getHeight(),
593   - (float) viewWidth / previewSize.getWidth());
594   - matrix.postScale(scale, scale, centerX, centerY);
595   - matrix.postRotate(90 * (rotation - 2), centerX, centerY);
596   - } else if (Surface.ROTATION_180 == rotation) {
597   - matrix.postRotate(180, centerX, centerY);
598   - }
599   - textureView.setTransform(matrix);
600   - }
601   -
602   - // 拍照前,先对焦
603   - private void lockFocus() {
604   - if (captureSession != null && state == STATE_PREVIEW) {
605   - try {
606   - previewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
607   - CameraMetadata.CONTROL_AF_TRIGGER_START);
608   - state = STATE_WAITING_FOR_LOCK;
609   - captureSession.capture(previewRequestBuilder.build(), captureCallback,
610   - backgroundHandler);
611   - } catch (CameraAccessException e) {
612   - if (e!=null)
613   - e.printStackTrace();
614   - }
615   - }
616   - }
617   -
618   - private void runPreCaptureSequence() {
619   - try {
620   - previewRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
621   - CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
622   - state = STATE_WAITING_FOR_CAPTURE;
623   - captureSession.capture(previewRequestBuilder.build(), captureCallback,
624   - backgroundHandler);
625   - } catch (CameraAccessException e) {
626   - if (e!=null)
627   - e.printStackTrace();
628   - }
629   - }
630   -
631   - // 拍照session
632   - private void captureStillPicture() {
633   - try {
634   - if (null == context || null == cameraDevice) {
635   - return;
636   - }
637   - final CaptureRequest.Builder captureBuilder =
638   - cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
639   - captureBuilder.addTarget(imageReader.getSurface());
640   - captureBuilder.set(CaptureRequest.CONTROL_AF_MODE,
641   - CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
642   -
643   - captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, getOrientation(orientation));
644   - updateFlashMode(this.flashMode, captureBuilder);
645   - CameraCaptureSession.CaptureCallback captureCallback =
646   - new CameraCaptureSession.CaptureCallback() {
647   - @Override
648   - public void onCaptureCompleted(@NonNull CameraCaptureSession session,
649   - @NonNull CaptureRequest request,
650   - @NonNull TotalCaptureResult result) {
651   - unlockFocus();
652   - }
653   -
654   - @Override
655   - public void onCaptureFailed(@NonNull CameraCaptureSession session,
656   - @NonNull CaptureRequest request,
657   - @NonNull CaptureFailure failure) {
658   - super.onCaptureFailed(session, request, failure);
659   - }
660   - };
661   -
662   - // 停止预览
663   - captureSession.stopRepeating();
664   - captureSession.capture(captureBuilder.build(), captureCallback, backgroundHandler);
665   - state = STATE_PICTURE_TAKEN;
666   - // unlockFocus();
667   - } catch (CameraAccessException e) {
668   - if (e!=null)
669   - e.printStackTrace();
670   - }
671   - }
672   -
673   - private int getOrientation(int rotation) {
674   - return (ORIENTATIONS.get(rotation) + sensorOrientation + 270) % 360;
675   - }
676   -
677   - // 停止对焦
678   - private void unlockFocus() {
679   - try {
680   - previewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
681   - CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
682   - captureSession.capture(previewRequestBuilder.build(), captureCallback,
683   - backgroundHandler);
684   - state = STATE_PREVIEW;
685   - // 预览
686   - captureSession.setRepeatingRequest(previewRequest, captureCallback,
687   - backgroundHandler);
688   - textureView.setSurfaceTextureListener(surfaceTextureListener);
689   - } catch (CameraAccessException e) {
690   - if (e!=null)
691   - e.printStackTrace();
692   - }
693   - }
694   -
695   - private void updateFlashMode(@FlashMode int flashMode, CaptureRequest.Builder builder) {
696   - switch (flashMode) {
697   - case FLASH_MODE_TORCH:
698   - builder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_TORCH);
699   - break;
700   - case FLASH_MODE_OFF:
701   - builder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_OFF);
702   - break;
703   - case ICameraControl.FLASH_MODE_AUTO:
704   - default:
705   - builder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_SINGLE);
706   - break;
707   - }
708   - }
709   -}
core/dentity_verfication/src/main/java/com/cnlive/core/ocr/ui/camera/CameraActivity.java deleted 100644 → 0
1   -/*
2   - * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
3   - */
4   -package com.cnlive.core.ocr.ui.camera;
5   -
6   -import android.Manifest;
7   -import android.app.Activity;
8   -import android.content.Intent;
9   -import android.content.pm.PackageManager;
10   -import android.content.res.Configuration;
11   -import android.graphics.Bitmap;
12   -import android.graphics.Rect;
13   -import android.graphics.drawable.BitmapDrawable;
14   -import android.os.Build;
15   -import android.os.Bundle;
16   -import android.os.Environment;
17   -import android.os.Handler;
18   -import android.view.Surface;
19   -import android.view.View;
20   -import android.widget.ImageView;
21   -import android.widget.Toast;
22   -
23   -import com.cnlive.core.libs.base.util.AlertUtil;
24   -import com.cnlive.core.ocr.idcardquality.IDcardQualityProcess;
25   -import com.cnlive.core.ocr.ui.crop.CropView;
26   -import com.cnlive.core.ocr.ui.crop.FrameOverlayView;
27   -import com.cnlive.core.people_verfication.R;
28   -import com.cnlive.media.picker.ImagePicker;
29   -import com.cnlive.media.picker.PickerConfig;
30   -import com.cnlive.media.picker.entity.Media;
31   -
32   -import java.io.File;
33   -import java.io.FileOutputStream;
34   -import java.io.IOException;
35   -import java.util.ArrayList;
36   -
37   -import androidx.annotation.NonNull;
38   -import androidx.core.app.ActivityCompat;
39   -
40   -public class CameraActivity extends Activity {
41   -
42   - public static final String KEY_OUTPUT_FILE_PATH = "outputFilePath";
43   - public static final String KEY_CONTENT_TYPE = "contentType";
44   - public static final String KEY_NATIVE_TOKEN = "nativeToken";
45   - public static final String KEY_NATIVE_ENABLE = "nativeEnable";
46   -
47   - public static final String CONTENT_TYPE_GENERAL = "general";
48   - public static final String CONTENT_TYPE_ID_CARD_FRONT = "IDCardFront";
49   - public static final String CONTENT_TYPE_ID_CARD_BACK = "IDCardBack";
50   - public static final String CONTENT_TYPE_BANK_CARD = "bankCard";
51   -
52   - private static final int REQUEST_CODE_PICK_IMAGE = 100;
53   - private static final int PERMISSIONS_REQUEST_CAMERA = 800;
54   - private static final int PERMISSIONS_EXTERNAL_STORAGE = 801;
55   -
56   - private File outputFile;
57   - private String contentType;
58   - private Handler handler = new Handler();
59   -
60   - private OCRCameraLayout takePictureContainer;
61   - private OCRCameraLayout cropContainer;
62   - private OCRCameraLayout confirmResultContainer;
63   - private ImageView lightButton;
64   - private CameraView cameraView;
65   - private ImageView displayImageView;
66   - private CropView cropView;
67   - private FrameOverlayView overlayView;
68   - private MaskView cropMaskView;
69   - private ImageView takePhotoBtn;
70   - private ImageView back;
71   - //上一个被点击过的btn的点击时间
72   - private long preViewClickTime = 0;
73   - private PermissionCallback permissionCallback = new PermissionCallback() {
74   - @Override
75   - public boolean onRequestPermission() {
76   - ActivityCompat.requestPermissions(CameraActivity.this,
77   - new String[]{Manifest.permission.CAMERA,
78   - Manifest.permission.WRITE_EXTERNAL_STORAGE,
79   - Manifest.permission.READ_EXTERNAL_STORAGE},
80   - PERMISSIONS_REQUEST_CAMERA);
81   - return false;
82   - }
83   - };
84   -
85   - @Override
86   - protected void onCreate(Bundle savedInstanceState) {
87   -
88   - super.onCreate(savedInstanceState);
89   - setContentView(R.layout.bd_ocr_activity_camera);
90   -
91   - takePictureContainer = (OCRCameraLayout) findViewById(R.id.take_picture_container);
92   - confirmResultContainer = (OCRCameraLayout) findViewById(R.id.confirm_result_container);
93   -
94   - cameraView = (CameraView) findViewById(R.id.camera_view);
95   - cameraView.getCameraControl().setPermissionCallback(permissionCallback);
96   - lightButton = (ImageView) findViewById(R.id.light_button);
97   - lightButton.setOnClickListener(lightButtonOnClickListener);
98   - takePhotoBtn = (ImageView) findViewById(R.id.take_photo_button);
99   - findViewById(R.id.album_button).setOnClickListener(albumButtonOnClickListener);
100   - takePhotoBtn.setOnClickListener(takeButtonOnClickListener);
101   -
102   - // confirm result;
103   - displayImageView = (ImageView) findViewById(R.id.display_image_view);
104   - confirmResultContainer.findViewById(R.id.confirm_button).setOnClickListener(confirmButtonOnClickListener);
105   - confirmResultContainer.findViewById(R.id.cancel_button).setOnClickListener(confirmCancelButtonOnClickListener);
106   - findViewById(R.id.rotate_button).setOnClickListener(rotateButtonOnClickListener);
107   -
108   - cropView = (CropView) findViewById(R.id.crop_view);
109   - cropContainer = (OCRCameraLayout) findViewById(R.id.crop_container);
110   - overlayView = (FrameOverlayView) findViewById(R.id.overlay_view);
111   - cropContainer.findViewById(R.id.confirm_button).setOnClickListener(cropConfirmButtonListener);
112   - cropMaskView = (MaskView) cropContainer.findViewById(R.id.crop_mask_view);
113   - cropContainer.findViewById(R.id.cancel_button).setOnClickListener(cropCancelButtonListener);
114   - back = findViewById(R.id.back);
115   - back.setOnClickListener(finishListener);
116   - setOrientation(getResources().getConfiguration());
117   - initParams();
118   -
119   - cameraView.setAutoPictureCallback(autoTakePictureCallback);
120   - }
121   -
122   - @Override
123   - protected void onStart() {
124   - super.onStart();
125   - cameraView.start();
126   - }
127   -
128   - @Override
129   - protected void onStop() {
130   - super.onStop();
131   - cameraView.stop();
132   - }
133   -
134   - private void initParams() {
135   - String outputPath = getIntent().getStringExtra(KEY_OUTPUT_FILE_PATH);
136   - final String token = getIntent().getStringExtra(KEY_NATIVE_TOKEN);
137   - boolean isNativeEnable = getIntent().getBooleanExtra(KEY_NATIVE_ENABLE, true);
138   - if (token == null) {
139   - isNativeEnable = false;
140   - }
141   -
142   - if (outputPath != null) {
143   - outputFile = new File(outputPath);
144   - }
145   -
146   - contentType = getIntent().getStringExtra(KEY_CONTENT_TYPE);
147   - if (contentType == null) {
148   - contentType = CONTENT_TYPE_GENERAL;
149   - }
150   - int maskType;
151   - switch (contentType) {
152   - case CONTENT_TYPE_ID_CARD_FRONT:
153   - maskType = MaskView.MASK_TYPE_ID_CARD_FRONT;
154   - overlayView.setVisibility(View.INVISIBLE);
155   - if (isNativeEnable) {
156   - takePhotoBtn.setVisibility(View.INVISIBLE);
157   - }
158   - break;
159   - case CONTENT_TYPE_ID_CARD_BACK:
160   - maskType = MaskView.MASK_TYPE_ID_CARD_BACK;
161   - overlayView.setVisibility(View.INVISIBLE);
162   - if (isNativeEnable) {
163   - takePhotoBtn.setVisibility(View.INVISIBLE);
164   - }
165   - break;
166   - case CONTENT_TYPE_BANK_CARD:
167   - maskType = MaskView.MASK_TYPE_BANK_CARD;
168   - overlayView.setVisibility(View.INVISIBLE);
169   - break;
170   - case CONTENT_TYPE_GENERAL:
171   - default:
172   - maskType = MaskView.MASK_TYPE_NONE;
173   - cropMaskView.setVisibility(View.INVISIBLE);
174   - break;
175   - }
176   -
177   - // 身份证本地能力初始化
178   - if (maskType == MaskView.MASK_TYPE_ID_CARD_FRONT || maskType == MaskView.MASK_TYPE_ID_CARD_BACK) {
179   - if (isNativeEnable) {
180   - initNative(token);
181   - }
182   - }
183   - cameraView.setEnableScan(isNativeEnable);
184   - cameraView.setMaskType(maskType, this);
185   - cropMaskView.setMaskType(maskType);
186   - }
187   -
188   - private void initNative(final String token) {
189   - CameraThreadPool.execute(new Runnable() {
190   - @Override
191   - public void run() {
192   - // 加载本地so失败, 异常返回getloadSoException
193   - if (IDcardQualityProcess.getLoadSoException() != null) {
194   - cameraView.setInitNativeStatus(CameraView.NATIVE_SOLOAD_FAIL);
195   - return;
196   - }
197   - // 授权状态
198   - int authStatus = IDcardQualityProcess.init(token);
199   - // 加载模型状态
200   - int initModelStatus = IDcardQualityProcess.getInstance()
201   - .idcardQualityInit(CameraActivity.this.getAssets(),
202   - "models");
203   - if (authStatus != 0) {
204   - cameraView.setInitNativeStatus(CameraView.NATIVE_AUTH_FAIL);
205   - return;
206   - }
207   - if (initModelStatus != 0) {
208   - cameraView.setInitNativeStatus(CameraView.NATIVE_INIT_FAIL);
209   - return;
210   - }
211   - }
212   - });
213   - }
214   -
215   - private void showTakePicture() {
216   - cameraView.getCameraControl().resume();
217   - updateFlashMode();
218   - takePictureContainer.setVisibility(View.VISIBLE);
219   - back.setVisibility(View.VISIBLE);
220   - confirmResultContainer.setVisibility(View.INVISIBLE);
221   - cropContainer.setVisibility(View.INVISIBLE);
222   - }
223   -
224   - private void showCrop() {
225   - cameraView.getCameraControl().pause();
226   - updateFlashMode();
227   - takePictureContainer.setVisibility(View.INVISIBLE);
228   - back.setVisibility(View.INVISIBLE);
229   - confirmResultContainer.setVisibility(View.INVISIBLE);
230   - cropContainer.setVisibility(View.VISIBLE);
231   - }
232   -
233   - private void showResultConfirm() {
234   - cameraView.getCameraControl().pause();
235   - updateFlashMode();
236   - takePictureContainer.setVisibility(View.INVISIBLE);
237   - back.setVisibility(View.INVISIBLE);
238   - confirmResultContainer.setVisibility(View.VISIBLE);
239   - cropContainer.setVisibility(View.INVISIBLE);
240   - }
241   -
242   - // take photo;
243   - private void updateFlashMode() {
244   - int flashMode = cameraView.getCameraControl().getFlashMode();
245   - if (flashMode == ICameraControl.FLASH_MODE_TORCH) {
246   - lightButton.setImageResource(R.drawable.bd_ocr_light_on);
247   - } else {
248   - lightButton.setImageResource(R.drawable.bd_ocr_light_off);
249   - }
250   - }
251   -
252   - private View.OnClickListener albumButtonOnClickListener = new View.OnClickListener() {
253   - @Override
254   - public void onClick(View v) {
255   - long curClickTime = System.currentTimeMillis();
256   - if (preViewClickTime > 0 && curClickTime - preViewClickTime <= 2000 ) {
257   - return;
258   - }
259   - preViewClickTime = curClickTime;
260   - if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.READ_EXTERNAL_STORAGE)
261   - != PackageManager.PERMISSION_GRANTED) {
262   - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
263   - ActivityCompat.requestPermissions(CameraActivity.this,
264   - new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
265   - PERMISSIONS_EXTERNAL_STORAGE);
266   - return;
267   - }
268   - }
269   - new ImagePicker
270   - .Builder()
271   - .setSelectGif(false)
272   - .maxImageSize(20 * 1024 * 1024)
273   - //最大选择图片数目,默认40张
274   - .maxNum(1)
275   - //选择模式(默认PICKER_IMAGE_VIDEO) PICKER_IMAGE-->图片 PICKER_VIDEO-->视频 PICKER_IMAGE_VIDEO-->图片&视频
276   - .selectMode(PickerConfig.PICKER_IMAGE)
277   - //拍照或录像存储位置 默认Environment.getExternalStorageDirectory().getPath() + File.separator + "JCamera"
278   - .cachePath(Environment.getExternalStorageDirectory() + "/strike/file/")
279   - //是否为发朋友圈模式(默认false) true-->图片与视频不能同时选择
280   - .isFriendCircle(true)
281   - //裁剪 只有在单选模式下才可以使用
282   -// .doCrop(1, 1, 300, 300)
283   - //是否开启单选模式(默认false)
284   - .isSinglePick(true)
285   - .builder()
286   - .start(CameraActivity.this, PickerConfig.PICKER_IMAGE, REQUEST_CODE_PICK_IMAGE);
287   - }
288   - };
289   -
290   - private View.OnClickListener lightButtonOnClickListener = new View.OnClickListener() {
291   - @Override
292   - public void onClick(View v) {
293   - if (cameraView.getCameraControl().getFlashMode() == ICameraControl.FLASH_MODE_OFF) {
294   - cameraView.getCameraControl().setFlashMode(ICameraControl.FLASH_MODE_TORCH);
295   - } else {
296   - cameraView.getCameraControl().setFlashMode(ICameraControl.FLASH_MODE_OFF);
297   - }
298   - updateFlashMode();
299   - }
300   - };
301   -
302   - private View.OnClickListener takeButtonOnClickListener = new View.OnClickListener() {
303   - @Override
304   - public void onClick(View v) {
305   - if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA)
306   - != PackageManager.PERMISSION_GRANTED) {
307   - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
308   - ActivityCompat.requestPermissions(CameraActivity.this,
309   - new String[]{Manifest.permission.CAMERA,
310   - Manifest.permission.WRITE_EXTERNAL_STORAGE,
311   - Manifest.permission.READ_EXTERNAL_STORAGE},
312   - PERMISSIONS_REQUEST_CAMERA);
313   - return;
314   - }
315   - }
316   - cameraView.takePicture(outputFile, takePictureCallback);
317   - }
318   - };
319   -
320   - private CameraView.OnTakePictureCallback autoTakePictureCallback = new CameraView.OnTakePictureCallback() {
321   - @Override
322   - public void onPictureTaken(final Bitmap bitmap) {
323   - CameraThreadPool.execute(new Runnable() {
324   - @Override
325   - public void run() {
326   - try {
327   - FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
328   - bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);
329   - bitmap.recycle();
330   - fileOutputStream.close();
331   - } catch (IOException e) {
332   - e.printStackTrace();
333   - }
334   - Intent intent = new Intent();
335   - intent.putExtra(CameraActivity.KEY_CONTENT_TYPE, contentType);
336   - setResult(Activity.RESULT_OK, intent);
337   - finish();
338   - }
339   - });
340   - }
341   - };
342   -
343   - private CameraView.OnTakePictureCallback takePictureCallback = new CameraView.OnTakePictureCallback() {
344   - @Override
345   - public void onPictureTaken(final Bitmap bitmap) {
346   - handler.post(new Runnable() {
347   - @Override
348   - public void run() {
349   - takePictureContainer.setVisibility(View.INVISIBLE);
350   - back.setVisibility(View.INVISIBLE);
351   - if (cropMaskView.getMaskType() == MaskView.MASK_TYPE_NONE) {
352   - cropView.setFilePath(outputFile.getAbsolutePath());
353   - showCrop();
354   - } else if (cropMaskView.getMaskType() == MaskView.MASK_TYPE_BANK_CARD) {
355   - cropView.setFilePath(outputFile.getAbsolutePath());
356   - cropMaskView.setVisibility(View.INVISIBLE);
357   - overlayView.setVisibility(View.VISIBLE);
358   - overlayView.setTypeWide();
359   - showCrop();
360   - } else {
361   - displayImageView.setImageBitmap(bitmap);
362   - showResultConfirm();
363   - }
364   - }
365   - });
366   - }
367   - };
368   -
369   - private View.OnClickListener cropCancelButtonListener = new View.OnClickListener() {
370   - @Override
371   - public void onClick(View v) {
372   - // 释放 cropView中的bitmap;
373   - cropView.setFilePath(null);
374   - showTakePicture();
375   - }
376   - };
377   -
378   -
379   - private View.OnClickListener finishListener = new View.OnClickListener() {
380   - @Override
381   - public void onClick(View v) {
382   - finish();
383   - }
384   - };
385   -
386   - private View.OnClickListener cropConfirmButtonListener = new View.OnClickListener() {
387   - @Override
388   - public void onClick(View v) {
389   - int maskType = cropMaskView.getMaskType();
390   - Rect rect;
391   - switch (maskType) {
392   - case MaskView.MASK_TYPE_BANK_CARD:
393   - case MaskView.MASK_TYPE_ID_CARD_BACK:
394   - case MaskView.MASK_TYPE_ID_CARD_FRONT:
395   - rect = cropMaskView.getFrameRect();
396   - break;
397   - case MaskView.MASK_TYPE_NONE:
398   - default:
399   - rect = overlayView.getFrameRect();
400   - break;
401   - }
402   - Bitmap cropped = cropView.crop(rect);
403   - if(cropped == null){
404   - return;
405   - }
406   - displayImageView.setImageBitmap(cropped);
407   - cropAndConfirm();
408   - }
409   - };
410   -
411   - private void cropAndConfirm() {
412   - cameraView.getCameraControl().pause();
413   - updateFlashMode();
414   - doConfirmResult();
415   - }
416   -
417   - private void doConfirmResult() {
418   - CameraThreadPool.execute(new Runnable() {
419   - @Override
420   - public void run() {
421   - try {
422   - FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
423   - Bitmap bitmap = ((BitmapDrawable) displayImageView.getDrawable()).getBitmap();
424   - bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);
425   - fileOutputStream.close();
426   - } catch (IOException e) {
427   - if (e!=null)
428   - e.printStackTrace();
429   - }
430   - Intent intent = new Intent();
431   - intent.putExtra(CameraActivity.KEY_CONTENT_TYPE, contentType);
432   - setResult(Activity.RESULT_OK, intent);
433   - finish();
434   - }
435   - });
436   - }
437   -
438   - private View.OnClickListener confirmButtonOnClickListener = new View.OnClickListener() {
439   - @Override
440   - public void onClick(View v) {
441   - doConfirmResult();
442   - }
443   - };
444   -
445   - private View.OnClickListener confirmCancelButtonOnClickListener = new View.OnClickListener() {
446   - @Override
447   - public void onClick(View v) {
448   - displayImageView.setImageBitmap(null);
449   - showTakePicture();
450   - }
451   - };
452   -
453   - private View.OnClickListener rotateButtonOnClickListener = new View.OnClickListener() {
454   - @Override
455   - public void onClick(View v) {
456   - cropView.rotate(90);
457   - }
458   - };
459   -
460   - @Override
461   - public void onConfigurationChanged(Configuration newConfig) {
462   - super.onConfigurationChanged(newConfig);
463   - setOrientation(newConfig);
464   - }
465   -
466   - private void setOrientation(Configuration newConfig) {
467   - int rotation = getWindowManager().getDefaultDisplay().getRotation();
468   - int orientation;
469   - int cameraViewOrientation = CameraView.ORIENTATION_PORTRAIT;
470   - switch (newConfig.orientation) {
471   - case Configuration.ORIENTATION_PORTRAIT:
472   - cameraViewOrientation = CameraView.ORIENTATION_PORTRAIT;
473   - orientation = OCRCameraLayout.ORIENTATION_PORTRAIT;
474   - break;
475   - case Configuration.ORIENTATION_LANDSCAPE:
476   - orientation = OCRCameraLayout.ORIENTATION_HORIZONTAL;
477   - if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90) {
478   - cameraViewOrientation = CameraView.ORIENTATION_HORIZONTAL;
479   - } else {
480   - cameraViewOrientation = CameraView.ORIENTATION_INVERT;
481   - }
482   - break;
483   - default:
484   - orientation = OCRCameraLayout.ORIENTATION_PORTRAIT;
485   - cameraView.setOrientation(CameraView.ORIENTATION_PORTRAIT);
486   - break;
487   - }
488   - takePictureContainer.setOrientation(orientation);
489   - cameraView.setOrientation(cameraViewOrientation);
490   - cropContainer.setOrientation(orientation);
491   - confirmResultContainer.setOrientation(orientation);
492   - }
493   -
494   - @Override
495   - protected void onActivityResult(int requestCode, int resultCode, Intent data) {
496   - super.onActivityResult(requestCode, resultCode, data);
497   - if (requestCode == REQUEST_CODE_PICK_IMAGE && data != null) {
498   - ArrayList<Media> select = data.getParcelableArrayListExtra(PickerConfig.EXTRA_RESULT);
499   - String path = select.get(0).path;
500   - cropView.setFilePath(path);
501   - showCrop();
502   - }else {
503   - cameraView.getCameraControl().resume();
504   - }
505   - }
506   -
507   -
508   -
509   - @Override
510   - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
511   - @NonNull int[] grantResults) {
512   - super.onRequestPermissionsResult(requestCode, permissions, grantResults);
513   - switch (requestCode) {
514   - case PERMISSIONS_REQUEST_CAMERA: {
515   - if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
516   - cameraView.getCameraControl().refreshPermission();
517   - } else {
518   - AlertUtil.showLongToast(getApplicationContext(), getString(R.string.camera_permission_required), Toast.LENGTH_LONG);
519   - }
520   - break;
521   - }
522   - case PERMISSIONS_EXTERNAL_STORAGE:
523   - if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
524   -
525   - } else {
526   - AlertUtil.showLongToast(getApplicationContext(), getString(R.string.permission_required), Toast.LENGTH_LONG);
527   - }
528   - default:
529   - break;
530   - }
531   - }
532   -
533   - /**
534   - * 做一些收尾工作,把这些工作从onDestory中移到正确的位置
535   - * 可以以防止新的activity启动后被调用
536   - */
537   - private void doClear() {
538   - CameraThreadPool.cancelAutoFocusTimer();
539   - IDcardQualityProcess.getInstance().releaseModel();
540   - }
541   -
542   -
543   - @Override
544   - protected void onDestroy() {
545   - super.onDestroy();
546   - this.doClear();
547   - }
548   -}
core/dentity_verfication/src/main/java/com/cnlive/core/ocr/ui/camera/CameraThreadPool.java deleted 100644 → 0
1   -/*
2   - * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
3   - */
4   -package com.cnlive.core.ocr.ui.camera;
5   -
6   -import java.util.Timer;
7   -import java.util.TimerTask;
8   -import java.util.concurrent.ExecutorService;
9   -import java.util.concurrent.Executors;
10   -
11   -public class CameraThreadPool {
12   -
13   - static Timer timerFocus = null;
14   -
15   - /*
16   - * 对焦频率
17   - */
18   - static final long cameraScanInterval = 2000;
19   -
20   - /*
21   - * 线程池大小
22   - */
23   - private static int poolCount = Runtime.getRuntime().availableProcessors();
24   -
25   - private static ExecutorService fixedThreadPool = Executors.newFixedThreadPool(poolCount);
26   -
27   - /**
28   - * 给线程池添加任务
29   - *
30   - * @param runnable 任务
31   - */
32   - public static void execute(Runnable runnable) {
33   - fixedThreadPool.execute(runnable);
34   - }
35   -
36   - /**
37   - * 创建一个定时对焦的timer任务
38   - *
39   - * @param runnable 对焦代码
40   - * @return Timer Timer对象,用来终止自动对焦
41   - */
42   - public static Timer createAutoFocusTimerTask(final Runnable runnable) {
43   - if (timerFocus != null) {
44   - return timerFocus;
45   - }
46   - timerFocus = new Timer();
47   - TimerTask task = new TimerTask() {
48   - @Override
49   - public void run() {
50   - runnable.run();
51   - }
52   - };
53   - timerFocus.scheduleAtFixedRate(task, 0, cameraScanInterval);
54   - return timerFocus;
55   - }
56   -
57   - /**
58   - * 终止自动对焦任务,实际调用了cancel方法并且清空对象
59   - * 但是无法终止执行中的任务,需额外处理
60   - */
61   - public static void cancelAutoFocusTimer() {
62   - if (timerFocus != null) {
63   - timerFocus.cancel();
64   - timerFocus = null;
65   - }
66   - }
67   -}
core/dentity_verfication/src/main/java/com/cnlive/core/ocr/ui/camera/CameraView.java deleted 100644 → 0
1   -/*
2   - * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
3   - */
4   -package com.cnlive.core.ocr.ui.camera;
5   -
6   -import android.content.Context;
7   -import android.graphics.Bitmap;
8   -import android.graphics.BitmapFactory;
9   -import android.graphics.BitmapRegionDecoder;
10   -import android.graphics.Color;
11   -import android.graphics.Matrix;
12   -import android.graphics.Rect;
13   -import android.os.Handler;
14   -import android.os.Looper;
15   -import android.util.AttributeSet;
16   -import android.util.TypedValue;
17   -import android.view.Gravity;
18   -import android.view.View;
19   -import android.widget.FrameLayout;
20   -import android.widget.ImageView;
21   -import android.widget.LinearLayout;
22   -import android.widget.TextView;
23   -
24   -import com.cnlive.core.ocr.idcardquality.IDcardQualityProcess;
25   -import com.cnlive.core.ocr.ui.util.ImageUtil;
26   -import com.cnlive.core.ocr.ui.util.PxUtil;
27   -import com.cnlive.core.people_verfication.R;
28   -
29   -import java.io.File;
30   -import java.io.FileOutputStream;
31   -import java.io.IOException;
32   -
33   -import androidx.annotation.IntDef;
34   -
35   -/**
36   - * 负责,相机的管理。同时提供,裁剪遮罩功能。
37   - */
38   -public class CameraView extends FrameLayout {
39   -
40   - private int maskType;
41   -
42   - /**
43   - * 照相回调
44   - */
45   - interface OnTakePictureCallback {
46   - void onPictureTaken(Bitmap bitmap);
47   - }
48   -
49   - /**
50   - * 垂直方向 {@link #setOrientation(int)}
51   - */
52   - public static final int ORIENTATION_PORTRAIT = 0;
53   - /**
54   - * 水平方向 {@link #setOrientation(int)}
55   - */
56   - public static final int ORIENTATION_HORIZONTAL = 90;
57   - /**
58   - * 水平翻转方向 {@link #setOrientation(int)}
59   - */
60   - public static final int ORIENTATION_INVERT = 270;
61   -
62   - /**
63   - * 本地模型授权,加载成功
64   - */
65   - public static final int NATIVE_AUTH_INIT_SUCCESS = 0;
66   -
67   - /**
68   - * 本地模型授权,加载成功
69   - */
70   - public static final int NATIVE_SOLOAD_FAIL = 10;
71   -
72   - /**
73   - * 本地模型授权,加载成功
74   - */
75   - public static final int NATIVE_AUTH_FAIL = 11;
76   -
77   - /**
78   - * 本地模型授权,加载成功
79   - */
80   - public static final int NATIVE_INIT_FAIL = 12;
81   -
82   -
83   - /**
84   - * 是否已经通过本地质量控制扫描
85   - */
86   - private final int SCAN_SUCCESS = 0;
87   -
88   - public void setInitNativeStatus(int initNativeStatus) {
89   - this.initNativeStatus = initNativeStatus;
90   - }
91   -
92   - /**
93   - * 本地检测初始化,模型加载标识
94   - */
95   - private int initNativeStatus = NATIVE_AUTH_INIT_SUCCESS;
96   -
97   - @IntDef({ORIENTATION_PORTRAIT, ORIENTATION_HORIZONTAL, ORIENTATION_INVERT})
98   - public @interface Orientation {
99   -
100   - }
101   -
102   - private CameraViewTakePictureCallback cameraViewTakePictureCallback = new CameraViewTakePictureCallback();
103   -
104   - private ICameraControl cameraControl;
105   -
106   - /**
107   - * 相机预览View
108   - */
109   - private View displayView;
110   - /**
111   - * 身份证,银行卡,等裁剪用的遮罩
112   - */
113   - private MaskView maskView;
114   -
115   - /**
116   - * 用于显示提示证 "请对齐身份证正面" 之类的背景
117   - */
118   - private ImageView hintView;
119   -
120   - /**
121   - * 用于显示提示证 "请对齐身份证正面" 之类的文字
122   - */
123   - private TextView hintViewText;
124   -
125   - /**
126   - * 提示文案容器
127   - */
128   - private LinearLayout hintViewTextWrapper;
129   -
130   - /**
131   - * 是否是本地质量控制扫描
132   - */
133   - private boolean isEnableScan;
134   -
135   - public void setEnableScan(boolean enableScan) {
136   - isEnableScan = enableScan;
137   - }
138   -
139   - /**
140   - * UI线程的handler
141   - */
142   - Handler uiHandler = new Handler(Looper.getMainLooper());
143   -
144   - public ICameraControl getCameraControl() {
145   - return cameraControl;
146   - }
147   -
148   - public void setOrientation(@Orientation int orientation) {
149   - cameraControl.setDisplayOrientation(orientation);
150   - }
151   -
152   - public CameraView(Context context) {
153   - super(context);
154   - init();
155   - }
156   -
157   - public CameraView(Context context, AttributeSet attrs) {
158   - super(context, attrs);
159   - init();
160   - }
161   -
162   - public CameraView(Context context, AttributeSet attrs, int defStyleAttr) {
163   - super(context, attrs, defStyleAttr);
164   - init();
165   - }
166   -
167   - public void start() {
168   - cameraControl.start();
169   - setKeepScreenOn(true);
170   - }
171   -
172   - public void stop() {
173   - cameraControl.stop();
174   - setKeepScreenOn(false);
175   - }
176   -
177   - public void takePicture(final File file, final OnTakePictureCallback callback) {
178   - cameraViewTakePictureCallback.file = file;
179   - cameraViewTakePictureCallback.callback = callback;
180   - cameraControl.takePicture(cameraViewTakePictureCallback);
181   - }
182   -
183   - private OnTakePictureCallback autoPictureCallback;
184   -
185   - public void setAutoPictureCallback(OnTakePictureCallback callback) {
186   - autoPictureCallback = callback;
187   - }
188   -
189   - public void setMaskType(@MaskView.MaskType int maskType, final Context ctx) {
190   - maskView.setMaskType(maskType);
191   -
192   - maskView.setVisibility(VISIBLE);
193   - hintView.setVisibility(VISIBLE);
194   -
195   - int hintResourceId = R.drawable.bd_ocr_hint_align_id_card;
196   - this.maskType = maskType;
197   - boolean isNeedSetImage = true;
198   - switch (maskType) {
199   - case MaskView.MASK_TYPE_ID_CARD_FRONT:
200   - hintResourceId = R.drawable.bd_ocr_round_corner;
201   - isNeedSetImage = false;
202   - break;
203   - case MaskView.MASK_TYPE_ID_CARD_BACK:
204   - isNeedSetImage = false;
205   - hintResourceId = R.drawable.bd_ocr_round_corner;
206   - break;
207   - case MaskView.MASK_TYPE_BANK_CARD:
208   - hintResourceId = R.drawable.bd_ocr_hint_align_bank_card;
209   - break;
210   - case MaskView.MASK_TYPE_NONE:
211   - default:
212   - maskView.setVisibility(INVISIBLE);
213   - hintView.setVisibility(INVISIBLE);
214   - break;
215   - }
216   -
217   - if (isNeedSetImage) {
218   - hintView.setImageResource(hintResourceId);
219   - hintViewTextWrapper.setVisibility(INVISIBLE);
220   - }
221   -
222   - if (maskType == MaskView.MASK_TYPE_ID_CARD_FRONT && isEnableScan) {
223   - cameraControl.setDetectCallback(new ICameraControl.OnDetectPictureCallback() {
224   - @Override
225   - public int onDetect(byte[] data, int rotation) {
226   - return detect(data, rotation);
227   - }
228   - });
229   - }
230   -
231   - if (maskType == MaskView.MASK_TYPE_ID_CARD_BACK && isEnableScan) {
232   - cameraControl.setDetectCallback(new ICameraControl.OnDetectPictureCallback() {
233   - @Override
234   - public int onDetect(byte[] data, int rotation) {
235   - return detect(data, rotation);
236   - }
237   - });
238   - }
239   - }
240   -
241   - private int detect(byte[] data, final int rotation) {
242   - if (initNativeStatus != NATIVE_AUTH_INIT_SUCCESS) {
243   - showTipMessage(initNativeStatus);
244   - return 1;
245   - }
246   - // 扫描成功阻止多余的操作
247   - if (cameraControl.getAbortingScan().get()) {
248   - return 0;
249   - }
250   - // BitmapRegionDecoder不会将整个图片加载到内存。
251   - BitmapRegionDecoder decoder = null;
252   - try {
253   - decoder = BitmapRegionDecoder.newInstance(data, 0, data.length, true);
254   - } catch (IOException e) {
255   - if (e!=null)
256   - e.printStackTrace();
257   - }
258   -
259   - Rect previewFrame = cameraControl.getPreviewFrame();
260   -
261   - int width = rotation % 180 == 0 ? decoder.getWidth() : decoder.getHeight();
262   - int height = rotation % 180 == 0 ? decoder.getHeight() : decoder.getWidth();
263   -
264   - Rect frameRect = maskView.getFrameRectExtend();
265   -
266   - int left = width * frameRect.left / maskView.getWidth();
267   - int top = height * frameRect.top / maskView.getHeight();
268   - int right = width * frameRect.right / maskView.getWidth();
269   - int bottom = height * frameRect.bottom / maskView.getHeight();
270   -
271   - // 高度大于图片
272   - if (previewFrame.top < 0) {
273   - // 宽度对齐。
274   - int adjustedPreviewHeight = previewFrame.height() * getWidth() / previewFrame.width();
275   - int topInFrame = ((adjustedPreviewHeight - frameRect.height()) / 2)
276   - * getWidth() / previewFrame.width();
277   - int bottomInFrame = ((adjustedPreviewHeight + frameRect.height()) / 2) * getWidth()
278   - / previewFrame.width();
279   -
280   - // 等比例投射到照片当中。
281   - top = topInFrame * height / previewFrame.height();
282   - bottom = bottomInFrame * height / previewFrame.height();
283   - } else {
284   - // 宽度大于图片
285   - if (previewFrame.left < 0) {
286   - // 高度对齐
287   - int adjustedPreviewWidth = previewFrame.width() * getHeight() / previewFrame.height();
288   - int leftInFrame = ((adjustedPreviewWidth - maskView.getFrameRect().width()) / 2) * getHeight()
289   - / previewFrame.height();
290   - int rightInFrame = ((adjustedPreviewWidth + maskView.getFrameRect().width()) / 2) * getHeight()
291   - / previewFrame.height();
292   -
293   - // 等比例投射到照片当中。
294   - left = leftInFrame * width / previewFrame.width();
295   - right = rightInFrame * width / previewFrame.width();
296   - }
297   - }
298   -
299   - Rect region = new Rect();
300   - region.left = left;
301   - region.top = top;
302   - region.right = right;
303   - region.bottom = bottom;
304   -
305   - // 90度或者270度旋转
306   - if (rotation % 180 == 90) {
307   - int x = decoder.getWidth() / 2;
308   - int y = decoder.getHeight() / 2;
309   -
310   - int rotatedWidth = region.height();
311   - int rotated = region.width();
312   -
313   - // 计算,裁剪框旋转后的坐标
314   - region.left = x - rotatedWidth / 2;
315   - region.top = y - rotated / 2;
316   - region.right = x + rotatedWidth / 2;
317   - region.bottom = y + rotated / 2;
318   - region.sort();
319   - }
320   -
321   - BitmapFactory.Options options = new BitmapFactory.Options();
322   -
323   - // 最大图片大小。
324   - int maxPreviewImageSize = 2560;
325   - int size = Math.min(decoder.getWidth(), decoder.getHeight());
326   - size = Math.min(size, maxPreviewImageSize);
327   -
328   - options.inSampleSize = ImageUtil.calculateInSampleSize(options, size, size);
329   - options.inScaled = true;
330   - options.inDensity = Math.max(options.outWidth, options.outHeight);
331   - options.inTargetDensity = size;
332   - options.inPreferredConfig = Bitmap.Config.RGB_565;
333   -
334   - Bitmap bitmap = decoder.decodeRegion(region, options);
335   -
336   - if (rotation != 0) {
337   - // 只能是裁剪完之后再旋转了。有没有别的更好的方案呢?
338   - Matrix matrix = new Matrix();
339   - matrix.postRotate(rotation);
340   - Bitmap rotatedBitmap = Bitmap.createBitmap(
341   - bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
342   - if (bitmap != rotatedBitmap) {
343   - // 有时候 createBitmap会复用对象
344   - bitmap.recycle();
345   - }
346   - bitmap = rotatedBitmap;
347   - }
348   -
349   - final int status;
350   -
351   - // 调用本地质量控制请求
352   - switch (maskType) {
353   - case MaskView.MASK_TYPE_ID_CARD_FRONT:
354   - status = IDcardQualityProcess.getInstance().idcardQualityDetectionImg(bitmap, true);
355   - break;
356   - case MaskView.MASK_TYPE_ID_CARD_BACK:
357   - status = IDcardQualityProcess.getInstance().idcardQualityDetectionImg(bitmap, false);
358   - break;
359   - default:
360   - status = 1;
361   - }
362   -
363   - // 当有某个扫描处理线程调用成功后,阻止其他线程继续调用本地控制代码
364   - if (status == SCAN_SUCCESS) {
365   - // 扫描成功阻止多线程同时回调
366   - if (!cameraControl.getAbortingScan().compareAndSet(false, true)) {
367   - bitmap.recycle();
368   - return 0;
369   - }
370   - autoPictureCallback.onPictureTaken(bitmap);
371   - }
372   -
373   - showTipMessage(status);
374   -
375   - return status;
376   - }
377   -
378   - private void showTipMessage(final int status) {
379   - // 提示tip文字变化
380   - uiHandler.post(new Runnable() {
381   - @Override
382   - public void run() {
383   - if (status == 0) {
384   - hintViewText.setVisibility(View.INVISIBLE);
385   - } else if (!cameraControl.getAbortingScan().get()) {
386   - hintViewText.setVisibility(View.VISIBLE);
387   - hintViewText.setText(getScanMessage(status));
388   - }
389   - }
390   - });
391   - }
392   -
393   - private String getScanMessage(int status) {
394   - String message;
395   - switch (status) {
396   - case 0:
397   - message = "";
398   - break;
399   - case 2:
400   - message = "身份证模糊,请重新尝试";
401   - break;
402   - case 3:
403   - message = "身份证反光,请重新尝试";
404   - break;
405   - case 4:
406   - message = "请将身份证前后反转再进行识别";
407   - break;
408   - case 5:
409   - message = "请拿稳镜头和身份证";
410   - break;
411   - case 6:
412   - message = "请将镜头靠近身份证";
413   - break;
414   - case 7:
415   - message = "请将身份证完整置于取景框内";
416   - break;
417   - case NATIVE_AUTH_FAIL:
418   - message = "本地质量控制授权失败";
419   - break;
420   - case NATIVE_INIT_FAIL:
421   - message = "本地模型加载失败";
422   - break;
423   - case NATIVE_SOLOAD_FAIL:
424   - message = "本地SO库加载失败";
425   - break;
426   - case 1:
427   - default:
428   - message = "请将身份证置于取景框内";
429   - }
430   -
431   -
432   - return message;
433   - }
434   -
435   - private void init() {
436   -// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
437   -// cameraControl = new Camera2Control(getContext());
438   -// } else {
439   -//
440   -// }
441   - cameraControl = new Camera1Control(getContext());
442   -
443   - displayView = cameraControl.getDisplayView();
444   - addView(displayView);
445   -
446   - maskView = new MaskView(getContext());
447   - addView(maskView);
448   -
449   - hintView = new ImageView(getContext());
450   - addView(hintView);
451   -
452   - hintViewTextWrapper = new LinearLayout(getContext());
453   - hintViewTextWrapper.setOrientation(LinearLayout.VERTICAL);
454   - LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
455   - PxUtil.dp2px(25));
456   -
457   - lp.gravity = Gravity.CENTER;
458   - hintViewText = new TextView(getContext());
459   - hintViewText.setBackgroundResource(R.drawable.bd_ocr_round_corner);
460   - hintViewText.setAlpha(0.5f);
461   - hintViewText.setPadding(PxUtil.dp2px(10), 0, PxUtil.dp2px(10), 0);
462   - hintViewTextWrapper.addView(hintViewText, lp);
463   -
464   -
465   - hintViewText.setGravity(Gravity.CENTER);
466   - hintViewText.setTextColor(Color.WHITE);
467   - hintViewText.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
468   - hintViewText.setText(getScanMessage(-1));
469   -
470   -
471   - addView(hintViewTextWrapper, lp);
472   - }
473   -
474   - @Override
475   - protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
476   - displayView.layout(left, 0, right, bottom - top);
477   - maskView.layout(left, 0, right, bottom - top);
478   -
479   - int hintViewWidth = PxUtil.dp2px(250);
480   - int hintViewHeight = PxUtil.dp2px(25);
481   -
482   - int hintViewLeft = (getWidth() - hintViewWidth) / 2;
483   - int hintViewTop = maskView.getFrameRect().bottom + PxUtil.dp2px(16);
484   -
485   - hintViewTextWrapper.layout(hintViewLeft, hintViewTop,
486   - hintViewLeft + hintViewWidth, hintViewTop + hintViewHeight);
487   -
488   - hintView.layout(hintViewLeft, hintViewTop,
489   - hintViewLeft + hintViewWidth, hintViewTop + hintViewHeight);
490   - }
491   -
492   - /**
493   - * 拍摄后的照片。需要进行裁剪。有些手机(比如三星)不会对照片数据进行旋转,而是将旋转角度写入EXIF信息当中,
494   - * 所以需要做旋转处理。
495   - *
496   - * @param outputFile 写入照片的文件。
497   - * @param data 原始照片数据。
498   - * @param rotation 照片exif中的旋转角度。
499   - * @return 裁剪好的bitmap。
500   - */
501   - @SuppressWarnings("ResultOfMethodCallIgnored")
502   - private Bitmap crop(File outputFile, byte[] data, int rotation) {
503   - try {
504   - // BitmapRegionDecoder不会将整个图片加载到内存。
505   - BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(data, 0, data.length, true);
506   -
507   - Rect previewFrame = cameraControl.getPreviewFrame();
508   -
509   - int width = rotation % 180 == 0 ? decoder.getWidth() : decoder.getHeight();
510   - int height = rotation % 180 == 0 ? decoder.getHeight() : decoder.getWidth();
511   -
512   - Rect frameRect = maskView.getFrameRect();
513   -
514   - int left = width * frameRect.left / maskView.getWidth();
515   - int top = height * frameRect.top / maskView.getHeight();
516   - int right = width * frameRect.right / maskView.getWidth();
517   - int bottom = height * frameRect.bottom / maskView.getHeight();
518   -
519   - // 高度大于图片
520   - if (previewFrame.top < 0) {
521   - // 宽度对齐。
522   - int adjustedPreviewHeight = previewFrame.height() * getWidth() / previewFrame.width();
523   - int topInFrame = ((adjustedPreviewHeight - frameRect.height()) / 2)
524   - * getWidth() / previewFrame.width();
525   - int bottomInFrame = ((adjustedPreviewHeight + frameRect.height()) / 2) * getWidth()
526   - / previewFrame.width();
527   -
528   - // 等比例投射到照片当中。
529   - top = topInFrame * height / previewFrame.height();
530   - bottom = bottomInFrame * height / previewFrame.height();
531   - } else {
532   - // 宽度大于图片
533   - if (previewFrame.left < 0) {
534   - // 高度对齐
535   - int adjustedPreviewWidth = previewFrame.width() * getHeight() / previewFrame.height();
536   - int leftInFrame = ((adjustedPreviewWidth - maskView.getFrameRect().width()) / 2) * getHeight()
537   - / previewFrame.height();
538   - int rightInFrame = ((adjustedPreviewWidth + maskView.getFrameRect().width()) / 2) * getHeight()
539   - / previewFrame.height();
540   -
541   - // 等比例投射到照片当中。
542   - left = leftInFrame * width / previewFrame.width();
543   - right = rightInFrame * width / previewFrame.width();
544   - }
545   - }
546   -
547   - Rect region = new Rect();
548   - region.left = left;
549   - region.top = top;
550   - region.right = right;
551   - region.bottom = bottom;
552   -
553   - // 90度或者270度旋转
554   - if (rotation % 180 == 90) {
555   - int x = decoder.getWidth() / 2;
556   - int y = decoder.getHeight() / 2;
557   -
558   - int rotatedWidth = region.height();
559   - int rotated = region.width();
560   -
561   - // 计算,裁剪框旋转后的坐标
562   - region.left = x - rotatedWidth / 2;
563   - region.top = y - rotated / 2;
564   - region.right = x + rotatedWidth / 2;
565   - region.bottom = y + rotated / 2;
566   - region.sort();
567   - }
568   -
569   - BitmapFactory.Options options = new BitmapFactory.Options();
570   -
571   - // 最大图片大小。
572   - int maxPreviewImageSize = 2560;
573   - int size = Math.min(decoder.getWidth(), decoder.getHeight());
574   - size = Math.min(size, maxPreviewImageSize);
575   -
576   - options.inSampleSize = ImageUtil.calculateInSampleSize(options, size, size);
577   - options.inScaled = true;
578   - options.inDensity = Math.max(options.outWidth, options.outHeight);
579   - options.inTargetDensity = size;
580   - options.inPreferredConfig = Bitmap.Config.RGB_565;
581   - Bitmap bitmap = decoder.decodeRegion(region, options);
582   -
583   - if (rotation != 0) {
584   - // 只能是裁剪完之后再旋转了。有没有别的更好的方案呢?
585   - Matrix matrix = new Matrix();
586   - matrix.postRotate(rotation);
587   - Bitmap rotatedBitmap = Bitmap.createBitmap(
588   - bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
589   - if (bitmap != rotatedBitmap) {
590   - // 有时候 createBitmap会复用对象
591   - bitmap.recycle();
592   - }
593   - bitmap = rotatedBitmap;
594   - }
595   -
596   - try {
597   - if (!outputFile.exists()) {
598   - outputFile.createNewFile();
599   - }
600   - FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
601   - bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fileOutputStream);
602   - fileOutputStream.flush();
603   - fileOutputStream.close();
604   - return bitmap;
605   - } catch (IOException e) {
606   - if (e!=null)
607   - e.printStackTrace();
608   - }
609   - } catch (IOException e) {
610   - if (e!=null)
611   - e.printStackTrace();
612   - }
613   - return null;
614   - }
615   -
616   - public void release() {
617   - IDcardQualityProcess.getInstance().releaseModel();
618   - }
619   -
620   - private class CameraViewTakePictureCallback implements ICameraControl.OnTakePictureCallback {
621   -
622   - private File file;
623   - private OnTakePictureCallback callback;
624   -
625   - @Override
626   - public void onPictureTaken(final byte[] data) {
627   - CameraThreadPool.execute(new Runnable() {
628   - @Override
629   - public void run() {
630   - final int rotation = ImageUtil.getOrientation(data);
631   - Bitmap bitmap = crop(file, data, rotation);
632   - callback.onPictureTaken(bitmap);
633   - }
634   - });
635   - }
636   - }
637   -}
core/dentity_verfication/src/main/java/com/cnlive/core/ocr/ui/camera/ICameraControl.java deleted 100644 → 0
1   -/*
2   - * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
3   - */
4   -package com.cnlive.core.ocr.ui.camera;
5   -
6   -import android.graphics.Rect;
7   -import android.view.View;
8   -
9   -import java.util.concurrent.atomic.AtomicBoolean;
10   -
11   -import androidx.annotation.IntDef;
12   -
13   -/**
14   - * Android 5.0 相机的API发生很大的变化。些类屏蔽掉了 api的变化。相机的操作和功能,抽象剥离出来。
15   - */
16   -public interface ICameraControl {
17   -
18   - /**
19   - * 闪光灯关 {@link #setFlashMode(int)}
20   - */
21   - int FLASH_MODE_OFF = 0;
22   - /**
23   - * 闪光灯开 {@link #setFlashMode(int)}
24   - */
25   - int FLASH_MODE_TORCH = 1;
26   - /**
27   - * 闪光灯自动 {@link #setFlashMode(int)}
28   - */
29   - int FLASH_MODE_AUTO = 2;
30   -
31   - @IntDef({FLASH_MODE_TORCH, FLASH_MODE_OFF, FLASH_MODE_AUTO})
32   - @interface FlashMode {
33   -
34   - }
35   -
36   - /**
37   - * 照相回调。
38   - */
39   - interface OnTakePictureCallback {
40   - void onPictureTaken(byte[] data);
41   - }
42   -
43   - /**
44   - * 设置本地质量控制回调,如果不设置则视为不扫描调用本地质量控制代码。
45   - */
46   - void setDetectCallback(OnDetectPictureCallback callback);
47   -
48   - /**
49   - * 预览回调
50   - */
51   - interface OnDetectPictureCallback {
52   - int onDetect(byte[] data, int rotation);
53   - }
54   -
55   - /**
56   - * 打开相机。
57   - */
58   - void start();
59   -
60   - /**
61   - * 关闭相机
62   - */
63   - void stop();
64   -
65   - void pause();
66   -
67   - void resume();
68   -
69   - /**
70   - * 相机对应的预览视图。
71   - * @return 预览视图
72   - */
73   - View getDisplayView();
74   -
75   - /**
76   - * 看到的预览可能不是照片的全部。返回预览视图的全貌。
77   - * @return 预览视图frame;
78   - */
79   - Rect getPreviewFrame();
80   -
81   - /**
82   - * 拍照。结果在回调中获取。
83   - * @param callback 拍照结果回调
84   - */
85   - void takePicture(OnTakePictureCallback callback);
86   -
87   - /**
88   - * 设置权限回调,当手机没有拍照权限时,可在回调中获取。
89   - * @param callback 权限回调
90   - */
91   - void setPermissionCallback(PermissionCallback callback);
92   -
93   - /**
94   - * 设置水平方向
95   - * @param displayOrientation 参数值见 {@link com.cnlive.ocr.ui.camera.CameraView.Orientation}
96   - */
97   - void setDisplayOrientation(@CameraView.Orientation int displayOrientation);
98   -
99   - /**
100   - * 获取到拍照权限时,调用些函数以继续。
101   - */
102   - void refreshPermission();
103   -
104   - /**
105   - * 获取已经扫描成功,处理中
106   - */
107   - AtomicBoolean getAbortingScan();
108   -
109   - /**
110   - * 设置闪光灯状态。
111   - * @param flashMode {@link #FLASH_MODE_TORCH,#FLASH_MODE_OFF,#FLASH_MODE_AUTO}
112   - */
113   - void setFlashMode(@FlashMode int flashMode);
114   -
115   - /**
116   - * 获取当前闪光灯状态
117   - * @return 当前闪光灯状态 参见 {@link #setFlashMode(int)}
118   - */
119   - @FlashMode
120   - int getFlashMode();
121   -}
core/dentity_verfication/src/main/java/com/cnlive/core/ocr/ui/camera/MaskView.java deleted 100644 → 0
1   -/*
2   - * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
3   - */
4   -package com.cnlive.core.ocr.ui.camera;
5   -
6   -import android.content.Context;
7   -import android.graphics.Canvas;
8   -import android.graphics.Color;
9   -import android.graphics.Paint;
10   -import android.graphics.Path;
11   -import android.graphics.PorterDuff;
12   -import android.graphics.PorterDuffXfermode;
13   -import android.graphics.Rect;
14   -import android.graphics.drawable.Drawable;
15   -import android.os.Build;
16   -import android.util.AttributeSet;
17   -import android.view.View;
18   -
19   -import com.cnlive.core.people_verfication.R;
20   -
21   -import java.io.File;
22   -
23   -import androidx.annotation.IntDef;
24   -import androidx.annotation.RequiresApi;
25   -import androidx.core.content.res.ResourcesCompat;
26   -
27   -@SuppressWarnings("unused")
28   -public class MaskView extends View {
29   -
30   - public static final int MASK_TYPE_NONE = 0;
31   - public static final int MASK_TYPE_ID_CARD_FRONT = 1;
32   - public static final int MASK_TYPE_ID_CARD_BACK = 2;
33   - public static final int MASK_TYPE_BANK_CARD = 11;
34   - public static final int MASK_TYPE_AVATAR = 12;
35   -
36   - @IntDef({MASK_TYPE_NONE, MASK_TYPE_ID_CARD_FRONT, MASK_TYPE_ID_CARD_BACK, MASK_TYPE_BANK_CARD, MASK_TYPE_AVATAR})
37   - @interface MaskType {
38   -
39   - }
40   -
41   - public void setLineColor(int lineColor) {
42   - this.lineColor = lineColor;
43   - }
44   -
45   - public void setMaskColor(int maskColor) {
46   - this.maskColor = maskColor;
47   - }
48   -
49   - private int lineColor = Color.WHITE;
50   -
51   - private int maskType = MASK_TYPE_ID_CARD_FRONT;
52   -
53   - private int maskColor = Color.argb(100, 0, 0, 0);
54   -
55   - private Paint eraser = new Paint(Paint.ANTI_ALIAS_FLAG);
56   - private Paint pen = new Paint(Paint.ANTI_ALIAS_FLAG);
57   -
58   - private Rect frame = new Rect();
59   -
60   - private Drawable locatorDrawable;
61   -
62   - public Rect getFrameRect() {
63   - if (maskType == MASK_TYPE_NONE) {
64   - return new Rect(0, 0, getWidth(), getHeight());
65   - } else {
66   - return new Rect(frame);
67   - }
68   -
69   - }
70   -
71   - public Rect getFrameRectExtend() {
72   - Rect rc = new Rect(frame);
73   - int widthExtend = (int) ((frame.right - frame.left) * 0.02f);
74   - int heightExtend = (int) ((frame.bottom - frame.top) * 0.02f);
75   - rc.left -= widthExtend;
76   - rc.right += widthExtend;
77   - rc.top -= heightExtend;
78   - rc.bottom += heightExtend;
79   - return rc;
80   - }
81   -
82   - public void setMaskType(@MaskType int maskType) {
83   - this.maskType = maskType;
84   - switch (maskType) {
85   - case MASK_TYPE_ID_CARD_FRONT:
86   - locatorDrawable = ResourcesCompat.getDrawable(getResources(),
87   - R.drawable.bd_ocr_id_card_locator_front, null);
88   - break;
89   - case MASK_TYPE_ID_CARD_BACK:
90   - locatorDrawable = ResourcesCompat.getDrawable(getResources(),
91   - R.drawable.bd_ocr_id_card_locator_back, null);
92   - break;
93   - case MASK_TYPE_BANK_CARD:
94   - break;
95   - case MASK_TYPE_AVATAR:
96   - break;
97   - case MASK_TYPE_NONE:
98   - default:
99   - break;
100   - }
101   - invalidate();
102   - }
103   -
104   - public int getMaskType() {
105   - return maskType;
106   - }
107   -
108   - public void setOrientation(@CameraView.Orientation int orientation) {
109   - }
110   -
111   - public MaskView(Context context) {
112   - super(context);
113   - init();
114   - }
115   -
116   - public MaskView(Context context, AttributeSet attrs) {
117   - super(context, attrs);
118   - init();
119   - }
120   -
121   - public MaskView(Context context, AttributeSet attrs, int defStyleAttr) {
122   - super(context, attrs, defStyleAttr);
123   - init();
124   - }
125   -
126   - private void init() {
127   - locatorDrawable = ResourcesCompat.getDrawable(getResources(), R.drawable.bd_ocr_id_card_locator_front, null);
128   - }
129   -
130   - @Override
131   - protected void onSizeChanged(int w, int h, int oldw, int oldh) {
132   - super.onSizeChanged(w, h, oldw, oldh);
133   - if (w > 0 && h > 0) {
134   - float ratio = h > w ? 0.9f : 0.72f;
135   -
136   - int width = (int) (w * ratio);
137   - int height;
138   - if (maskType == MASK_TYPE_AVATAR) {
139   - height = width;
140   - } else {
141   - height = width * 400 / 620;
142   - }
143   -
144   - int left = (w - width) / 2;
145   - int top = (h - height) / 2;
146   - int right = width + left;
147   - int bottom = height + top;
148   -
149   - frame.left = left;
150   - frame.top = top;
151   - frame.right = right;
152   - frame.bottom = bottom;
153   -
154   - }
155   - }
156   -
157   - @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
158   - @Override
159   - protected void onDraw(Canvas canvas) {
160   - super.onDraw(canvas);
161   -
162   - int width = frame.width();
163   - int height = frame.height();
164   -
165   - int left = frame.left;
166   - int top = frame.top;
167   - int right = frame.right;
168   - int bottom = frame.bottom;
169   -
170   - canvas.drawColor(maskColor);
171   - fillRectRound(left, top, right, bottom, 30, 30, false);
172   - canvas.drawPath(path, pen);
173   - canvas.drawPath(path, eraser);
174   -
175   - if (maskType == MASK_TYPE_ID_CARD_FRONT) {
176   - locatorDrawable.setBounds(
177   - (int) (left + 601f / 1006 * width),
178   - (int) (top + (110f / 632) * height),
179   - (int) (left + (963f / 1006) * width),
180   - (int) (top + (476f / 632) * height));
181   - } else if (maskType == MASK_TYPE_ID_CARD_BACK) {
182   - locatorDrawable.setBounds(
183   - (int) (left + 51f / 1006 * width),
184   - (int) (top + (48f / 632) * height),
185   - (int) (left + (250f / 1006) * width),
186   - (int) (top + (262f / 632) * height));
187   - }
188   - if (locatorDrawable != null) {
189   - locatorDrawable.draw(canvas);
190   - }
191   - }
192   -
193   - private Path path = new Path();
194   -
195   - private Path fillRectRound(float left, float top, float right, float bottom, float rx, float ry, boolean
196   - conformToOriginalPost) {
197   -
198   - path.reset();
199   - if (rx < 0) {
200   - rx = 0;
201   - }
202   - if (ry < 0) {
203   - ry = 0;
204   - }
205   - float width = right - left;
206   - float height = bottom - top;
207   - if (rx > width / 2) {
208   - rx = width / 2;
209   - }
210   - if (ry > height / 2) {
211   - ry = height / 2;
212   - }
213   - float widthMinusCorners = (width - (2 * rx));
214   - float heightMinusCorners = (height - (2 * ry));
215   -
216   - path.moveTo(right, top + ry);
217   - path.rQuadTo(0, -ry, -rx, -ry);
218   - path.rLineTo(-widthMinusCorners, 0);
219   - path.rQuadTo(-rx, 0, -rx, ry);
220   - path.rLineTo(0, heightMinusCorners);
221   -
222   - if (conformToOriginalPost) {
223   - path.rLineTo(0, ry);
224   - path.rLineTo(width, 0);
225   - path.rLineTo(0, -ry);
226   - } else {
227   - path.rQuadTo(0, ry, rx, ry);
228   - path.rLineTo(widthMinusCorners, 0);
229   - path.rQuadTo(rx, 0, rx, -ry);
230   - }
231   -
232   - path.rLineTo(0, -heightMinusCorners);
233   - path.close();
234   - return path;
235   - }
236   -
237   - {
238   - // 硬件加速不支持,图层混合。
239   - setLayerType(View.LAYER_TYPE_SOFTWARE, null);
240   -
241   - pen.setColor(Color.WHITE);
242   - pen.setStyle(Paint.Style.STROKE);
243   - pen.setStrokeWidth(6);
244   -
245   - eraser.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
246   - }
247   -
248   - private void capture(File file) {
249   -
250   - }
251   -}
core/dentity_verfication/src/main/java/com/cnlive/core/ocr/ui/camera/OCRCameraLayout.java deleted 100644 → 0
1   -/*
2   - * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
3   - */
4   -package com.cnlive.core.ocr.ui.camera;
5   -
6   -import android.content.Context;
7   -import android.content.res.TypedArray;
8   -import android.graphics.Canvas;
9   -import android.graphics.Color;
10   -import android.graphics.Paint;
11   -import android.graphics.Rect;
12   -import android.util.AttributeSet;
13   -import android.view.View;
14   -import android.widget.FrameLayout;
15   -
16   -import com.cnlive.core.people_verfication.R;
17   -
18   -
19   -public class OCRCameraLayout extends FrameLayout {
20   -
21   - public static int ORIENTATION_PORTRAIT = 0;
22   - public static int ORIENTATION_HORIZONTAL = 1;
23   -
24   - private int orientation = ORIENTATION_PORTRAIT;
25   - private View contentView;
26   - private View centerView;
27   - private View leftDownView;
28   - private View rightUpView;
29   -
30   - private int contentViewId;
31   - private int centerViewId;
32   - private int leftDownViewId;
33   - private int rightUpViewId;
34   -
35   - public void setOrientation(int orientation) {
36   - if (this.orientation == orientation) {
37   - return;
38   - }
39   - this.orientation = orientation;
40   - requestLayout();
41   - }
42   -
43   - public OCRCameraLayout(Context context) {
44   - super(context);
45   - }
46   -
47   - public OCRCameraLayout(Context context, AttributeSet attrs) {
48   - super(context, attrs);
49   - parseAttrs(attrs);
50   - }
51   -
52   - public OCRCameraLayout(Context context, AttributeSet attrs, int defStyleAttr) {
53   - super(context, attrs, defStyleAttr);
54   - parseAttrs(attrs);
55   - }
56   -
57   - {
58   - setWillNotDraw(false);
59   - }
60   -
61   - private void parseAttrs(AttributeSet attrs) {
62   - TypedArray a = getContext().getTheme().obtainStyledAttributes(
63   - attrs,
64   - R.styleable.OCRCameraLayout,
65   - 0, 0);
66   - try {
67   - contentViewId = a.getResourceId(R.styleable.OCRCameraLayout_contentView, -1);
68   - centerViewId = a.getResourceId(R.styleable.OCRCameraLayout_centerView, -1);
69   - leftDownViewId = a.getResourceId(R.styleable.OCRCameraLayout_leftDownView, -1);
70   - rightUpViewId = a.getResourceId(R.styleable.OCRCameraLayout_rightUpView, -1);
71   - } finally {
72   - a.recycle();
73   - }
74   - }
75   -
76   - @Override
77   - protected void onAttachedToWindow() {
78   - super.onAttachedToWindow();
79   - contentView = findViewById(contentViewId);
80   - if (centerViewId != -1) {
81   - centerView = findViewById(centerViewId);
82   - }
83   - leftDownView = findViewById(leftDownViewId);
84   - rightUpView = findViewById(rightUpViewId);
85   - }
86   -
87   - private Rect backgroundRect = new Rect();
88   - private Paint paint = new Paint();
89   -
90   - {
91   - paint.setStyle(Paint.Style.FILL);
92   - paint.setColor(Color.argb(83, 0, 0, 0));
93   - }
94   -
95   - @Override
96   - protected void onLayout(boolean changed, int l, int t, int r, int b) {
97   - int width = getWidth();
98   - int height = getHeight();
99   - int left;
100   - int top;
101   -
102   - MarginLayoutParams leftDownViewLayoutParams = (MarginLayoutParams) leftDownView.getLayoutParams();
103   - MarginLayoutParams rightUpViewLayoutParams = (MarginLayoutParams) rightUpView.getLayoutParams();
104   - if (r < b) {
105   - int contentHeight = width * 4 / 3;
106   - int heightLeft = height - contentHeight;
107   - contentView.layout(l, t, r, contentHeight);
108   -
109   - backgroundRect.left = 0;
110   - backgroundRect.top = contentHeight;
111   - backgroundRect.right = width;
112   - backgroundRect.bottom = height;
113   -
114   - // layout centerView;
115   - if (centerView != null) {
116   - left = (width - centerView.getMeasuredWidth()) / 2;
117   - top = contentHeight + (heightLeft - centerView.getMeasuredHeight()) / 2;
118   - centerView
119   - .layout(left, top, left + centerView.getMeasuredWidth(), top + centerView.getMeasuredHeight());
120   - }
121   - // layout leftDownView
122   -
123   - left = leftDownViewLayoutParams.leftMargin;
124   - top = contentHeight + (heightLeft - leftDownView.getMeasuredHeight()) / 2;
125   - leftDownView
126   - .layout(left, top, left + leftDownView.getMeasuredWidth(), top + leftDownView.getMeasuredHeight());
127   - // layout rightUpView
128   - left = width - rightUpView.getMeasuredWidth() - rightUpViewLayoutParams.rightMargin;
129   - top = contentHeight + (heightLeft - rightUpView.getMeasuredHeight()) / 2;
130   - rightUpView.layout(left, top, left + rightUpView.getMeasuredWidth(), top + rightUpView.getMeasuredHeight());
131   - } else {
132   - int contentWidth = height * 4 / 3;
133   - int widthLeft = width - contentWidth;
134   - contentView.layout(l, t, contentWidth, height);
135   -
136   - backgroundRect.left = contentWidth;
137   - backgroundRect.top = 0;
138   - backgroundRect.right = width;
139   - backgroundRect.bottom = height;
140   -
141   - // layout centerView
142   - if (centerView != null) {
143   - left = contentWidth + (widthLeft - centerView.getMeasuredWidth()) / 2;
144   - top = (height - centerView.getMeasuredHeight()) / 2;
145   - centerView
146   - .layout(left, top, left + centerView.getMeasuredWidth(), top + centerView.getMeasuredHeight());
147   - }
148   - // layout leftDownView
149   - left = contentWidth + (widthLeft - leftDownView.getMeasuredWidth()) / 2;
150   - top = height - leftDownView.getMeasuredHeight() - leftDownViewLayoutParams.bottomMargin;
151   - leftDownView
152   - .layout(left, top, left + leftDownView.getMeasuredWidth(), top + leftDownView.getMeasuredHeight());
153   - // layout rightUpView
154   - left = contentWidth + (widthLeft - rightUpView.getMeasuredWidth()) / 2;
155   -
156   - top = rightUpViewLayoutParams.topMargin;
157   - rightUpView.layout(left, top, left + rightUpView.getMeasuredWidth(), top + rightUpView.getMeasuredHeight());
158   - }
159   - }
160   -
161   - @Override
162   - protected void onDraw(Canvas canvas) {
163   - super.onDraw(canvas);
164   - canvas.drawRect(backgroundRect, paint);
165   - }
166   -}
core/dentity_verfication/src/main/java/com/cnlive/core/ocr/ui/camera/OCRFrameLayout.java deleted 100644 → 0
1   -/*
2   - * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
3   - */
4   -package com.cnlive.core.ocr.ui.camera;
5   -
6   -
7   -import android.content.Context;
8   -import android.util.AttributeSet;
9   -import android.view.View;
10   -import android.view.ViewGroup;
11   -
12   -public class OCRFrameLayout extends ViewGroup {
13   -
14   - public OCRFrameLayout(Context context) {
15   - super(context);
16   - }
17   -
18   - public OCRFrameLayout(Context context, AttributeSet attrs) {
19   - super(context, attrs);
20   - parseAttrs(attrs);
21   - }
22   -
23   - public OCRFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
24   - super(context, attrs, defStyleAttr);
25   - parseAttrs(attrs);
26   - }
27   -
28   - private void parseAttrs(AttributeSet attrs) {
29   - }
30   -
31   - @Override
32   - protected void onLayout(boolean changed, int l, int t, int r, int b) {
33   - int childCount = getChildCount();
34   - for (int i = 0; i < childCount; i++) {
35   - View view = getChildAt(i);
36   - view.layout(l, t, r, b);
37   - }
38   - }
39   -
40   - @Override
41   - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
42   - super.onMeasure(widthMeasureSpec, heightMeasureSpec);
43   - int width;
44   - int height;
45   - int childCount = getChildCount();
46   -
47   - width = MeasureSpec.getSize(widthMeasureSpec);
48   - height = MeasureSpec.getSize(heightMeasureSpec);
49   - for (int i = 0; i < childCount; i++) {
50   - View view = getChildAt(i);
51   - measureChild(view, MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec
52   - (height, MeasureSpec.EXACTLY));
53   - }
54   - setMeasuredDimension(resolveSize(width, widthMeasureSpec), resolveSize(height, heightMeasureSpec));
55   - }
56   -}
core/dentity_verfication/src/main/java/com/cnlive/core/ocr/ui/camera/PermissionCallback.java deleted 100644 → 0
1   -/*
2   - * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
3   - */
4   -package com.cnlive.core.ocr.ui.camera;
5   -
6   -public interface PermissionCallback {
7   - boolean onRequestPermission();
8   -}
core/dentity_verfication/src/main/java/com/cnlive/core/ocr/ui/crop/CropView.java deleted 100644 → 0
1   -/*
2   - * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
3   - */
4   -package com.cnlive.core.ocr.ui.crop;
5   -
6   -import android.content.Context;
7   -import android.graphics.Bitmap;
8   -import android.graphics.BitmapFactory;
9   -import android.graphics.Canvas;
10   -import android.graphics.Matrix;
11   -import android.graphics.Point;
12   -import android.graphics.Rect;
13   -import android.media.ExifInterface;
14   -import android.util.AttributeSet;
15   -import android.view.GestureDetector;
16   -import android.view.MotionEvent;
17   -import android.view.ScaleGestureDetector;
18   -import android.view.View;
19   -import android.view.WindowManager;
20   -
21   -import com.cnlive.core.libs.base.util.AlertUtil;
22   -import com.cnlive.core.ocr.ui.util.ImageUtil;
23   -
24   -import java.io.IOException;
25   -
26   -public class CropView extends View {
27   -
28   - public CropView(Context context) {
29   - super(context);
30   - init();
31   - }
32   -
33   - public CropView(Context context, AttributeSet attrs) {
34   - super(context, attrs);
35   - init();
36   - }
37   -
38   - public CropView(Context context, AttributeSet attrs, int defStyleAttr) {
39   - super(context, attrs, defStyleAttr);
40   - init();
41   - }
42   -
43   - public void setFilePath(String path) {
44   -
45   - if (this.bitmap != null && !this.bitmap.isRecycled()) {
46   - this.bitmap.recycle();
47   - }
48   -
49   - if (path == null) {
50   - return;
51   - }
52   -
53   - BitmapFactory.Options options = new BitmapFactory.Options();
54   - options.inJustDecodeBounds = true;
55   - Bitmap original = BitmapFactory.decodeFile(path, options);
56   -
57   - try {
58   - ExifInterface exif = new ExifInterface(path);
59   - int rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
60   - Matrix matrix = new Matrix();
61   - int rotationInDegrees = ImageUtil.exifToDegrees(rotation);
62   - if (rotation != 0f) {
63   - matrix.preRotate(rotationInDegrees);
64   - }
65   -
66   - // 图片太大会导致内存泄露,所以在显示前对图片进行裁剪。
67   - int maxPreviewImageSize = 2560;
68   -
69   - int min = Math.min(options.outWidth, options.outHeight);
70   - min = Math.min(min, maxPreviewImageSize);
71   -
72   - WindowManager windowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
73   - Point screenSize = new Point();
74   - windowManager.getDefaultDisplay().getSize(screenSize);
75   - min = Math.min(min, screenSize.x * 2 / 3);
76   -
77   - options.inSampleSize = ImageUtil.calculateInSampleSize(options, min, min);
78   - options.inScaled = true;
79   - options.inDensity = options.outWidth;
80   - options.inTargetDensity = min * options.inSampleSize;
81   - options.inPreferredConfig = Bitmap.Config.RGB_565;
82   -
83   - options.inJustDecodeBounds = false;
84   - this.bitmap = BitmapFactory.decodeFile(path, options);
85   - } catch (IOException e) {
86   - e.printStackTrace();
87   - this.bitmap = original;
88   - } catch (NullPointerException e) {
89   - e.printStackTrace();
90   - }
91   - setBitmap(this.bitmap);
92   - }
93   -
94   - private void setBitmap(Bitmap bitmap) {
95   - this.bitmap = bitmap;
96   - matrix.reset();
97   - centerImage(getWidth(), getHeight());
98   - rotation = 0;
99   - invalidate();
100   - }
101   -
102   - @Override
103   - protected void onSizeChanged(int w, int h, int oldw, int oldh) {
104   - super.onSizeChanged(w, h, oldw, oldh);
105   - centerImage(w, h);
106   - invalidate();
107   - }
108   -
109   - public Bitmap crop(Rect frame) {
110   - float scale = getScale();
111   -
112   - float[] src = new float[] {frame.left, frame.top};
113   - float[] desc = new float[] {0, 0};
114   -
115   - Matrix invertedMatrix = new Matrix();
116   - this.matrix.invert(invertedMatrix);
117   - invertedMatrix.mapPoints(desc, src);
118   -
119   - Matrix matrix = new Matrix();
120   -
121   - int width = (int) (frame.width() / scale);
122   - int height = (int) (frame.height() / scale);
123   - Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
124   - Canvas canvas = new Canvas(bitmap);
125   -
126   - Bitmap originalBitmap = this.bitmap;
127   - if(originalBitmap == null){
128   - AlertUtil.showDeftToast(getContext(),"该照片已失效,请重新选择");
129   - return null;
130   - }
131   - matrix.postTranslate(-desc[0], -desc[1]);
132   - canvas.drawBitmap(originalBitmap, matrix, null);
133   - return bitmap;
134   - }
135   -
136   - public void setMinimumScale(float setMinimumScale) {
137   - this.setMinimumScale = setMinimumScale;
138   - }
139   -
140   - public void setMaximumScale(float maximumScale) {
141   - this.maximumScale = maximumScale;
142   - }
143   -
144   - private float setMinimumScale = 0.2f;
145   - private float maximumScale = 4.0f;
146   -
147   - private float[] matrixArray = new float[9];
148   - private Matrix matrix = new Matrix();
149   - private Bitmap bitmap;
150   -
151   - private GestureDetector gestureDetector;
152   -
153   - private ScaleGestureDetector scaleGestureDetector;
154   - private ScaleGestureDetector.OnScaleGestureListener onScaleGestureListener =
155   - new ScaleGestureDetector.OnScaleGestureListener() {
156   - @Override
157   - public boolean onScale(ScaleGestureDetector detector) {
158   - scale(detector);
159   - return true;
160   - }
161   -
162   - @Override
163   - public boolean onScaleBegin(ScaleGestureDetector detector) {
164   - return true;
165   - }
166   -
167   - @Override
168   - public void onScaleEnd(ScaleGestureDetector detector) {
169   - float scale = detector.getScaleFactor();
170   - matrix.postScale(scale, scale);
171   - invalidate();
172   - }
173   - };
174   -
175   - private void init() {
176   - scaleGestureDetector = new ScaleGestureDetector(getContext(), onScaleGestureListener);
177   - gestureDetector = new GestureDetector(getContext(), new GestureDetector.OnGestureListener() {
178   - @Override
179   - public boolean onDown(MotionEvent e) {
180   - return true;
181   - }
182   -
183   - @Override
184   - public void onShowPress(MotionEvent e) {
185   - }
186   -
187   - @Override
188   - public boolean onSingleTapUp(MotionEvent e) {
189   - return false;
190   - }
191   -
192   - @Override
193   - public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
194   - translate(distanceX, distanceY);
195   - return true;
196   - }
197   -
198   - @Override
199   - public void onLongPress(MotionEvent e) {
200   - }
201   -
202   - @Override
203   - public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
204   - return false;
205   - }
206   - });
207   - }
208   -
209   - int rotation = 0;
210   -
211   - public void rotate(int degrees) {
212   - Matrix matrix = new Matrix();
213   -
214   - if(bitmap == null) return;
215   - int dx = this.bitmap.getWidth() / 2;
216   - int dy = this.bitmap.getHeight() / 2;
217   -
218   - matrix.postTranslate(-dx, -dy);
219   - matrix.postRotate(degrees);
220   - matrix.postTranslate(dy, dx);
221   - Bitmap scaledBitmap = this.bitmap;
222   - Bitmap rotatedBitmap = Bitmap.createBitmap(scaledBitmap.getHeight(), scaledBitmap.getWidth(),
223   - Bitmap.Config.RGB_565);
224   - Canvas canvas = new Canvas(rotatedBitmap);
225   - canvas.drawBitmap(this.bitmap, matrix, null);
226   - this.bitmap.recycle();
227   - this.bitmap = rotatedBitmap;
228   - centerImage(getWidth(), getHeight());
229   - invalidate();
230   - }
231   -
232   - private void translate(float distanceX, float distanceY) {
233   - matrix.getValues(matrixArray);
234   - float left = matrixArray[Matrix.MTRANS_X];
235   - float top = matrixArray[Matrix.MTRANS_Y];
236   -
237   - Rect bound = getRestrictedBound();
238   - if (bound != null) {
239   - float scale = getScale();
240   - float right = left + (int) (bitmap.getWidth() / scale);
241   - float bottom = top + (int) (bitmap.getHeight() / scale);
242   -
243   - if (left - distanceX > bound.left) {
244   - distanceX = left - bound.left;
245   - }
246   - if (top - distanceY > bound.top) {
247   - distanceY = top - bound.top;
248   - }
249   -
250   - if (distanceX > 0) {
251   - if (right - distanceX < bound.right) {
252   - distanceX = right - bound.right;
253   - }
254   - }
255   - if (distanceY > 0) {
256   - if (bottom - distanceY < bound.bottom) {
257   - distanceY = bottom - bound.bottom;
258   - }
259   - }
260   - }
261   - matrix.postTranslate(-distanceX, -distanceY);
262   - invalidate();
263   - }
264   -
265   - private void scale(ScaleGestureDetector detector) {
266   - float scale = detector.getScaleFactor();
267   - float currentScale = getScale();
268   - if (currentScale * scale < setMinimumScale) {
269   - scale = setMinimumScale / currentScale;
270   - }
271   - if (currentScale * scale > maximumScale) {
272   - scale = maximumScale / currentScale;
273   - }
274   - matrix.postScale(scale, scale, detector.getFocusX(), detector.getFocusY());
275   - invalidate();
276   - }
277   -
278   - private void centerImage(int width, int height) {
279   - if (width <= 0 || height <= 0 || bitmap == null) {
280   - return;
281   - }
282   - float widthRatio = 1.0f * height / this.bitmap.getHeight();
283   - float heightRatio = 1.0f * width / this.bitmap.getWidth();
284   -
285   - float ratio = Math.min(widthRatio, heightRatio);
286   -
287   - float dx = (width - this.bitmap.getWidth()) / 2;
288   - float dy = (height - this.bitmap.getHeight()) / 2;
289   - matrix.setTranslate(0, 0);
290   - matrix.setScale(ratio, ratio, bitmap.getWidth() / 2, bitmap.getHeight() / 2);
291   - matrix.postTranslate(dx, dy);
292   - invalidate();
293   - }
294   -
295   - private float getScale() {
296   - matrix.getValues(matrixArray);
297   - float scale = matrixArray[Matrix.MSCALE_X];
298   - if (Math.abs(scale) <= 0.1) {
299   - scale = matrixArray[Matrix.MSKEW_X];
300   - }
301   - return Math.abs(scale);
302   - }
303   -
304   - @Override
305   - protected void onDraw(Canvas canvas) {
306   - super.onDraw(canvas);
307   - if (bitmap != null) {
308   - canvas.drawBitmap(bitmap, matrix, null);
309   - }
310   - }
311   -
312   - @Override
313   - public boolean onTouchEvent(MotionEvent event) {
314   - boolean result = scaleGestureDetector.onTouchEvent(event);
315   - result = gestureDetector.onTouchEvent(event) || result;
316   - return result || super.onTouchEvent(event);
317   - }
318   -
319   - private Rect restrictBound;
320   -
321   - private Rect getRestrictedBound() {
322   - return restrictBound;
323   - }
324   -
325   - public void setRestrictBound(Rect rect) {
326   - this.restrictBound = rect;
327   - }
328   -}