├── .gitignore
├── .idea
├── caches
│ └── build_file_checksums.ser
├── codeStyles
│ └── Project.xml
├── gradle.xml
├── inspectionProfiles
│ └── Project_Default.xml
├── jarRepositories.xml
├── misc.xml
├── modules.xml
├── runConfigurations.xml
└── vcs.xml
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── camera
│ │ └── cn
│ │ └── cameramaster
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── assets
│ │ └── web
│ │ │ ├── css
│ │ │ └── login.css
│ │ │ ├── image
│ │ │ └── logo.png
│ │ │ ├── index.html
│ │ │ └── login.html
│ ├── java
│ │ └── camera
│ │ │ └── cn
│ │ │ └── cameramaster
│ │ │ ├── OpenReceiver.java
│ │ │ ├── adapter
│ │ │ ├── EffectAdapter.java
│ │ │ ├── MenuAdapter.java
│ │ │ └── SenseAdapter.java
│ │ │ ├── base
│ │ │ ├── App.java
│ │ │ └── BaseActivity.java
│ │ │ ├── bean
│ │ │ └── Lab.java
│ │ │ ├── filter
│ │ │ ├── AFilter.java
│ │ │ └── TextureFilter.java
│ │ │ ├── server
│ │ │ ├── AnyEventType.java
│ │ │ ├── CoreService.java
│ │ │ ├── ServerManager.java
│ │ │ ├── TestController.java
│ │ │ ├── component
│ │ │ │ └── LoggerInterceptor.java
│ │ │ ├── model
│ │ │ │ └── UserInfo.java
│ │ │ └── util
│ │ │ │ ├── FileUtils.java
│ │ │ │ └── NetUtils.java
│ │ │ ├── ui
│ │ │ ├── Camera2Activity.java
│ │ │ ├── CameraActivity.java
│ │ │ ├── CameraSurfaceViewActivity.java
│ │ │ ├── CameraVideoActivity.java
│ │ │ ├── GoogleCameraActivity.java
│ │ │ ├── MainActivity.java
│ │ │ └── ShowPicActivity.java
│ │ │ ├── util
│ │ │ ├── AppConstant.java
│ │ │ ├── BitmapUtils.java
│ │ │ ├── Camera2Util.java
│ │ │ ├── CameraUtil.java
│ │ │ ├── CameraV2.java
│ │ │ ├── CompareSizesByArea.java
│ │ │ ├── FilterEngine.java
│ │ │ ├── LabUtil.java
│ │ │ ├── MatrixUtils.java
│ │ │ ├── Utils.java
│ │ │ ├── cameravideo
│ │ │ │ ├── CameraHelper.java
│ │ │ │ ├── CoordinateTransformer.java
│ │ │ │ ├── ICamera2.java
│ │ │ │ ├── IVideoControl.java
│ │ │ │ └── VideoPlayer.java
│ │ │ └── render
│ │ │ │ └── CameraV2Renderer.java
│ │ │ └── view
│ │ │ ├── AnimationTextView.java
│ │ │ ├── AutoFitTextureView.java
│ │ │ ├── AutoLocateHorizontalView.java
│ │ │ ├── AutoTextureView.java
│ │ │ ├── AwbSeekBar.java
│ │ │ ├── AwbSeekBarChangeListener.java
│ │ │ ├── CameraV2GLSurfaceView.java
│ │ │ ├── ShowSurfaceView.java
│ │ │ └── SleepThread.java
│ └── res
│ │ ├── anim
│ │ ├── alpha_in.xml
│ │ └── alpha_out.xml
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ ├── ic_camera.xml
│ │ ├── ic_fouces.xml
│ │ ├── ic_launcher_background.xml
│ │ └── ic_launcher_camera.xml
│ │ ├── layout
│ │ ├── activity_camera.xml
│ │ ├── activity_camera2.xml
│ │ ├── activity_camera_sv.xml
│ │ ├── activity_camera_video.xml
│ │ ├── activity_google_camera.xml
│ │ ├── activity_look_camera.xml
│ │ ├── activity_main.xml
│ │ ├── activity_show_pic.xml
│ │ ├── item_age.xml
│ │ └── item_rv_text.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── btn_ae.png
│ │ ├── btn_album.png
│ │ ├── btn_awb.png
│ │ ├── btn_camera_turn_n.png
│ │ ├── btn_change_camera_normal.png
│ │ ├── btn_effect.png
│ │ ├── btn_flash_auto_normal.png
│ │ ├── btn_flash_off_normal.png
│ │ ├── btn_flash_on_normal.png
│ │ ├── btn_iso.png
│ │ ├── btn_sense.png
│ │ ├── btn_zoom.png
│ │ ├── flash_auto.png
│ │ ├── flash_close.png
│ │ ├── flash_open.png
│ │ ├── ic_add.png
│ │ ├── ic_camera_wb_auto.png
│ │ ├── ic_camera_wb_cloudy_daylight.png
│ │ ├── ic_camera_wb_daylight.png
│ │ ├── ic_camera_wb_fluorescent.png
│ │ ├── ic_camera_wb_incandescent.png
│ │ ├── ic_camera_wb_shade.png
│ │ ├── ic_camera_wb_twilight.png
│ │ ├── ic_camera_wb_warm_fluorescent.png
│ │ ├── ic_close.png
│ │ ├── ic_delete.png
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_background.xml
│ │ ├── ic_launcher_round.png
│ │ ├── ic_minus.png
│ │ ├── ic_pause.png
│ │ ├── ic_play.png
│ │ ├── ic_recording.png
│ │ ├── ic_save.png
│ │ ├── ic_switch_camera.png
│ │ ├── ic_video_close.png
│ │ ├── icon_back.xml
│ │ ├── icon_camera_a.png
│ │ ├── icon_camera_off.png
│ │ └── icon_camera_on.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── raw
│ │ ├── base_fragment_shader.glsl
│ │ └── base_vertex_shader.glsl
│ │ ├── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ │ └── xml
│ │ └── file_paths.xml
│ └── test
│ └── java
│ └── camera
│ └── cn
│ └── cameramaster
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 |
--------------------------------------------------------------------------------
/.idea/caches/build_file_checksums.ser:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/.idea/caches/build_file_checksums.ser
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | xmlns:android
14 |
15 | ^$
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | xmlns:.*
25 |
26 | ^$
27 |
28 |
29 | BY_NAME
30 |
31 |
32 |
33 |
34 |
35 |
36 | .*:id
37 |
38 | http://schemas.android.com/apk/res/android
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | .*:name
48 |
49 | http://schemas.android.com/apk/res/android
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | name
59 |
60 | ^$
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | style
70 |
71 | ^$
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 | .*
81 |
82 | ^$
83 |
84 |
85 | BY_NAME
86 |
87 |
88 |
89 |
90 |
91 |
92 | .*
93 |
94 | http://schemas.android.com/apk/res/android
95 |
96 |
97 | ANDROID_ATTRIBUTE_ORDER
98 |
99 |
100 |
101 |
102 |
103 |
104 | .*
105 |
106 | .*
107 |
108 |
109 | BY_NAME
110 |
111 |
112 |
113 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
19 |
20 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/.idea/jarRepositories.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | 1.8
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SunCamera
2 |
3 | 一个 学习自定义的 Camera1 、Camera2 、Camera X 和 OpenglES 的Demo
4 |
5 | # 版本迭代
6 |
7 | - 1.3 完善部分bug (暂时停止维护,抽空整理成底层SDK,相对架构来一次深度的学习)
8 | - 1.2 添加 拍照录像及硬件设备信息调节界面
9 | - 1.1 添加 Camera 2 相机使用界面
10 | - 1.0 添加 Camera 1 相机使用界面
11 |
12 | # 感谢
13 |
14 | https://github.com/chensowf/Camera 录像代码部分参考和学习。感谢开源
15 |
16 |
17 | # 效果图
18 |
19 | 1. 目前 拍照 摄像界面 效果界面主要 在 CameraVideoActivity 界面中。
20 |
21 | 
22 |
23 | 2.camera+surfaceview 博客地址:https://www.jianshu.com/p/af39024896ce
24 |
25 | 
26 |
27 |
28 | 3. camera2 + TextureView 博客地址 : https://www.jianshu.com/p/c99fd9dfd77f
29 |
30 | 4. camera2 + glSurfaceview + opengles 博客地址 : https://www.jianshu.com/p/e4ece3f21ec8
31 |
32 | 
33 |
34 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 27
5 | defaultConfig {
6 | applicationId "camera.cn.cameramaster"
7 | minSdkVersion 17
8 | targetSdkVersion 27
9 | versionCode 103
10 | versionName "1.0.3"
11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
12 | }
13 | buildTypes {
14 | debug {
15 | debuggable true
16 | zipAlignEnabled false
17 | minifyEnabled false
18 | shrinkResources false
19 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
20 | }
21 |
22 | release {
23 | debuggable false
24 | zipAlignEnabled true
25 | minifyEnabled true
26 | shrinkResources true
27 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
28 | }
29 | }
30 | buildToolsVersion '27.0.3'
31 | }
32 |
33 | dependencies {
34 | implementation fileTree(include: ['*.jar'], dir: 'libs')
35 | implementation 'com.android.support:appcompat-v7:27.1.1'
36 | implementation 'com.android.support.constraint:constraint-layout:1.1.3'
37 | testImplementation 'junit:junit:4.12'
38 | implementation 'com.android.support:cardview-v7:27.1.1'
39 | implementation 'com.android.support:recyclerview-v7:27.1.1'
40 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
41 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
42 | // butterknife
43 | implementation 'com.jakewharton:butterknife:8.8.1'
44 | annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
45 | // permission
46 | implementation 'com.yanzhenjie:permission:2.0.0-rc4'
47 | implementation 'com.android.support:exifinterface:27.1.1'
48 | // api
49 | implementation 'com.yanzhenjie.andserver:api:2.0.4'
50 | annotationProcessor 'com.yanzhenjie.andserver:processor:2.0.4'
51 | // load json
52 | implementation 'com.alibaba:fastjson:1.2.48'
53 | implementation 'com.yanzhenjie:loading:1.0.0'
54 | // event bus
55 | implementation 'org.greenrobot:eventbus:3.1.1'
56 |
57 | api "io.reactivex.rxjava2:rxjava:2.1.0"
58 | api "io.reactivex.rxjava2:rxandroid:2.1.0"
59 | }
60 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
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
22 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/camera/cn/cameramaster/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package camera.cn.cameramaster;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("camera.cn.cameramaster", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
15 |
16 |
17 |
18 |
19 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
65 |
66 |
67 |
68 |
73 |
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/app/src/main/assets/web/css/login.css:
--------------------------------------------------------------------------------
1 | .sec_body { color:#404040;background:#EBEBEB;text-shadow:#ddd 0 1px 0px;font-family:Helvetica;line-height:1.5;font-size:small; }
2 | .center_father {color:#404040;text-align: center;}
3 | .center_son { margin-right: auto; margin-left: auto; }
--------------------------------------------------------------------------------
/app/src/main/assets/web/image/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/assets/web/image/logo.png
--------------------------------------------------------------------------------
/app/src/main/assets/web/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | AndServer Sample
8 |
11 |
12 |
13 |
14 |
15 |
Login
16 | More, please see the sample code.
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/assets/web/login.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Sign In
10 |
11 |
12 |
13 |
14 |
Sign In
15 |
16 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/OpenReceiver.java:
--------------------------------------------------------------------------------
1 | package camera.cn.cameramaster;
2 |
3 | import android.content.BroadcastReceiver;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.util.Log;
7 |
8 | import camera.cn.cameramaster.ui.MainActivity;
9 |
10 | /**
11 | * 开机
12 | * @packageName: cn.tongue.tonguecamera
13 | * @fileName: OpenReceiver
14 | * @date: 2019/1/28 13:09
15 | * @author: ymc
16 | * @QQ:745612618
17 | */
18 |
19 | public class OpenReceiver extends BroadcastReceiver {
20 | @Override
21 | public void onReceive(Context context, Intent intent) {
22 |
23 | Log.i("broadCastReceiver","onReceiver...");
24 |
25 | Intent mBootIntent = new Intent(context, MainActivity.class);
26 | // 必须设置FLAG_ACTIVITY_NEW_TASK
27 | mBootIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
28 | context.startActivity(mBootIntent);
29 |
30 | }
31 |
32 | }
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/adapter/EffectAdapter.java:
--------------------------------------------------------------------------------
1 | package camera.cn.cameramaster.adapter;
2 |
3 | import android.content.Context;
4 | import android.support.annotation.NonNull;
5 | import android.support.v7.widget.RecyclerView;
6 | import android.util.Log;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.TextView;
11 |
12 | import butterknife.BindView;
13 | import butterknife.ButterKnife;
14 | import camera.cn.cameramaster.R;
15 |
16 | /**
17 | * effect 适配器
18 | *
19 | * @packageName: cn.tongue.tonguecamera.adapter
20 | * @fileName: EffectAdapter
21 | * @date: 2019/4/17 14:33
22 | * @author: ymc
23 | * @QQ:745612618
24 | */
25 |
26 | public class EffectAdapter extends RecyclerView.Adapter {
27 | private LayoutInflater mLayoutInflater;
28 | private String[] effectArr;
29 |
30 | public EffectAdapter(Context mContext,String[] arr) {
31 | this.effectArr = arr;
32 | mLayoutInflater = LayoutInflater.from(mContext);
33 | }
34 |
35 | @NonNull
36 | @Override
37 | public EffectViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
38 | return new EffectViewHolder(mLayoutInflater.inflate(R.layout.item_rv_text, parent, false));
39 | }
40 |
41 | @Override
42 | public void onBindViewHolder(@NonNull EffectViewHolder holder, int position) {
43 | holder.mTextView.setText(effectArr[position]);
44 | }
45 |
46 | @Override
47 | public int getItemCount() {
48 | return effectArr.length;
49 | }
50 |
51 | public class EffectViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
52 | @BindView(R.id.text_view)
53 | TextView mTextView;
54 |
55 | EffectViewHolder(View view) {
56 | super(view);
57 | ButterKnife.bind(this, view);
58 | view.setOnClickListener(this);
59 | }
60 |
61 | @Override
62 | public void onClick(View v) {
63 | if (effectOnItemClickListener != null) {
64 | effectOnItemClickListener.itemOnClick(getPosition());
65 | }
66 | }
67 | }
68 |
69 | private EffectOnItemClickListener effectOnItemClickListener;
70 |
71 | public interface EffectOnItemClickListener {
72 |
73 | void itemOnClick(int position);
74 |
75 | }
76 |
77 | public void setEffectOnItemClickListener(EffectOnItemClickListener effectOnItemClickListener) {
78 | this.effectOnItemClickListener = effectOnItemClickListener;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/adapter/MenuAdapter.java:
--------------------------------------------------------------------------------
1 | package camera.cn.cameramaster.adapter;
2 |
3 | import android.content.Context;
4 | import android.graphics.Color;
5 | import android.support.annotation.NonNull;
6 | import android.support.v7.widget.RecyclerView;
7 | import android.util.TypedValue;
8 | import android.view.LayoutInflater;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.widget.TextView;
12 |
13 | import java.util.List;
14 |
15 | import camera.cn.cameramaster.R;
16 | import camera.cn.cameramaster.view.AutoLocateHorizontalView;
17 |
18 | /**
19 | * 选项适配器
20 | *
21 | * @author ymc
22 | * @date 2019年5月8日 10:38:54
23 | */
24 |
25 | public class MenuAdapter extends RecyclerView.Adapter
26 | implements AutoLocateHorizontalView.IAutoLocateHorizontalView {
27 | private Context context;
28 | private View view;
29 | private List ages;
30 | private AutoLocateHorizontalView recyclerView;
31 |
32 | public MenuAdapter(Context context, List ages, AutoLocateHorizontalView recyclerView){
33 | this.context = context;
34 | this.ages = ages;
35 | this.recyclerView = recyclerView;
36 | }
37 |
38 | @NonNull
39 | @Override
40 | public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
41 | view = LayoutInflater.from(context).inflate(R.layout.item_age,parent,false);
42 | return new ItemViewHolder(view);
43 | }
44 |
45 | @Override
46 | public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) {
47 | holder.tvAge.setText(ages.get(position));
48 | }
49 |
50 | @Override
51 | public int getItemCount() {
52 | return ages.size();
53 | }
54 |
55 | @Override
56 | public View getItemView() {
57 | return view;
58 | }
59 |
60 | @Override
61 | public void onViewSelected(boolean isSelected, int pos, RecyclerView.ViewHolder holder, int itemWidth) {
62 | if(isSelected) {
63 | ((ItemViewHolder) holder).tvAge.setTextSize(TypedValue.COMPLEX_UNIT_SP,16);
64 | ((ItemViewHolder) holder).tvAge.setTextColor(Color.WHITE);
65 | ((ItemViewHolder) holder).tvAge.setAlpha(1.0f);
66 | }else{
67 | ((ItemViewHolder) holder).tvAge.setTextSize(TypedValue.COMPLEX_UNIT_SP,14);
68 | ((ItemViewHolder) holder).tvAge.setTextColor(Color.rgb(0xfe,0xfe,0xfe));
69 | ((ItemViewHolder) holder).tvAge.setAlpha(0.5f);
70 | }
71 | }
72 |
73 | class ItemViewHolder extends RecyclerView.ViewHolder{
74 | TextView tvAge;
75 | ItemViewHolder(View itemView) {
76 | super(itemView);
77 | tvAge = itemView.findViewById(R.id.tv_age);
78 | tvAge.setTag(this);
79 | tvAge.setOnClickListener(new View.OnClickListener() {
80 | @Override
81 | public void onClick(View v) {
82 | ItemViewHolder itemViewHolder = (ItemViewHolder)v.getTag();
83 | int position = recyclerView.getChildAdapterPosition(itemViewHolder.itemView);
84 | position--;
85 | recyclerView.moveToPosition(position);
86 | }
87 | });
88 | }
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/adapter/SenseAdapter.java:
--------------------------------------------------------------------------------
1 | package camera.cn.cameramaster.adapter;
2 |
3 | import android.content.Context;
4 | import android.support.annotation.NonNull;
5 | import android.support.v7.widget.RecyclerView;
6 | import android.util.Log;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.TextView;
11 |
12 | import butterknife.BindView;
13 | import butterknife.ButterKnife;
14 | import camera.cn.cameramaster.R;
15 |
16 | /**
17 | * effect 适配器
18 | *
19 | * @packageName: cn.tongue.tonguecamera.adapter
20 | * @fileName: EffectAdapter
21 | * @date: 2019/4/17 14:33
22 | * @author: ymc
23 | * @QQ:745612618
24 | */
25 |
26 | public class SenseAdapter extends RecyclerView.Adapter {
27 | private LayoutInflater mLayoutInflater;
28 | private String[] senseArr;
29 |
30 | public SenseAdapter(Context mContext,String[] arr) {
31 | this.senseArr = arr;
32 | mLayoutInflater = LayoutInflater.from(mContext);
33 | }
34 |
35 | @NonNull
36 | @Override
37 | public EffectViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
38 | return new EffectViewHolder(mLayoutInflater.inflate(R.layout.item_rv_text, parent, false));
39 | }
40 |
41 | @Override
42 | public void onBindViewHolder(@NonNull EffectViewHolder holder, int position) {
43 | holder.mTextView.setText(senseArr[position]);
44 | }
45 |
46 | @Override
47 | public int getItemCount() {
48 | return senseArr.length;
49 | }
50 |
51 | public class EffectViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
52 | @BindView(R.id.text_view)
53 | TextView mTextView;
54 |
55 | EffectViewHolder(View view) {
56 | super(view);
57 | ButterKnife.bind(this, view);
58 | view.setOnClickListener(this);
59 | }
60 |
61 | @Override
62 | public void onClick(View v) {
63 | if (senseOnItemClickListener != null) {
64 | senseOnItemClickListener.itemOnClick(getPosition());
65 | }
66 | }
67 | }
68 |
69 | private SenseOnItemClickListener senseOnItemClickListener;
70 |
71 | public interface SenseOnItemClickListener {
72 |
73 | void itemOnClick(int position);
74 |
75 | }
76 |
77 | public void setSenseOnItemClickListener(SenseOnItemClickListener senseOnItemClickListener) {
78 | this.senseOnItemClickListener = senseOnItemClickListener;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/base/App.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Yan Zhenjie.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package camera.cn.cameramaster.base;
17 |
18 | import android.app.Application;
19 | import android.content.Context;
20 | import android.os.Environment;
21 | import android.support.annotation.NonNull;
22 |
23 | import com.yanzhenjie.andserver.util.IOUtils;
24 |
25 | import java.io.File;
26 |
27 | import camera.cn.cameramaster.server.util.FileUtils;
28 |
29 |
30 | /**
31 | * application
32 | *
33 | * Created by YanZhenjie on 2018/6/9.
34 | * @author ymc
35 | */
36 |
37 | public class App extends Application {
38 |
39 | private static App mInstance;
40 |
41 | private File mRootDir;
42 |
43 | @Override
44 | public void onCreate() {
45 | super.onCreate();
46 |
47 | if (mInstance == null) {
48 | mInstance = this;
49 | initRootPath(this);
50 | }
51 | }
52 |
53 | @NonNull
54 | public static App getInstance() {
55 | return mInstance;
56 | }
57 |
58 | @NonNull
59 | public File getRootDir() {
60 | return mRootDir;
61 | }
62 |
63 | private void initRootPath(Context context) {
64 | if (mRootDir != null) {
65 | return;
66 | }
67 |
68 | if (FileUtils.storageAvailable()) {
69 | mRootDir = Environment.getExternalStorageDirectory();
70 | } else {
71 | mRootDir = context.getFilesDir();
72 | }
73 | mRootDir = new File(mRootDir, "AndServer");
74 | IOUtils.createFolder(mRootDir);
75 | }
76 | }
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/base/BaseActivity.java:
--------------------------------------------------------------------------------
1 | package camera.cn.cameramaster.base;
2 |
3 | import android.os.Build;
4 | import android.os.Bundle;
5 | import android.support.annotation.Nullable;
6 | import android.support.v4.view.ViewCompat;
7 | import android.support.v7.app.AppCompatActivity;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.view.Window;
11 | import android.view.WindowManager;
12 |
13 | import butterknife.ButterKnife;
14 | import butterknife.Unbinder;
15 | import camera.cn.cameramaster.R;
16 |
17 | /**
18 | * 基础Activity
19 | *
20 | * @packageName: cn.ymc.vip.suntimejava.base
21 | * @fileName: BaseActivity
22 | * @date: 2019/1/8 17:35
23 | * @author: ymc
24 | * @QQ:745612618
25 | */
26 |
27 | public abstract class BaseActivity extends AppCompatActivity {
28 |
29 | protected BaseActivity activity;
30 | private Unbinder bun;
31 |
32 | @Override
33 | protected void onCreate(@Nullable Bundle savedInstanceState) {
34 | super.onCreate(savedInstanceState);
35 | //去除标题栏
36 | supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
37 | //去除状态栏
38 | getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
39 | WindowManager.LayoutParams.FLAG_FULLSCREEN);
40 | setContentView(getLayoutId());
41 | // getSupportActionBar().hide();
42 | bun = ButterKnife.bind(this);
43 | activity = this;
44 | initStatusColor();
45 | initView();
46 | initData();
47 | }
48 |
49 | /**
50 | * 设置透明状态栏,这样才能让 ContentView 向上 6.0小米手机设置 tootlbar 会被挤上去
51 | * window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
52 | */
53 | private void initStatusColor() {
54 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
55 | Window window = activity.getWindow();
56 | window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
57 | //设置状态栏颜色
58 | window.setStatusBarColor(getColor(R.color.theme));
59 |
60 | ViewGroup mContentView = activity.findViewById(Window.ID_ANDROID_CONTENT);
61 | View mChildView = mContentView.getChildAt(0);
62 | if (mChildView != null) {
63 | //注意不是设置 ContentView 的 FitsSystemWindows, 而是设置 ContentView 的第一个子 View . 使其不为系统 View 预留空间.
64 | ViewCompat.setFitsSystemWindows(mChildView, false);
65 | }
66 | }
67 | }
68 |
69 | protected abstract int getLayoutId();
70 | protected abstract void initView();
71 | protected abstract void initData();
72 |
73 | @Override
74 | protected void onDestroy() {
75 | bun.unbind();
76 | super.onDestroy();
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/bean/Lab.java:
--------------------------------------------------------------------------------
1 | package camera.cn.cameramaster.bean;
2 |
3 | /**
4 | * lab 实体类
5 | *
6 | * @packageName: cn.tongue.tonguecamera.bean
7 | * @fileName: Lab
8 | * @date: 2019/4/3 13:37
9 | * @author: ymc
10 | * @QQ:745612618
11 | */
12 |
13 | public class Lab {
14 |
15 | public double L;
16 | public double a;
17 | public double b;
18 |
19 | public double getL() {
20 | return L;
21 | }
22 |
23 | public void setL(double l) {
24 | L = l;
25 | }
26 |
27 | public double getA() {
28 | return a;
29 | }
30 |
31 | public void setA(double a) {
32 | this.a = a;
33 | }
34 |
35 | public double getB() {
36 | return b;
37 | }
38 |
39 | public void setB(double b) {
40 | this.b = b;
41 | }
42 |
43 | @Override
44 | public String toString() {
45 | return "Lab l:" + L + " Lab a:" + a + " Lab b:" + b;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/filter/TextureFilter.java:
--------------------------------------------------------------------------------
1 | package camera.cn.cameramaster.filter;
2 |
3 | import android.content.res.Resources;
4 | import android.graphics.SurfaceTexture;
5 |
6 | import java.nio.ByteBuffer;
7 |
8 | /**
9 | * @packageName: cn.tongue.tonguecamera.filter
10 | * @fileName: TextureFilter
11 | * @date: 2019/3/15 14:40
12 | * @author: ymc
13 | * @QQ:745612618
14 | */
15 |
16 | public class TextureFilter extends AFilter{
17 | private int width=0;
18 | private int height=0;
19 |
20 | private int[] fFrame = new int[1];
21 | private int[] fTexture = new int[1];
22 | private int[] mCameraTexture=new int[1];
23 |
24 | private SurfaceTexture mSurfaceTexture;
25 | private float[] mCoordOM=new float[16];
26 | /**
27 | * 获取Track数据
28 | */
29 | private ByteBuffer tBuffer;
30 |
31 |
32 | public TextureFilter(Resources mRes) {
33 | super(mRes);
34 | }
35 |
36 | @Override
37 | protected void onCreate() {
38 |
39 | }
40 |
41 | @Override
42 | protected void onSizeChanged(int width, int height) {
43 |
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/server/AnyEventType.java:
--------------------------------------------------------------------------------
1 | package camera.cn.cameramaster.server;
2 |
3 | /**
4 | * event bus 消息类
5 | *
6 | * @packageName: cn.tongue.tonguecamera.eventbus
7 | * @fileName: AnyEventType
8 | * @date: 2019/4/24 18:36
9 | * @author: ymc
10 | * @QQ:745612618
11 | */
12 |
13 | public class AnyEventType {
14 |
15 | public AnyEventType(){}
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/server/CoreService.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2018 Yan Zhenjie.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package camera.cn.cameramaster.server;
17 |
18 | import android.app.Service;
19 | import android.content.Intent;
20 | import android.os.IBinder;
21 | import android.support.annotation.Nullable;
22 | import android.util.Log;
23 |
24 | import com.yanzhenjie.andserver.AndServer;
25 | import com.yanzhenjie.andserver.Server;
26 |
27 | import java.util.concurrent.TimeUnit;
28 |
29 | import camera.cn.cameramaster.server.util.NetUtils;
30 |
31 |
32 | /**
33 | * server
34 | *
35 | * Created by Yan Zhenjie on 2018/6/9.
36 | * @author ymc
37 | */
38 | public class CoreService extends Service {
39 | private static final String TAG = "CoreService";
40 | private Server mServer;
41 |
42 | @Override
43 | public void onCreate() {
44 | mServer = AndServer.serverBuilder()
45 | .inetAddress(NetUtils.getLocalIPAddress())
46 | .port(8081)
47 | .timeout(10, TimeUnit.SECONDS)
48 | .listener(new Server.ServerListener() {
49 | @Override
50 | public void onStarted() {
51 | String hostAddress = mServer.getInetAddress().getHostAddress();
52 | ServerManager.onServerStart(CoreService.this, hostAddress);
53 | Log.e(TAG, "onStarted: ");
54 | }
55 |
56 | @Override
57 | public void onStopped() {
58 | ServerManager.onServerStop(CoreService.this);
59 | Log.e(TAG, "onStopped: ");
60 | }
61 |
62 | @Override
63 | public void onException(Exception e) {
64 | ServerManager.onServerError(CoreService.this, e.getMessage());
65 | Log.e(TAG, "onException: ");
66 | }
67 | })
68 | .build();
69 | }
70 |
71 | @Override
72 | public int onStartCommand(Intent intent, int flags, int startId) {
73 | startServer();
74 | return START_STICKY;
75 | }
76 |
77 | @Override
78 | public void onDestroy() {
79 | stopServer();
80 | super.onDestroy();
81 | }
82 |
83 | /**
84 | * Start server.
85 | */
86 | private void startServer() {
87 | if (mServer.isRunning()) {
88 | String hostAddress = mServer.getInetAddress().getHostAddress();
89 | ServerManager.onServerStart(CoreService.this, hostAddress);
90 | } else {
91 | mServer.startup();
92 | }
93 | }
94 |
95 | /**
96 | * Stop server.
97 | */
98 | private void stopServer() {
99 | mServer.shutdown();
100 | }
101 |
102 | @Nullable
103 | @Override
104 | public IBinder onBind(Intent intent) {
105 | return null;
106 | }
107 | }
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/server/ServerManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2018 Yan Zhenjie.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package camera.cn.cameramaster.server;
17 |
18 | import android.content.BroadcastReceiver;
19 | import android.content.Context;
20 | import android.content.Intent;
21 | import android.content.IntentFilter;
22 | import android.os.Build;
23 | import android.support.annotation.RequiresApi;
24 |
25 | import camera.cn.cameramaster.ui.GoogleCameraActivity;
26 |
27 |
28 | /**
29 | *
30 | * Created by Yan Zhenjie on 2018/6/9.
31 | * @author ymc
32 | */
33 |
34 | public class ServerManager extends BroadcastReceiver {
35 |
36 | private static final String ACTION = "com.yanzhenjie.andserver.receiver";
37 |
38 | private static final String CMD_KEY = "CMD_KEY";
39 | private static final String MESSAGE_KEY = "MESSAGE_KEY";
40 |
41 | private static final int CMD_VALUE_START = 1;
42 | private static final int CMD_VALUE_ERROR = 2;
43 | private static final int CMD_VALUE_STOP = 4;
44 |
45 | /**
46 | * Notify serverStart.
47 | *
48 | * @param context context.
49 | */
50 | public static void onServerStart(Context context, String hostAddress) {
51 | sendBroadcast(context, CMD_VALUE_START, hostAddress);
52 | }
53 |
54 | /**
55 | * Notify serverStop.
56 | *
57 | * @param context context.
58 | */
59 | public static void onServerError(Context context, String error) {
60 | sendBroadcast(context, CMD_VALUE_ERROR, error);
61 | }
62 |
63 | /**
64 | * Notify serverStop.
65 | *
66 | * @param context context.
67 | */
68 | public static void onServerStop(Context context) {
69 | sendBroadcast(context, CMD_VALUE_STOP);
70 | }
71 |
72 | private static void sendBroadcast(Context context, int cmd) {
73 | sendBroadcast(context, cmd, null);
74 | }
75 |
76 | private static void sendBroadcast(Context context, int cmd, String message) {
77 | Intent broadcast = new Intent(ACTION);
78 | broadcast.putExtra(CMD_KEY, cmd);
79 | broadcast.putExtra(MESSAGE_KEY, message);
80 | context.sendBroadcast(broadcast);
81 | }
82 |
83 | private GoogleCameraActivity mActivity;
84 | private Intent mService;
85 |
86 | public ServerManager(GoogleCameraActivity activity) {
87 | this.mActivity = activity;
88 | mService = new Intent(activity, CoreService.class);
89 | }
90 |
91 | /**
92 | * Register broadcast.
93 | */
94 | public void register() {
95 | IntentFilter filter = new IntentFilter(ACTION);
96 | mActivity.registerReceiver(this, filter);
97 | }
98 |
99 | /**
100 | * UnRegister broadcast.
101 | */
102 | public void unRegister() {
103 | mActivity.unregisterReceiver(this);
104 | }
105 |
106 | public void startServer() {
107 | mActivity.startService(mService);
108 | }
109 |
110 | public void stopServer() {
111 | mActivity.stopService(mService);
112 | }
113 |
114 | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
115 | @Override
116 | public void onReceive(Context context, Intent intent) {
117 | String action = intent.getAction();
118 | if (ACTION.equals(action)) {
119 | int cmd = intent.getIntExtra(CMD_KEY, 0);
120 | switch (cmd) {
121 | case CMD_VALUE_START: {
122 | String ip = intent.getStringExtra(MESSAGE_KEY);
123 | mActivity.onServerStart(ip);
124 | break;
125 | }
126 | case CMD_VALUE_ERROR: {
127 | String error = intent.getStringExtra(MESSAGE_KEY);
128 | mActivity.onServerError(error);
129 | break;
130 | }
131 | case CMD_VALUE_STOP: {
132 | mActivity.onServerStop();
133 | break;
134 | }
135 | default:
136 | break;
137 | }
138 | }
139 | }
140 | }
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/server/TestController.java:
--------------------------------------------------------------------------------
1 | package camera.cn.cameramaster.server;
2 |
3 | import android.os.Build;
4 | import android.support.annotation.RequiresApi;
5 | import android.util.Log;
6 |
7 | import com.alibaba.fastjson.JSON;
8 | import com.yanzhenjie.andserver.annotation.Addition;
9 | import com.yanzhenjie.andserver.annotation.CookieValue;
10 | import com.yanzhenjie.andserver.annotation.FormPart;
11 | import com.yanzhenjie.andserver.annotation.GetMapping;
12 | import com.yanzhenjie.andserver.annotation.PathVariable;
13 | import com.yanzhenjie.andserver.annotation.PostMapping;
14 | import com.yanzhenjie.andserver.annotation.RequestBody;
15 | import com.yanzhenjie.andserver.annotation.RequestMapping;
16 | import com.yanzhenjie.andserver.annotation.RequestParam;
17 | import com.yanzhenjie.andserver.annotation.ResponseBody;
18 | import com.yanzhenjie.andserver.annotation.RestController;
19 | import com.yanzhenjie.andserver.http.HttpRequest;
20 | import com.yanzhenjie.andserver.http.HttpResponse;
21 | import com.yanzhenjie.andserver.http.cookie.Cookie;
22 | import com.yanzhenjie.andserver.http.multipart.MultipartFile;
23 | import com.yanzhenjie.andserver.http.session.Session;
24 | import com.yanzhenjie.andserver.util.MediaType;
25 |
26 | import org.greenrobot.eventbus.EventBus;
27 |
28 | import java.io.File;
29 | import java.io.IOException;
30 | import java.util.List;
31 |
32 | import camera.cn.cameramaster.server.model.UserInfo;
33 | import camera.cn.cameramaster.server.util.FileUtils;
34 |
35 |
36 | /**
37 | * 测试控制器
38 | *
39 | * @packageName: ymc.cn.servertest
40 | * @fileName: TestController
41 | * @date: 2019/4/23 16:15
42 | * @author: ymc
43 | * @QQ:745612618
44 | */
45 |
46 | @RestController
47 | @RequestMapping(path = "/test")
48 | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
49 | public class TestController {
50 |
51 | private static final String TAG = "TestController";
52 |
53 | private static final String LOGIN_ATTRIBUTE = "USER.LOGIN.SIGN";
54 |
55 | @ResponseBody
56 | @GetMapping("/take")
57 | public void takeCamera() {
58 | EventBus.getDefault().post(new AnyEventType());
59 | }
60 |
61 | @GetMapping(path = "/get/{userId}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
62 | String info(@PathVariable(name = "userId") String userId) {
63 | return userId;
64 | }
65 |
66 | @PostMapping(path = "/login", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
67 | String login(HttpRequest request, HttpResponse response, @RequestParam(name = "account",required = false
68 | ) String account, @RequestParam(name = "password",required = false) String password) {
69 | Session session = request.getValidSession();
70 | session.setAttribute(LOGIN_ATTRIBUTE, true);
71 |
72 | Cookie cookie = new Cookie("account", account + "=" + password);
73 | response.addCookie(cookie);
74 | return "login successful";
75 | }
76 |
77 | @Addition(stringType = "login", booleanType = true)
78 | @GetMapping(path = "/userInfo", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
79 | UserInfo userInfo(@CookieValue("account") String account) {
80 | Log.e(TAG, "Account: " + account);
81 | UserInfo userInfo = new UserInfo();
82 | userInfo.setmUserId("123");
83 | userInfo.setmUserName("AndServer");
84 | return userInfo;
85 | }
86 |
87 | @PostMapping(path = "/upload", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
88 | String upload(@RequestParam(name = "header") MultipartFile file) throws IOException {
89 | File localFile = FileUtils.createRandomFile(file);
90 | file.transferTo(localFile);
91 | return localFile.getAbsolutePath();
92 | }
93 |
94 | @GetMapping(path = "/consume", consumes = {"application/json", "!application/xml"})
95 | String consume() {
96 | return "Consume is successful";
97 | }
98 |
99 | @GetMapping(path = "/produce", produces = {"application/json; charset=utf-8"})
100 | String produce() {
101 | return "Produce is successful";
102 | }
103 |
104 | @GetMapping(path = "/include", params = {"name=123"})
105 | String include(@RequestParam(name = "name") String name) {
106 | return name;
107 | }
108 |
109 | @GetMapping(path = "/exclude", params = "name!=123")
110 | String exclude() {
111 | return "Exclude is successful.";
112 | }
113 |
114 | @GetMapping(path = {"/mustKey", "/getName"}, params = "name")
115 | String getMustKey(@RequestParam(name = "name") String name) {
116 | return name;
117 | }
118 |
119 | @PostMapping(path = {"/mustKey", "/postName"}, params = "name")
120 | String postMustKey(@RequestParam(name = "name") String name) {
121 | return name;
122 | }
123 |
124 | @GetMapping(path = "/noName", params = "!name")
125 | String noName() {
126 | return "NoName is successful.";
127 | }
128 |
129 | @PostMapping(path = "/formPart")
130 | String forPart(@FormPart(name = "user") UserInfo userInfo) {
131 | return JSON.toJSONString(userInfo);
132 | }
133 |
134 | @PostMapping(path = "/jsonBody")
135 | String jsonBody(@RequestBody UserInfo userInfo) {
136 | return JSON.toJSONString(userInfo);
137 | }
138 |
139 | @PostMapping(path = "/listBody")
140 | String jsonBody(@RequestBody List infoList) {
141 | return JSON.toJSONString(infoList);
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/server/component/LoggerInterceptor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Yan Zhenjie.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package camera.cn.cameramaster.server.component;
17 |
18 | import android.support.annotation.NonNull;
19 | import android.util.Log;
20 |
21 | import com.alibaba.fastjson.JSON;
22 | import com.yanzhenjie.andserver.annotation.Interceptor;
23 | import com.yanzhenjie.andserver.framework.HandlerInterceptor;
24 | import com.yanzhenjie.andserver.framework.handler.RequestHandler;
25 | import com.yanzhenjie.andserver.http.HttpMethod;
26 | import com.yanzhenjie.andserver.http.HttpRequest;
27 | import com.yanzhenjie.andserver.http.HttpResponse;
28 | import com.yanzhenjie.andserver.util.MultiValueMap;
29 |
30 | /**
31 | * 拦截器
32 | *
33 | * @author ymc
34 | */
35 |
36 | @Interceptor
37 | public class LoggerInterceptor implements HandlerInterceptor {
38 |
39 | private static final String TAG = "LoggerInterceptor";
40 |
41 | @Override
42 | public boolean onIntercept(@NonNull HttpRequest request, @NonNull HttpResponse response,
43 | @NonNull RequestHandler handler) {
44 | String path = request.getPath();
45 | HttpMethod method = request.getMethod();
46 | MultiValueMap valueMap = request.getParameter();
47 | Log.e(TAG, "Path: " + path);
48 | Log.e(TAG, "Method: " + method.value());
49 | Log.e(TAG, "Param: " + JSON.toJSONString(valueMap));
50 | return false;
51 | }
52 | }
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/server/model/UserInfo.java:
--------------------------------------------------------------------------------
1 | package camera.cn.cameramaster.server.model;
2 |
3 | import android.os.Parcel;
4 | import android.os.Parcelable;
5 |
6 | import com.alibaba.fastjson.annotation.JSONField;
7 |
8 | /**
9 | * 用户
10 | *
11 | * @packageName: ymc.cn.servertest.model
12 | * @fileName: UserInfo
13 | * @date: 2019/4/23 17:31
14 | * @author: ymc
15 | * @QQ:745612618
16 | */
17 |
18 | public class UserInfo implements Parcelable {
19 |
20 | @JSONField(name = "userId")
21 | private String mUserId;
22 | @JSONField(name = "userName")
23 | private String mUserName;
24 |
25 | public static final Creator CREATOR = new Creator() {
26 | @Override
27 | public UserInfo createFromParcel(Parcel in) {
28 | return new UserInfo(in);
29 | }
30 |
31 | @Override
32 | public UserInfo[] newArray(int size) {
33 | return new UserInfo[size];
34 | }
35 | };
36 |
37 | @Override
38 | public int describeContents() {
39 | return 0;
40 | }
41 |
42 | @Override
43 | public void writeToParcel(Parcel dest, int flags) {
44 | dest.writeString(mUserId);
45 | dest.writeString(mUserName);
46 | }
47 |
48 | public UserInfo() {
49 | }
50 |
51 | protected UserInfo(Parcel in) {
52 | mUserId = in.readString();
53 | mUserName = in.readString();
54 | }
55 |
56 | public String getmUserId() {
57 | return mUserId;
58 | }
59 |
60 | public void setmUserId(String mUserId) {
61 | this.mUserId = mUserId;
62 | }
63 |
64 | public String getmUserName() {
65 | return mUserName;
66 | }
67 |
68 | public void setmUserName(String mUserName) {
69 | this.mUserName = mUserName;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/server/util/FileUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Yan Zhenjie.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package camera.cn.cameramaster.server.util;
17 |
18 | import android.os.Environment;
19 | import android.webkit.MimeTypeMap;
20 |
21 | import com.yanzhenjie.andserver.http.multipart.MultipartFile;
22 | import com.yanzhenjie.andserver.util.StringUtils;
23 |
24 | import java.io.File;
25 | import java.util.UUID;
26 |
27 | import camera.cn.cameramaster.base.App;
28 |
29 |
30 | /**
31 | * Created by YanZhenjie on 2018/6/9.
32 | */
33 | public class FileUtils {
34 |
35 | /**
36 | * Create a random file based on mimeType.
37 | *
38 | * @param file file.
39 | *
40 | * @return file object.
41 | */
42 | public static File createRandomFile(MultipartFile file) {
43 | String extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(file.getContentType().toString());
44 | if (StringUtils.isEmpty(extension)) {
45 | extension = MimeTypeMap.getFileExtensionFromUrl(file.getFilename());
46 | }
47 | String uuid = UUID.randomUUID().toString();
48 | return new File(App.getInstance().getRootDir(), uuid + "." + extension);
49 | }
50 |
51 | /**
52 | * SD is available.
53 | *
54 | * @return true, otherwise is false.
55 | */
56 | public static boolean storageAvailable() {
57 | if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
58 | File sd = new File(Environment.getExternalStorageDirectory().getAbsolutePath());
59 | return sd.canWrite();
60 | } else {
61 | return false;
62 | }
63 | }
64 | }
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/server/util/NetUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright © 2018 Yan Zhenjie.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package camera.cn.cameramaster.server.util;
17 |
18 | import java.net.InetAddress;
19 | import java.net.NetworkInterface;
20 | import java.net.SocketException;
21 | import java.util.Enumeration;
22 | import java.util.regex.Pattern;
23 |
24 | /**
25 | * Created by YanZhenjie on 2018/6/9.
26 | */
27 | public class NetUtils {
28 |
29 | /**
30 | * Ipv4 address check.
31 | */
32 | private static final Pattern IPV4_PATTERN = Pattern.compile(
33 | "^(" + "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}" +
34 | "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$");
35 |
36 | /**
37 | * Check if valid IPV4 address.
38 | *
39 | * @param input the address string to check for validity.
40 | *
41 | * @return True if the input parameter is a valid IPv4 address.
42 | */
43 | public static boolean isIPv4Address(String input) {
44 | return IPV4_PATTERN.matcher(input).matches();
45 | }
46 |
47 | /**
48 | * Get local Ip address.
49 | */
50 | public static InetAddress getLocalIPAddress() {
51 | Enumeration enumeration = null;
52 | try {
53 | enumeration = NetworkInterface.getNetworkInterfaces();
54 | } catch (SocketException e) {
55 | e.printStackTrace();
56 | }
57 | if (enumeration != null) {
58 | while (enumeration.hasMoreElements()) {
59 | NetworkInterface nif = enumeration.nextElement();
60 | Enumeration inetAddresses = nif.getInetAddresses();
61 | if (inetAddresses != null) {
62 | while (inetAddresses.hasMoreElements()) {
63 | InetAddress inetAddress = inetAddresses.nextElement();
64 | if (!inetAddress.isLoopbackAddress() && isIPv4Address(inetAddress.getHostAddress())) {
65 | return inetAddress;
66 | }
67 | }
68 | }
69 | }
70 | }
71 | return null;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/ui/CameraSurfaceViewActivity.java:
--------------------------------------------------------------------------------
1 | package camera.cn.cameramaster.ui;
2 |
3 | import android.os.Build;
4 | import android.support.annotation.RequiresApi;
5 | import android.support.constraint.ConstraintLayout;
6 | import android.util.DisplayMetrics;
7 | import android.util.Log;
8 | import android.util.Size;
9 | import android.view.View;
10 | import android.widget.FrameLayout;
11 | import android.widget.LinearLayout;
12 |
13 | import butterknife.BindView;
14 | import butterknife.OnClick;
15 | import camera.cn.cameramaster.R;
16 | import camera.cn.cameramaster.base.BaseActivity;
17 | import camera.cn.cameramaster.util.CameraV2;
18 | import camera.cn.cameramaster.view.CameraV2GLSurfaceView;
19 |
20 | /**
21 | * 基于 camera2 surfaceview 过滤界面
22 | * 参考url : [https://blog.csdn.net/lb377463323/article/details/78054892]
23 | *
24 | * @author ymc
25 | * @date 2019年2月12日 14:32:37
26 | */
27 |
28 | public class CameraSurfaceViewActivity extends BaseActivity {
29 | private static final String TAG = "CameraSVActivity";
30 | @BindView(R.id.frame_layout)
31 | FrameLayout frameLayout;
32 | private CameraV2 mCamera;
33 | private CameraV2GLSurfaceView mCameraV2GLSurfaceView;
34 |
35 | @Override
36 | protected int getLayoutId() {
37 | return R.layout.activity_camera_sv;
38 | }
39 |
40 | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
41 | @Override
42 | protected void initView() {
43 | mCameraV2GLSurfaceView = new CameraV2GLSurfaceView(this);
44 | DisplayMetrics dm = new DisplayMetrics();
45 | getWindowManager().getDefaultDisplay().getMetrics(dm);
46 | mCamera = new CameraV2(this);
47 | Size size = mCamera.setUpCameraOutputs(dm.widthPixels, dm.heightPixels);
48 | if (!mCamera.openCamera()) {
49 | Log.e(TAG, "mCamera openCamera err");
50 | return;
51 | }
52 | mCameraV2GLSurfaceView.init(mCamera, false,
53 | CameraSurfaceViewActivity.this);
54 | // 将 surfaceview 添加到布局中
55 | ConstraintLayout.LayoutParams lp = new ConstraintLayout.LayoutParams(
56 | LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
57 | lp.width = size.getHeight();
58 | lp.height = size.getWidth();
59 | mCameraV2GLSurfaceView.setLayoutParams(lp);
60 | frameLayout.addView(mCameraV2GLSurfaceView);
61 | }
62 |
63 | @Override
64 | protected void initData() {
65 |
66 | }
67 |
68 | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
69 | @OnClick({R.id.iv_back, R.id.img_camera})
70 | public void onClick(View view) {
71 | switch (view.getId()) {
72 | case R.id.iv_back:
73 | finish();
74 | break;
75 | case R.id.img_camera:
76 | mCamera.lockFocus();
77 | break;
78 | default:
79 | break;
80 | }
81 | }
82 |
83 | // TODO: 2019/4/3 会退到当前界面如何重新启动相机
84 | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
85 | @Override
86 | protected void onResume() {
87 | super.onResume();
88 | mCamera.startBackgroundThread();
89 | // 存在关联则打开相机,没有则绑定事件
90 | // mCamera.openCamera();
91 | }
92 |
93 | @Override
94 | protected void onPause() {
95 | mCamera.closeCamera();
96 | mCamera.stopBackgroundThread();
97 | super.onPause();
98 | }
99 |
100 | @Override
101 | protected void onDestroy() {
102 | super.onDestroy();
103 | }
104 |
105 | }
106 |
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/ui/MainActivity.java:
--------------------------------------------------------------------------------
1 | package camera.cn.cameramaster.ui;
2 |
3 | import android.Manifest;
4 | import android.annotation.SuppressLint;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.net.ConnectivityManager;
8 | import android.os.Build;
9 | import android.support.annotation.RequiresApi;
10 | import android.util.Log;
11 | import android.view.View;
12 | import android.widget.Button;
13 | import android.widget.TextView;
14 |
15 | import com.yanzhenjie.permission.Action;
16 | import com.yanzhenjie.permission.AndPermission;
17 | import com.yanzhenjie.permission.Rationale;
18 | import com.yanzhenjie.permission.RequestExecutor;
19 |
20 | import java.io.File;
21 | import java.lang.reflect.Method;
22 | import java.util.List;
23 |
24 | import butterknife.BindView;
25 | import butterknife.OnClick;
26 | import camera.cn.cameramaster.R;
27 | import camera.cn.cameramaster.base.BaseActivity;
28 | import camera.cn.cameramaster.util.AppConstant;
29 |
30 | /**
31 | * 首页
32 | *
33 | * @author ymc
34 | */
35 |
36 | public class MainActivity extends BaseActivity {
37 | private final static String TAG = "MainActivity";
38 | @BindView(R.id.btn_camera)
39 | public Button btn;
40 | @BindView(R.id.tv_message)
41 | TextView tvMsg;
42 |
43 | private File mD65File;
44 | private File mFile;
45 |
46 | @Override
47 | protected int getLayoutId() {
48 | return R.layout.activity_main;
49 | }
50 |
51 | @Override
52 | protected void initView() {
53 | mD65File = new File(getExternalFilesDir(""), "picD65.jpg");
54 | mFile = new File(getExternalFilesDir(null), "pic.jpg");
55 | }
56 |
57 | @Override
58 | protected void initData() {
59 | requestPermission();
60 | // 设置关闭 移动网络
61 | setDataConnectionState(this,false);
62 | }
63 |
64 |
65 | @SuppressLint("WrongConstant")
66 | public static void setDataConnectionState(Context cxt, boolean state) {
67 | ConnectivityManager connectivityManager = null;
68 | Class connectivityManagerClz = null;
69 | try {
70 | connectivityManager = (ConnectivityManager) cxt
71 | .getSystemService("connectivity");
72 | connectivityManagerClz = connectivityManager.getClass();
73 | Method method = connectivityManagerClz.getMethod(
74 | "setMobileDataEnabled", new Class[] { boolean.class });
75 | method.invoke(connectivityManager, state);
76 | } catch (Exception e) {
77 | e.printStackTrace();
78 | }
79 | }
80 |
81 | @OnClick({R.id.btn_camera, R.id.btn_camera2, R.id.btn_filter_camera2, R.id.btn_camera2_video})
82 | public void onClick(View view) {
83 | switch (view.getId()) {
84 | case R.id.btn_camera:
85 | Intent intent = new Intent(this, CameraActivity.class);
86 | startActivityForResult(intent, 0);
87 | break;
88 | case R.id.btn_camera2:
89 | Intent intent2 = new Intent(this, GoogleCameraActivity.class);
90 | startActivityForResult(intent2, 1);
91 | break;
92 | case R.id.btn_filter_camera2:
93 | Intent intentFilter2 = new Intent(this, CameraSurfaceViewActivity.class);
94 | startActivityForResult(intentFilter2, 0);
95 | break;
96 | case R.id.btn_camera2_video:
97 | Intent intentVideo = new Intent(this, CameraVideoActivity.class);
98 | startActivity(intentVideo);
99 | break;
100 | default:
101 | break;
102 | }
103 | }
104 |
105 |
106 | @Override
107 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
108 | super.onActivityResult(requestCode, resultCode, data);
109 | if (resultCode != AppConstant.RESULT_CODE.RESULT_OK) {
110 | return;
111 | }
112 | if (requestCode == 0) {
113 | String imgPath = data.getStringExtra(AppConstant.KEY.IMG_PATH);
114 | int picWidth = data.getIntExtra(AppConstant.KEY.PIC_WIDTH, 0);
115 | int picHeight = data.getIntExtra(AppConstant.KEY.PIC_HEIGHT, 0);
116 | Intent intent = new Intent(activity, ShowPicActivity.class);
117 | intent.putExtra(AppConstant.KEY.PIC_WIDTH, picWidth);
118 | intent.putExtra(AppConstant.KEY.PIC_HEIGHT, picHeight);
119 | intent.putExtra(AppConstant.KEY.IMG_PATH, imgPath);
120 | startActivity(intent);
121 | } else if (requestCode == 1) {
122 | // tvMsg.setText("图片 D65 光源处理中 请勿退出....");
123 | // new Thread(new Runnable() {
124 | // @Override
125 | // public void run() {
126 | // final long starttime = System.currentTimeMillis();
127 | // FileInputStream fis = null;
128 | // FileOutputStream output = null;
129 | // try {
130 | // fis = new FileInputStream(mFile);
131 | // Bitmap bitmap = BitmapFactory.decodeStream(fis);
132 | // Bitmap d65bitmap = BitmapUtils.ImgaeToNegative(bitmap);
133 | // output = new FileOutputStream(mD65File);
134 | // d65bitmap.compress(Bitmap.CompressFormat.JPEG, 100, output);
135 | // runOnUiThread(new Runnable() {
136 | // @Override
137 | // public void run() {
138 | // tvMsg.setText("处理完毕.耗时:"+ (System.currentTimeMillis() - starttime)+ " ms");
139 | // }
140 | // });
141 | // } catch (FileNotFoundException e) {
142 | // e.printStackTrace();
143 | // }
144 | // }
145 | // }).start();
146 | }
147 | }
148 |
149 | /**
150 | * 动态申请 (电话/位置/存储)
151 | */
152 | @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
153 | private void requestPermission() {
154 | AndPermission.with(this)
155 | .permission(Manifest.permission.CAMERA,
156 | Manifest.permission.READ_EXTERNAL_STORAGE,
157 | Manifest.permission.RECORD_AUDIO)
158 | .rationale(new Rationale() {
159 | @Override
160 | public void showRationale(Context context, List permissions, RequestExecutor executor) {
161 | executor.execute();
162 | }
163 | })
164 | .onGranted(new Action() {
165 | @Override
166 | public void onAction(List permissions) {
167 | Log.e(TAG, "用户给权限");
168 | }
169 | })
170 | .onDenied(new Action() {
171 | @Override
172 | public void onAction(List permissions) {
173 | if (AndPermission.hasAlwaysDeniedPermission(MainActivity.this, permissions)) {
174 | // 打开权限设置页
175 | AndPermission.permissionSetting(MainActivity.this).execute();
176 | return;
177 | }
178 | Log.e(TAG, "用户拒绝权限");
179 | }
180 | })
181 | .start();
182 | }
183 | }
184 |
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/util/AppConstant.java:
--------------------------------------------------------------------------------
1 | package camera.cn.cameramaster.util;
2 |
3 | /**
4 | * 应用 常量类
5 | *
6 | * @packageName: cn.ymc.suncamera.util
7 | * @fileName: AppConstant
8 | * @date: 2019/1/24 16:54
9 | * @author: ymc
10 | * @QQ:745612618
11 | */
12 |
13 | public class AppConstant {
14 |
15 | /**
16 | * 摄像头模式
17 | */
18 | public final static int CAMERA_MODE = 0;
19 | /**
20 | * 视频播放器模式
21 | */
22 | public final static int VIDEO_MODE = 1;
23 |
24 | /**
25 | * 视频最长的时长是10s
26 | */
27 | public final static int VIDEO_MAX_TIME = 10;
28 |
29 | /**
30 | * 视频播放模式
31 | */
32 | public final static int VIDEO_PLAY_MODE = 0;
33 |
34 | /**
35 | * 视频录像模式
36 | */
37 | public final static int VIDEO_RECORD_MODE = 1;
38 |
39 | /**
40 | * 拍照模式
41 | */
42 | public final static int VIDEO_TAKE_PHOTO = 2;
43 |
44 | /**
45 | * 当前面板是预览状态
46 | */
47 | public final static int TEXTURE_PREVIEW_STATE = 0;
48 |
49 | /**
50 | * 当前面板是录像状态
51 | */
52 | public final static int TEXTURE_RECORD_STATE = 1;
53 |
54 | /**
55 | * 当前面板是图片状态
56 | */
57 | public final static int TEXTURE_PHOTO_STATE = 2;
58 |
59 | /**
60 | * 当前面板是视频播放状态
61 | */
62 |
63 | public final static int TEXTURE_PLAY_STATE = 3;
64 |
65 | /**
66 | * 当前是摄像头模式还是视频播放模式
67 | */
68 | public int MODE;
69 |
70 | /**
71 | * 当前的模式,默认为拍照模式
72 | */
73 | public int NOW_MODE = VIDEO_TAKE_PHOTO;
74 |
75 |
76 | /**
77 | * 感觉数组
78 | */
79 | public static String[] senseArr = {"DISABLED", "FACE_PRIORITY", "ACTION", "PORTRAIT", "LANDSCAPE", "NIGHT"
80 | , "NIGHT_PORTRAIT", "THEATRE", "BEACH", "SNOW", "SUNSET", "STEADYPHOTO", "FIREWORKS",
81 | "SPORTS", "PARTY", "CANDLELIGHT", "BARCODE"};
82 |
83 | public static String[] effectArr = {"aqua", "blackboard", "monoColor", "negative", "posterization", "sepia"
84 | , "solarisation", "whiteboard", "off"};
85 |
86 | public interface KEY{
87 | String IMG_PATH = "IMG_PATH";
88 | String VIDEO_PATH = "VIDEO_PATH";
89 | String PIC_WIDTH = "PIC_WIDTH";
90 | String PIC_HEIGHT = "PIC_HEIGHT";
91 | }
92 |
93 | public interface RESULT_CODE {
94 | int RESULT_OK = -1;
95 | int RESULT_CANCELED = 0;
96 | int RESULT_ERROR = 1;
97 | }
98 |
99 | /**
100 | * 底部状态 : 曝光
101 | */
102 | public static final int SHOW_AE = 1;
103 | /**
104 | * 白平衡
105 | */
106 | public static final int SHOW_AWB = 2;
107 | /**
108 | * 感光度
109 | */
110 | public static final int SHOW_ISO = 3;
111 | /**
112 | * 放大 倍数
113 | */
114 | public static final int SHOW_ZOOM = 4;
115 | /**
116 | * effect
117 | */
118 | public static final int SHOW_EFFECT = 5;
119 | /**
120 | * sense
121 | */
122 | public static final int SHOW_SENSE = 6;
123 |
124 | /**
125 | * 手动设置
126 | */
127 | public static final int SHOW_SETTING = 6;
128 |
129 |
130 | /**
131 | * lab rgb 数组
132 | */
133 | public static double[][] labmap = {{37.986,13.555,14.059},{65.711,18.13,17.81},{49.927,-4.88,-21.925},
134 | {43.139,-13.095,21.905} ,{55.112,8.844,-25.399},{70.719,-33.397,-0.199},
135 | {62.661,36.067,57.096},{40.02,10.41,-45.964},{51.124,48.239,16.248},
136 | {30.325,22.976,-21.587},{72.532,-23.709,57.255},{71.941,19.363,67.857},
137 | {28.778,14.179,-50.297},{55.261,-38.342,31.37},{42.101,53.378,28.19},
138 | {81.733,4.039,79.819} ,{51.935,49.986,-14.574},{51.038,-28.631,-28.638},
139 | {96.539,-0.425,1.186},{81.257,-0.638,-0.335},{66.766,-0.734,-0.504},
140 | {50.867,-0.153,-0.27} ,{35.656,-0.421,-1.231},{20.461,-0.079,-0.973}};
141 |
142 | public static double [][] rgbmap = {{115,82,68},{194,150,130},{98,122,157},{87,108,67},
143 | {133,128,177},{103,189,170},{214,126,44},{80,91,166},{193,90,99},{94,60,108},
144 | {157,188,64},{224,163,46},{56,61,150},{70,148,73},{175,54,60},{231,199,31},
145 | {187,86,149},{8,133,161},{243,243,242},{200,200,200},{160,160,160},
146 | {122,122,121},{85,85,85},{52,52,52}};
147 |
148 | }
149 |
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/util/Camera2Util.java:
--------------------------------------------------------------------------------
1 | package camera.cn.cameramaster.util;
2 |
3 | import android.graphics.ImageFormat;
4 | import android.media.Image;
5 | import android.os.Build;
6 | import android.support.annotation.RequiresApi;
7 | import android.util.Log;
8 |
9 | import java.nio.ByteBuffer;
10 |
11 | /**
12 | * camera2 中 yuv 420 格式图片 转为 rgb 图片
13 | *
14 | * @packageName: cn.tongue.tonguecamera.util
15 | * @fileName: Camera2Util
16 | * @date: 2019/3/13 13:37
17 | * @author: ymc
18 | * @QQ:745612618
19 | */
20 |
21 | public class Camera2Util {
22 |
23 | public static final int YUV420P = 0;
24 | public static final int YUV420SP = 1;
25 | public static final int NV21 = 2;
26 | private static final String TAG = "Camera2Util";
27 |
28 | /***
29 | * 此方法内注释以640*480为例
30 | * 未考虑CropRect的
31 | */
32 | @RequiresApi(api = Build.VERSION_CODES.KITKAT)
33 | public static byte[] getBytesFromImageAsType(Image image, int type) {
34 | try {
35 | //获取源数据,如果是YUV格式的数据planes.length = 3
36 | //plane[i]里面的实际数据可能存在byte[].length <= capacity (缓冲区总大小)
37 | final Image.Plane[] planes = image.getPlanes();
38 | //数据有效宽度,一般的,图片width <= rowStride,这也是导致byte[].length <= capacity的原因
39 | // 所以我们只取width部分
40 | int width = image.getWidth();
41 | int height = image.getHeight();
42 |
43 | //此处用来装填最终的YUV数据,需要1.5倍的图片大小,因为Y U V 比例为 4:1:1
44 | byte[] yuvBytes = new byte[width * height * ImageFormat.getBitsPerPixel(ImageFormat.YUV_420_888) / 8];
45 | //目标数组的装填到的位置
46 | int dstIndex = 0;
47 |
48 | //临时存储uv数据的
49 | byte uBytes[] = new byte[width * height / 4];
50 | byte vBytes[] = new byte[width * height / 4];
51 | int uIndex = 0;
52 | int vIndex = 0;
53 |
54 | int pixelsStride, rowStride;
55 | for (int i = 0; i < planes.length; i++) {
56 | pixelsStride = planes[i].getPixelStride();
57 | rowStride = planes[i].getRowStride();
58 |
59 | ByteBuffer buffer = planes[i].getBuffer();
60 |
61 | //如果pixelsStride==2,一般的Y的buffer长度=640*480,UV的长度=640*480/2-1
62 | //源数据的索引,y的数据是byte中连续的,u的数据是v向左移以为生成的,两者都是偶数位为有效数据
63 | byte[] bytes = new byte[buffer.capacity()];
64 | buffer.get(bytes);
65 |
66 | int srcIndex = 0;
67 | if (i == 0) {
68 | //直接取出来所有Y的有效区域,也可以存储成一个临时的bytes,到下一步再copy
69 | for (int j = 0; j < height; j++) {
70 | System.arraycopy(bytes, srcIndex, yuvBytes, dstIndex, width);
71 | srcIndex += rowStride;
72 | dstIndex += width;
73 | }
74 | } else if (i == 1) {
75 | //根据pixelsStride取相应的数据
76 | for (int j = 0; j < height / 2; j++) {
77 | for (int k = 0; k < width / 2; k++) {
78 | uBytes[uIndex++] = bytes[srcIndex];
79 | srcIndex += pixelsStride;
80 | }
81 | if (pixelsStride == 2) {
82 | srcIndex += rowStride - width;
83 | } else if (pixelsStride == 1) {
84 | srcIndex += rowStride - width / 2;
85 | }
86 | }
87 | } else if (i == 2) {
88 | //根据pixelsStride取相应的数据
89 | for (int j = 0; j < height / 2; j++) {
90 | for (int k = 0; k < width / 2; k++) {
91 | vBytes[vIndex++] = bytes[srcIndex];
92 | srcIndex += pixelsStride;
93 | }
94 | if (pixelsStride == 2) {
95 | srcIndex += rowStride - width;
96 | } else if (pixelsStride == 1) {
97 | srcIndex += rowStride - width / 2;
98 | }
99 | }
100 | }
101 | }
102 | // image.close();
103 | //根据要求的结果类型进行填充
104 | switch (type) {
105 | case YUV420P:
106 | System.arraycopy(uBytes, 0, yuvBytes, dstIndex, uBytes.length);
107 | System.arraycopy(vBytes, 0, yuvBytes, dstIndex + uBytes.length, vBytes.length);
108 | break;
109 | case YUV420SP:
110 | for (int i = 0; i < vBytes.length; i++) {
111 | yuvBytes[dstIndex++] = uBytes[i];
112 | yuvBytes[dstIndex++] = vBytes[i];
113 | }
114 | break;
115 | case NV21:
116 | for (int i = 0; i < vBytes.length; i++) {
117 | yuvBytes[dstIndex++] = vBytes[i];
118 | yuvBytes[dstIndex++] = uBytes[i];
119 | }
120 | break;
121 | }
122 | return yuvBytes;
123 | } catch (final Exception e) {
124 | if (image != null) {
125 | image.close();
126 | }
127 | Log.i(TAG, e.toString());
128 | }
129 | return null;
130 | }
131 |
132 | /***
133 | * YUV420 转化成 RGB
134 | */
135 | public static int[] decodeYUV420SP(byte[] yuv420sp, int width, int height) {
136 | final int frameSize = width * height;
137 | int rgb[] = new int[frameSize];
138 | for (int j = 0, yp = 0; j < height; j++) {
139 | int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;
140 | for (int i = 0; i < width; i++, yp++) {
141 | int y = (0xff & ((int) yuv420sp[yp])) - 16;
142 | if (y < 0) {
143 | y = 0;
144 | }
145 | if ((i & 1) == 0) {
146 | v = (0xff & yuv420sp[uvp++]) - 128;
147 | u = (0xff & yuv420sp[uvp++]) - 128;
148 | }
149 | int y1192 = 1192 * y;
150 | int r = (y1192 + 1634 * v);
151 | int g = (y1192 - 833 * v - 400 * u);
152 | int b = (y1192 + 2066 * u);
153 | if (r < 0) {
154 | r = 0;
155 | } else if (r > 262143) {
156 | r = 262143;
157 | }
158 | if (g < 0) {
159 | g = 0;
160 | } else if (g > 262143) {
161 | g = 262143;
162 | }
163 | if (b < 0) {
164 | b = 0;
165 | } else if (b > 262143) {
166 | b = 262143;
167 | }
168 | rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000)
169 | | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);
170 | }
171 | }
172 | return rgb;
173 | }
174 |
175 | }
176 |
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/util/CompareSizesByArea.java:
--------------------------------------------------------------------------------
1 | package camera.cn.cameramaster.util;
2 |
3 | import android.os.Build;
4 | import android.support.annotation.RequiresApi;
5 | import android.util.Size;
6 |
7 | import java.util.Comparator;
8 |
9 | /**
10 | * 比较 工具
11 | *
12 | * @packageName: cn.tongue.tonguecamera.util
13 | * @fileName: CompareSizesByArea
14 | * @date: 2019/4/16 13:42
15 | * @author: ymc
16 | * @QQ:745612618
17 | */
18 |
19 | public class CompareSizesByArea implements Comparator {
20 |
21 | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
22 | @Override
23 | public int compare(Size lhs, Size rhs) {
24 | // 在这里投射以确保乘法不会溢出
25 | return Long.signum((long) lhs.getWidth() * lhs.getHeight() -
26 | (long) rhs.getWidth() * rhs.getHeight());
27 | }
28 | }
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/util/FilterEngine.java:
--------------------------------------------------------------------------------
1 | package camera.cn.cameramaster.util;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.content.Context;
5 | import android.opengl.GLES11Ext;
6 | import android.opengl.GLES20;
7 |
8 | import java.nio.ByteBuffer;
9 | import java.nio.ByteOrder;
10 | import java.nio.FloatBuffer;
11 |
12 |
13 | import camera.cn.cameramaster.R;
14 |
15 | import static android.opengl.GLES20.GL_FLOAT;
16 | import static android.opengl.GLES20.GL_FRAGMENT_SHADER;
17 | import static android.opengl.GLES20.GL_TRIANGLES;
18 | import static android.opengl.GLES20.GL_VERTEX_SHADER;
19 | import static android.opengl.GLES20.glActiveTexture;
20 | import static android.opengl.GLES20.glAttachShader;
21 | import static android.opengl.GLES20.glBindTexture;
22 | import static android.opengl.GLES20.glCompileShader;
23 | import static android.opengl.GLES20.glCreateProgram;
24 | import static android.opengl.GLES20.glCreateShader;
25 | import static android.opengl.GLES20.glDrawArrays;
26 | import static android.opengl.GLES20.glEnableVertexAttribArray;
27 | import static android.opengl.GLES20.glGetAttribLocation;
28 | import static android.opengl.GLES20.glGetError;
29 | import static android.opengl.GLES20.glGetUniformLocation;
30 | import static android.opengl.GLES20.glLinkProgram;
31 | import static android.opengl.GLES20.glShaderSource;
32 | import static android.opengl.GLES20.glUniform1i;
33 | import static android.opengl.GLES20.glUniformMatrix4fv;
34 | import static android.opengl.GLES20.glUseProgram;
35 | import static android.opengl.GLES20.glVertexAttribPointer;
36 |
37 | /**
38 | * 滤镜 工具
39 | * 参考url : [https://blog.csdn.net/lb377463323/article/details/78054892]
40 | *
41 | * @date 2019年2月12日 14:10:07
42 | * @author ymc
43 | */
44 |
45 | public class FilterEngine {
46 |
47 | @SuppressLint("StaticFieldLeak")
48 | private static FilterEngine filterEngine = null;
49 |
50 | private Context mContext;
51 | /**
52 | * 存放顶点的Color数组
53 | */
54 | private FloatBuffer mBuffer;
55 | private int mOESTextureId = -1;
56 | private int vertexShader = -1;
57 | private int fragmentShader = -1;
58 |
59 | private int mShaderProgram = -1;
60 |
61 | private int aPositionLocation = -1;
62 | private int aTextureCoordLocation = -1;
63 | private int uTextureMatrixLocation = -1;
64 | private int uTextureSamplerLocation = -1;
65 | /**
66 | * 每行前两个值为顶点坐标,后两个为纹理坐标
67 | */
68 | private static final float[] VERTEX_DATA = {
69 | 1f, 1f, 1f, 1f,
70 | -1f, 1f, 0f, 1f,
71 | -1f, -1f, 0f, 0f,
72 | 1f, 1f, 1f, 1f,
73 | -1f, -1f, 0f, 0f,
74 | 1f, -1f, 1f, 0f
75 | };
76 |
77 | public static final String POSITION_ATTRIBUTE = "aPosition";
78 | public static final String TEXTURE_COORD_ATTRIBUTE = "aTextureCoordinate";
79 | public static final String TEXTURE_MATRIX_UNIFORM = "uTextureMatrix";
80 | public static final String TEXTURE_SAMPLER_UNIFORM = "uTextureSampler";
81 | public static final String COLOR_TYPE = "vColorType";
82 |
83 | /**
84 | * 构造方法
85 | * @param oestextureid oes id
86 | * @param context 上下文
87 | */
88 | public FilterEngine(int oestextureid, Context context) {
89 | mContext = context;
90 | mOESTextureId = oestextureid;
91 | mBuffer = createBuffer(VERTEX_DATA);
92 | /**
93 | * 预览相机的着色器,顶点着色器不变,需要修改片元着色器,不再用sampler2D采样,
94 | * 需要使用samplerExternalOES 纹理采样器,并且要在头部增加使用扩展纹理的声明
95 | * #extension GL_OES_EGL_image_external : require。
96 | */
97 | fragmentShader = loadShader(GL_FRAGMENT_SHADER, Utils.readShaderFromResource(mContext, R.raw.base_fragment_shader));
98 | vertexShader = loadShader(GL_VERTEX_SHADER, Utils.readShaderFromResource(mContext, R.raw.base_vertex_shader));
99 | mShaderProgram = linkProgram(vertexShader, fragmentShader);
100 | }
101 |
102 | /**
103 | * 创建 FloatBuffer 数组 (防止内存回收)
104 | * @param vertexData float 数组
105 | * @return FloatBuffer
106 | */
107 | private FloatBuffer createBuffer(float[] vertexData) {
108 | FloatBuffer buffer = ByteBuffer.allocateDirect(vertexData.length * 4)
109 | .order(ByteOrder.nativeOrder())
110 | .asFloatBuffer();
111 | buffer.put(vertexData, 0, vertexData.length).position(0);
112 | return buffer;
113 | }
114 |
115 | /**
116 | * 加载着色器
117 | * GL_VERTEX_SHADER 代表生成顶点着色器
118 | * GL_FRAGMENT_SHADER 代表生成片段着色器
119 | *
120 | * @param type 类型
121 | * @param shaderSource shader string
122 | * @return shader
123 | */
124 | private int loadShader(int type, String shaderSource) {
125 | int shader = glCreateShader(type);
126 | if (shader == 0) {
127 | throw new RuntimeException("Create Shader Failed!" + glGetError());
128 | }
129 | glShaderSource(shader, shaderSource);
130 | glCompileShader(shader);
131 | return shader;
132 | }
133 |
134 | /**
135 | * 将两个Shader链接至program中
136 | * @param verShader verShader
137 | * @param fragShader fragShader
138 | * @return program
139 | */
140 | private int linkProgram(int verShader, int fragShader) {
141 | int program = glCreateProgram();
142 | if (program == 0) {
143 | throw new RuntimeException("Create Program Failed!" + glGetError());
144 | }
145 | //附着顶点和片段着色器
146 | glAttachShader(program, verShader);
147 | glAttachShader(program, fragShader);
148 | // 绑定 program
149 | glLinkProgram(program);
150 | //告诉OpenGL ES使用此program
151 | glUseProgram(program);
152 | return program;
153 | }
154 |
155 | public void drawTexture(float[] transformMatrix) {
156 | aPositionLocation = glGetAttribLocation(mShaderProgram, FilterEngine.POSITION_ATTRIBUTE);
157 | aTextureCoordLocation = glGetAttribLocation(mShaderProgram, FilterEngine.TEXTURE_COORD_ATTRIBUTE);
158 | uTextureMatrixLocation = glGetUniformLocation(mShaderProgram, FilterEngine.TEXTURE_MATRIX_UNIFORM);
159 | uTextureSamplerLocation = glGetUniformLocation(mShaderProgram, FilterEngine.TEXTURE_SAMPLER_UNIFORM);
160 |
161 | glActiveTexture(GLES20.GL_TEXTURE0);
162 | glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mOESTextureId);
163 | glUniform1i(uTextureSamplerLocation, 0);
164 | glUniformMatrix4fv(uTextureMatrixLocation, 1, false, transformMatrix, 0);
165 |
166 | if (mBuffer != null) {
167 | mBuffer.position(0);
168 | glEnableVertexAttribArray(aPositionLocation);
169 | glVertexAttribPointer(aPositionLocation, 2, GL_FLOAT, false, 16, mBuffer);
170 |
171 | mBuffer.position(2);
172 | glEnableVertexAttribArray(aTextureCoordLocation);
173 | glVertexAttribPointer(aTextureCoordLocation, 2, GL_FLOAT, false, 16, mBuffer);
174 |
175 | glDrawArrays(GL_TRIANGLES, 0, 6);
176 | }
177 | }
178 |
179 | public int getShaderProgram() {
180 | return mShaderProgram;
181 | }
182 |
183 | public FloatBuffer getBuffer() {
184 | return mBuffer;
185 | }
186 |
187 | public int getOESTextureId() {
188 | return mOESTextureId;
189 | }
190 |
191 | public void setOESTextureId(int OESTextureId) {
192 | mOESTextureId = OESTextureId;
193 | }
194 | }
195 |
196 |
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/util/LabUtil.java:
--------------------------------------------------------------------------------
1 | package camera.cn.cameramaster.util;
2 |
3 |
4 | import java.util.Arrays;
5 |
6 | /**
7 | * rgb 转 lab 工具类
8 | *
9 | * @fileName: LabUtil
10 | * @date: 2019/4/3 13:38
11 | * @author: ymc
12 | * @QQ:745612618
13 | */
14 |
15 | public class LabUtil {
16 |
17 | public static void main(String[] args) {
18 | for (int i = 0; i < 24; i++) {
19 | double[] a = AppConstant.rgbmap[i];
20 | int fx = 0;
21 | int fx1 = -30;
22 | double rrr = a[0] + fx > 255 ? 255 :a[0] + fx;
23 | double ggg = a[1] + fx > 255 ? 255 :a[1] + fx;
24 | double bbb = a[2] + fx1 > 255 ? 255 :a[2] + fx1;
25 | double[] xyz = LabUtil.sRGB2XYZ(new double[]{rrr,ggg,bbb});
26 | double[] lab = LabUtil.XYZ2Lab(xyz);
27 | double cha = Math.sqrt(Math.pow((lab[0] - AppConstant.labmap[i][0]), 2)
28 | + Math.pow((lab[1] - AppConstant.labmap[i][1]), 2)
29 | + Math.pow((lab[2] - AppConstant.labmap[i][2]), 2));
30 | System.out.println(Arrays.toString(new double[]{rrr,ggg,bbb}) + " lab[]:"+ Arrays.toString(lab) + " 色差:"+cha);
31 | System.out.println("lab误差 l: "+(lab[0] - AppConstant.labmap[i][0]) +
32 | " a: "+(lab[1] - AppConstant.labmap[i][1])+" b: "+(lab[2] - AppConstant.labmap[i][2]));
33 | // Log.e("", a.toString() + " lab[]:"+lab.toString() + " 色差:"+cha);
34 | }
35 | }
36 |
37 | /**
38 | * D65 or D50
39 | */
40 | private static boolean hasD50 = false;
41 |
42 | /**
43 | * lab 转 xyz
44 | *
45 | * @param Lab
46 | * @return
47 | */
48 | public static double[] Lab2XYZ(double[] Lab) {
49 | double[] XYZ = new double[3];
50 | double L, a, b;
51 | double fx, fy, fz;
52 | double Xn, Yn, Zn;
53 | // D50
54 | if (hasD50) {
55 | Xn = 96.42;
56 | Yn = 100;
57 | Zn = 82.51;
58 | } else {
59 | // D65
60 | Xn = 95.04;
61 | Yn = 100;
62 | Zn = 108.89;
63 | }
64 | L = Lab[0];
65 | a = Lab[1];
66 | b = Lab[2];
67 |
68 | fy = (L + 16) / 116;
69 | fx = a / 500 + fy;
70 | fz = fy - b / 200;
71 |
72 | if (fx > 0.2069) {
73 | XYZ[0] = Xn * Math.pow(fx, 3);
74 | } else {
75 | XYZ[0] = Xn * (fx - 0.1379) * 0.1284;
76 | }
77 |
78 | if ((fy > 0.2069) || (L > 8)) {
79 | XYZ[1] = Yn * Math.pow(fy, 3);
80 | } else {
81 | XYZ[1] = Yn * (fy - 0.1379) * 0.1284;
82 | }
83 |
84 | if (fz > 0.2069) {
85 | XYZ[2] = Zn * Math.pow(fz, 3);
86 | } else {
87 | XYZ[2] = Zn * (fz - 0.1379) * 0.1284;
88 | }
89 |
90 | return XYZ;
91 | }
92 |
93 | /**
94 | * xyz 转为 lab
95 | *
96 | * @param XYZ
97 | * @return
98 | */
99 | public static double[] XYZ2Lab(double[] XYZ) {
100 | double[] Lab = new double[3];
101 | double X, Y, Z;
102 | X = XYZ[0];
103 | Y = XYZ[1];
104 | Z = XYZ[2];
105 | double Xn, Yn, Zn;
106 | if (hasD50) {
107 | // D50
108 | Xn = 96.42;
109 | Yn = 100;
110 | Zn = 82.51;
111 | } else {
112 | // D65
113 | Xn = 95.04;
114 | Yn = 100;
115 | Zn = 108.89;
116 | }
117 | double XXn, YYn, ZZn;
118 | XXn = X / Xn;
119 | YYn = Y / Yn;
120 | ZZn = Z / Zn;
121 |
122 | double fx, fy, fz;
123 | if (XXn > 0.008856) {
124 | fx = Math.pow(XXn, 0.333333);
125 | } else {
126 | fx = 7.787 * XXn + 0.137931;
127 | }
128 | if (YYn > 0.008856) {
129 | fy = Math.pow(YYn, 0.333333);
130 | } else {
131 | fy = 7.787 * YYn + 0.137931;
132 | }
133 | if (ZZn > 0.008856) {
134 | fz = Math.pow(ZZn, 0.333333);
135 | } else {
136 | fz = 7.787 * ZZn + 0.137931;
137 | }
138 | Lab[0] = 116 * fy - 16;
139 | Lab[1] = 500 * (fx - fy);
140 | Lab[2] = 200 * (fy - fz);
141 |
142 | return Lab;
143 | }
144 |
145 | /**
146 | * rgb 转 xyz
147 | *
148 | * @return double[]
149 | */
150 | public static double[] sRGB2XYZ(double[] RGB) {
151 | double[] XYZ = new double[3];
152 | double sR, sG, sB;
153 | sR = RGB[0];
154 | sG = RGB[1];
155 | sB = RGB[2];
156 | sR /= 255;
157 | sG /= 255;
158 | sB /= 255;
159 |
160 | if (sR <= 0.04045) {
161 | sR = sR / 12.92;
162 | } else {
163 | sR = Math.pow(((sR + 0.055) / 1.055), 2.4);
164 | }
165 |
166 | if (sG <= 0.04045) {
167 | sG = sG / 12.92;
168 | } else {
169 | sG = Math.pow(((sG + 0.055) / 1.055), 2.4);
170 | }
171 |
172 | if (sB <= 0.04045) {
173 | sB = sB / 12.92;
174 | } else {
175 | sB = Math.pow(((sB + 0.055) / 1.055), 2.4);
176 | }
177 | if (hasD50) {
178 | // D50
179 | XYZ[0] = 43.6052025 * sR + 38.5081593 * sG + 14.3087414 * sB;
180 | XYZ[1] = 22.2491598 * sR + 71.6886060 * sG + 6.0621486 * sB;
181 | XYZ[2] = 1.3929122 * sR + 9.7097002 * sG + 71.4185470 * sB;
182 | } else {
183 | // D65
184 | XYZ[0] = 41.24 * sR + 35.76 * sG + 18.05 * sB;
185 | XYZ[1] = 21.26 * sR + 71.52 * sG + 7.22 * sB;
186 | XYZ[2] = 1.93 * sR + 11.92 * sG + 95.05 * sB;
187 | }
188 | return XYZ;
189 | }
190 |
191 | /**
192 | * xyz 转 rgb
193 | *
194 | * @param XYZ double[]
195 | * @return double[]
196 | */
197 | public static double[] XYZ2sRGB(double[] XYZ) {
198 | double[] sRGB = new double[3];
199 | double X, Y, Z;
200 | double dr = 0, dg = 0, db = 0;
201 | X = XYZ[0];
202 | Y = XYZ[1];
203 | Z = XYZ[2];
204 |
205 | if (hasD50) {
206 | // TODO: 2019/4/3 D50格式暂时没有找到 D50格式
207 | } else {
208 | dr = 0.032406 * X - 0.015371 * Y - 0.0049895 * Z;
209 | dg = -0.0096891 * X + 0.018757 * Y + 0.00041914 * Z;
210 | db = 0.00055708 * X - 0.0020401 * Y + 0.01057 * Z;
211 | }
212 |
213 | if (dr <= 0.00313) {
214 | dr = dr * 12.92;
215 | } else {
216 | dr = Math.exp(Math.log(dr) / 2.4) * 1.055 - 0.055;
217 | }
218 |
219 | if (dg <= 0.00313) {
220 | dg = dg * 12.92;
221 | } else {
222 | dg = Math.exp(Math.log(dg) / 2.4) * 1.055 - 0.055;
223 | }
224 |
225 | if (db <= 0.00313) {
226 | db = db * 12.92;
227 | } else {
228 | db = Math.exp(Math.log(db) / 2.4) * 1.055 - 0.055;
229 | }
230 |
231 | dr = dr * 255;
232 | dg = dg * 255;
233 | db = db * 255;
234 |
235 | dr = Math.min(255, dr);
236 | dg = Math.min(255, dg);
237 | db = Math.min(255, db);
238 |
239 | sRGB[0] = dr + 0.5;
240 | sRGB[1] = dg + 0.5;
241 | sRGB[2] = db + 0.5;
242 |
243 | return sRGB;
244 | }
245 |
246 | }
247 |
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/util/MatrixUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * FastDrawerHelper.java
4 | *
5 | * Created by Wuwang on 2016/11/17
6 | * Copyright © 2016年 深圳哎吖科技. All rights reserved.
7 | */
8 | package camera.cn.cameramaster.util;
9 |
10 | import android.opengl.Matrix;
11 |
12 | /**
13 | * 矩阵 工具类
14 | */
15 | public enum MatrixUtils {
16 | ;
17 | public static final int TYPE_FITXY=0;
18 | public static final int TYPE_CENTERCROP=1;
19 | public static final int TYPE_CENTERINSIDE=2;
20 | public static final int TYPE_FITSTART=3;
21 | public static final int TYPE_FITEND=4;
22 |
23 | MatrixUtils(){
24 |
25 | }
26 |
27 | /**
28 | * use {@link #getMatrix} instead
29 | */
30 | @Deprecated
31 | public static void getShowMatrix(float[] matrix,int imgWidth,int imgHeight,int viewWidth,int
32 | viewHeight){
33 | if(imgHeight>0&&imgWidth>0&&viewWidth>0&&viewHeight>0){
34 | float sWhView=(float)viewWidth/viewHeight;
35 | float sWhImg=(float)imgWidth/imgHeight;
36 | float[] projection=new float[16];
37 | float[] camera=new float[16];
38 | if(sWhImg>sWhView){
39 | Matrix.orthoM(projection,0,-sWhView/sWhImg,sWhView/sWhImg,-1,1,1,3);
40 | }else{
41 | Matrix.orthoM(projection,0,-1,1,-sWhImg/sWhView,sWhImg/sWhView,1,3);
42 | }
43 | Matrix.setLookAtM(camera,0,0,0,1,0,0,0,0,1,0);
44 | Matrix.multiplyMM(matrix,0,projection,0,camera,0);
45 | }
46 | }
47 |
48 | public static void getMatrix(float[] matrix,int type,int imgWidth,int imgHeight,int viewWidth,
49 | int viewHeight){
50 | if(imgHeight>0&&imgWidth>0&&viewWidth>0&&viewHeight>0){
51 | float[] projection=new float[16];
52 | float[] camera=new float[16];
53 | if(type==TYPE_FITXY){
54 | Matrix.orthoM(projection,0,-1,1,-1,1,1,3);
55 | Matrix.setLookAtM(camera,0,0,0,1,0,0,0,0,1,0);
56 | Matrix.multiplyMM(matrix,0,projection,0,camera,0);
57 | }
58 | float sWhView=(float)viewWidth/viewHeight;
59 | float sWhImg=(float)imgWidth/imgHeight;
60 | if(sWhImg>sWhView){
61 | switch (type){
62 | case TYPE_CENTERCROP:
63 | Matrix.orthoM(projection,0,-sWhView/sWhImg,sWhView/sWhImg,-1,1,1,3);
64 | break;
65 | case TYPE_CENTERINSIDE:
66 | Matrix.orthoM(projection,0,-1,1,-sWhImg/sWhView,sWhImg/sWhView,1,3);
67 | break;
68 | case TYPE_FITSTART:
69 | Matrix.orthoM(projection,0,-1,1,1-2*sWhImg/sWhView,1,1,3);
70 | break;
71 | case TYPE_FITEND:
72 | Matrix.orthoM(projection,0,-1,1,-1,2*sWhImg/sWhView-1,1,3);
73 | break;
74 | }
75 | }else{
76 | switch (type){
77 | case TYPE_CENTERCROP:
78 | Matrix.orthoM(projection,0,-1,1,-sWhImg/sWhView,sWhImg/sWhView,1,3);
79 | break;
80 | case TYPE_CENTERINSIDE:
81 | Matrix.orthoM(projection,0,-sWhView/sWhImg,sWhView/sWhImg,-1,1,1,3);
82 | break;
83 | case TYPE_FITSTART:
84 | Matrix.orthoM(projection,0,-1,2*sWhView/sWhImg-1,-1,1,1,3);
85 | break;
86 | case TYPE_FITEND:
87 | Matrix.orthoM(projection,0,1-2*sWhView/sWhImg,1,-1,1,1,3);
88 | break;
89 | }
90 | }
91 | Matrix.setLookAtM(camera,0,0,0,1,0,0,0,0,1,0);
92 | Matrix.multiplyMM(matrix,0,projection,0,camera,0);
93 | }
94 | }
95 |
96 | public static void getCenterInsideMatrix(float[] matrix,int imgWidth,int imgHeight,int viewWidth,int
97 | viewHeight){
98 | if(imgHeight>0&&imgWidth>0&&viewWidth>0&&viewHeight>0){
99 | float sWhView=(float)viewWidth/viewHeight;
100 | float sWhImg=(float)imgWidth/imgHeight;
101 | float[] projection=new float[16];
102 | float[] camera=new float[16];
103 | if(sWhImg>sWhView){
104 | Matrix.orthoM(projection,0,-1,1,-sWhImg/sWhView,sWhImg/sWhView,1,3);
105 | }else{
106 | Matrix.orthoM(projection,0,-sWhView/sWhImg,sWhView/sWhImg,-1,1,1,3);
107 | }
108 | Matrix.setLookAtM(camera,0,0,0,1,0,0,0,0,1,0);
109 | Matrix.multiplyMM(matrix,0,projection,0,camera,0);
110 | }
111 | }
112 |
113 | public static float[] rotate(float[] m,float angle){
114 | Matrix.rotateM(m,0,angle,0,0,1);
115 | return m;
116 | }
117 |
118 | public static float[] flip(float[] m,boolean x,boolean y){
119 | if(x||y){
120 | Matrix.scaleM(m,0,x?-1:1,y?-1:1,1);
121 | }
122 | return m;
123 | }
124 |
125 | public static float[] scale(float[] m,float x,float y){
126 | Matrix.scaleM(m,0,x,y,1);
127 | return m;
128 | }
129 |
130 | public static float[] getOriginalMatrix(){
131 | return new float[]{
132 | 1,0,0,0,
133 | 0,1,0,0,
134 | 0,0,1,0,
135 | 0,0,0,1
136 | };
137 | }
138 |
139 | }
140 |
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/util/Utils.java:
--------------------------------------------------------------------------------
1 | package camera.cn.cameramaster.util;
2 |
3 | import android.content.Context;
4 | import android.opengl.GLES11Ext;
5 | import android.opengl.GLES20;
6 | import android.os.Environment;
7 | import android.util.Log;
8 |
9 | import java.io.BufferedReader;
10 | import java.io.File;
11 | import java.io.IOException;
12 | import java.io.InputStream;
13 | import java.io.InputStreamReader;
14 | import java.text.SimpleDateFormat;
15 | import java.util.Date;
16 |
17 | import javax.microedition.khronos.opengles.GL10;
18 |
19 | import static android.provider.MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE;
20 | import static android.provider.MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO;
21 |
22 | /**
23 | * opengles utils
24 | *
25 | * @date 2019年2月12日 14:03:59
26 | * @author ymc
27 | */
28 |
29 | public class Utils {
30 |
31 | private static final String TAG = "Utils";
32 |
33 | /**
34 | * 创建 oes id
35 | * @return oesId
36 | */
37 | public static int createOESTextureObject() {
38 | int[] tex = new int[1];
39 | //生成一个纹理
40 | GLES20.glGenTextures(1, tex, 0);
41 | //将此纹理绑定到外部纹理上
42 | GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, tex[0]);
43 | //设置纹理过滤参数
44 | GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
45 | GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
46 | GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
47 | GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
48 | GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
49 | GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
50 | GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
51 | GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
52 | //解除纹理绑定
53 | GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 0);
54 | return tex[0];
55 | }
56 |
57 | public static String readShaderFromResource(Context context, int resourceId) {
58 | StringBuilder builder = new StringBuilder();
59 | InputStream is = null;
60 | InputStreamReader isr = null;
61 | BufferedReader br = null;
62 | try {
63 | is = context.getResources().openRawResource(resourceId);
64 | isr = new InputStreamReader(is);
65 | br = new BufferedReader(isr);
66 | String line;
67 | while ((line = br.readLine()) != null) {
68 | builder.append(line).append("\n");
69 | }
70 | } catch (IOException e) {
71 | e.printStackTrace();
72 | } finally {
73 | try {
74 | if (is != null) {
75 | is.close();
76 | is = null;
77 | }
78 | if (isr != null) {
79 | isr.close();
80 | isr = null;
81 | }
82 | if (br != null) {
83 | br.close();
84 | br = null;
85 | }
86 | } catch (IOException e) {
87 | e.printStackTrace();
88 | }
89 | }
90 | return builder.toString();
91 | }
92 |
93 |
94 | /**
95 | * 获取输出照片视频路径
96 | * @param mContext 上下文
97 | * @param mediaType 拍照视频类型
98 | * @return 文件地址
99 | */
100 | public static File getOutputMediaFile(Context mContext, int mediaType) {
101 | String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
102 | String fileName = null;
103 | File storageDir = null;
104 | if (mediaType == MEDIA_TYPE_IMAGE) {
105 | fileName = "JPEG_" + timeStamp + "_";
106 | storageDir = mContext.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
107 | } else if (mediaType == MEDIA_TYPE_VIDEO) {
108 | fileName = "MP4_" + timeStamp + "_";
109 | storageDir = mContext.getExternalFilesDir(Environment.DIRECTORY_MOVIES);
110 | }
111 |
112 | // Create the storage directory if it does not exist
113 | if (!storageDir.exists()) {
114 | if (!storageDir.mkdirs()) {
115 | Log.d(TAG, "failed to create directory");
116 | return null;
117 | }
118 | }
119 |
120 | File file = null;
121 | try {
122 | file = File.createTempFile(
123 | fileName, /* prefix */
124 | (mediaType == MEDIA_TYPE_IMAGE) ? ".jpg" : ".mp4", /* suffix */
125 | storageDir /* directory */
126 | );
127 | Log.d(TAG, "getOutputMediaFile: absolutePath==" + file.getAbsolutePath());
128 | } catch (IOException e) {
129 | e.printStackTrace();
130 | }
131 | return file;
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/util/cameravideo/CoordinateTransformer.java:
--------------------------------------------------------------------------------
1 | package camera.cn.cameramaster.util.cameravideo;
2 |
3 | import android.graphics.Matrix;
4 | import android.graphics.Rect;
5 | import android.graphics.RectF;
6 | import android.hardware.camera2.CameraCharacteristics;
7 | import android.os.Build;
8 | import android.support.annotation.RequiresApi;
9 |
10 | /**
11 | * 将坐标转换为预览坐标空间和相机驱动程序坐标空间。
12 | * @author ymc
13 | */
14 |
15 | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
16 | public class CoordinateTransformer {
17 |
18 | private final Matrix mPreviewToCameraTransform;
19 | private RectF mDriverRectF;
20 |
21 | /**
22 | * 将矩形转换为相机坐标或从相机坐标转换并预览坐标空间。
23 | * @param chr camera characteristics
24 | * @param previewRect the preview rectangle size and position.
25 | */
26 |
27 | public CoordinateTransformer(CameraCharacteristics chr, RectF previewRect) {
28 | if (!hasNonZeroArea(previewRect)) {
29 | throw new IllegalArgumentException("previewRect");
30 | }
31 | Rect rect = chr.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
32 | Integer sensorOrientation = chr.get(CameraCharacteristics.SENSOR_ORIENTATION);
33 | int rotation = sensorOrientation == null ? 90 : sensorOrientation;
34 | mDriverRectF = new RectF(rect);
35 | Integer face = chr.get(CameraCharacteristics.LENS_FACING);
36 | boolean mirrorX = face != null && face == CameraCharacteristics.LENS_FACING_FRONT;
37 | mPreviewToCameraTransform = previewToCameraTransform(mirrorX, rotation, previewRect);
38 | }
39 |
40 | /**
41 | * 将预览视图空间中的矩形转换为新的矩形相机视图空间。
42 | *
43 | * @param source the rectangle in preview view space
44 | * @return the rectangle in camera view space.
45 | */
46 | public RectF toCameraSpace(RectF source) {
47 | RectF result = new RectF();
48 | mPreviewToCameraTransform.mapRect(result, source);
49 | return result;
50 | }
51 |
52 | private Matrix previewToCameraTransform(boolean mirrorX, int sensorOrientation,
53 | RectF previewRect) {
54 | Matrix transform = new Matrix();
55 | // Need mirror for front camera.
56 | transform.setScale(mirrorX ? -1 : 1, 1);
57 | // Because preview orientation is different form sensor orientation,
58 | // rotate to same orientation, Counterclockwise.
59 | transform.postRotate(-sensorOrientation);
60 | // Map rotated matrix to preview rect
61 | transform.mapRect(previewRect);
62 | // Map preview coordinates to driver coordinates
63 | Matrix fill = new Matrix();
64 | fill.setRectToRect(previewRect, mDriverRectF, Matrix.ScaleToFit.FILL);
65 | // Concat the previous transform on top of the fill behavior.
66 | transform.setConcat(fill, transform);
67 | // finally get transform matrix
68 | return transform;
69 | }
70 |
71 | private boolean hasNonZeroArea(RectF rect) {
72 | return rect.width() != 0 && rect.height() != 0;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/util/cameravideo/ICamera2.java:
--------------------------------------------------------------------------------
1 | package camera.cn.cameramaster.util.cameravideo;
2 |
3 | import android.util.Size;
4 | import android.view.Surface;
5 | import android.view.TextureView;
6 |
7 | import java.io.File;
8 |
9 | /**
10 | * 相机 接口类
11 | */
12 |
13 | public interface ICamera2 {
14 |
15 | /**
16 | * 缩放
17 | * @param zoom 缩放比例
18 | */
19 | void cameraZoom(float zoom);
20 |
21 | /**
22 | * 打开摄像头
23 | */
24 | boolean openCamera(CameraType cameraType);
25 |
26 | /**
27 | * 关闭摄像头
28 | */
29 | void closeCamera();
30 |
31 | /**
32 | * 切换摄像头
33 | * @param cameraType 切换摄像头类型
34 | * @return boolean 是否切换成功
35 | */
36 | boolean switchCamera(CameraType cameraType);
37 |
38 | /**
39 | * 开启相机的预览模式
40 | */
41 | boolean startPreview();
42 |
43 | /**
44 | * 停止预览
45 | */
46 | void resumePreview();
47 |
48 | /**
49 | * 开始视频的录制
50 | * @param path 存储路径
51 | * @param mediaType 文件类型
52 | */
53 | boolean startVideoRecord(String path, int mediaType);
54 |
55 | /**
56 | * 停止视频录制
57 | */
58 | void stopVideoRecord();
59 |
60 | /**
61 | * 拍照
62 | * @param path 存储路径
63 | * @param mediaType 文件类型
64 | */
65 | boolean takePhone(String path, MediaType mediaType);
66 |
67 | /**
68 | * 获取预览大小
69 | * @return
70 | */
71 | Size getPreViewSize();
72 |
73 | void setSurface(Surface surface);
74 |
75 | void setTextureView(TextureView textureView);
76 |
77 | void setTakePhotoListener(TakePhotoListener mTakePhotoListener);
78 |
79 | void setCameraReady(CameraReady mCameraReady);
80 |
81 | void flashSwitchState(FlashState mFlashState);
82 |
83 | void setCameraState(CameraMode cameraMode);
84 |
85 | /**
86 | * 手动请求对焦
87 | * @param x
88 | * @param y
89 | */
90 | void requestFocus(float x, float y);
91 |
92 | /**
93 | * 摄像头模式类型
94 | */
95 | enum CameraMode
96 | {
97 | RECORD_VIDEO,
98 | TAKE_PHOTO
99 | }
100 |
101 | /**
102 | * 当前只有mp4类型
103 | */
104 | enum MediaType
105 | {
106 | MP4,
107 | JPEG,
108 | }
109 |
110 | /**
111 | * 摄像头类型
112 | */
113 | enum CameraType
114 | {
115 | FRONT,
116 | BACK,
117 | USB
118 | }
119 |
120 | /**
121 | * 灯光状态
122 | */
123 | enum FlashState
124 | {
125 | CLOSE,
126 | AUTO,
127 | OPEN
128 | }
129 |
130 | interface TakePhotoListener{
131 | void onTakePhotoFinish(File file, int photoRotation, int width, int height);
132 | }
133 |
134 | interface CameraReady
135 | {
136 | void onCameraReady();
137 | }
138 | }
139 |
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/util/cameravideo/IVideoControl.java:
--------------------------------------------------------------------------------
1 | package camera.cn.cameramaster.util.cameravideo;
2 |
3 | /**
4 | * 视频接口
5 | */
6 |
7 | public interface IVideoControl {
8 |
9 | /**
10 | * 播放视频
11 | */
12 | void play();
13 |
14 | /**
15 | * 暂停视频播放
16 | */
17 | void pause();
18 |
19 | /**
20 | * 继续播放视频,前提是暂停了视频
21 | */
22 | void resume();
23 |
24 | /**
25 | * 停止播放视频
26 | */
27 | void stop();
28 |
29 | /**
30 | * 进度条快进
31 | * @param timeStamp
32 | */
33 | void seekTo(int timeStamp);
34 |
35 | void setPlaySeekTimeListener(PlaySeekTimeListener mPlaySeekTimeListener);
36 |
37 | void setPlayStateListener(PlayStateListener mPlayStateListener);
38 |
39 | interface PlaySeekTimeListener
40 | {
41 | void onSeekTime(int allTime, int time);
42 | }
43 |
44 | /**
45 | * 播放状态
46 | */
47 | interface PlayStateListener{
48 |
49 | void onStartListener(int width, int height);
50 |
51 | void onCompletionListener();
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/view/AnimationTextView.java:
--------------------------------------------------------------------------------
1 | package camera.cn.cameramaster.view;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.content.Context;
5 | import android.os.Build;
6 | import android.os.Handler;
7 | import android.support.annotation.RequiresApi;
8 | import android.util.AttributeSet;
9 | import android.view.animation.Animation;
10 | import android.widget.TextView;
11 |
12 | /**
13 | * 文字显示 一秒后消失
14 | */
15 |
16 | @SuppressLint("AppCompatCustomView")
17 | public class AnimationTextView extends TextView {
18 | private Handler mMainHandler;
19 | private Animation mAnimation;
20 | /**
21 | * 防止又换了个text,但是上次哪个还没有消失即将小时就把新的text的给消失了
22 | */
23 | public int mTimes = 0;
24 |
25 | public AnimationTextView(Context context) {
26 | super(context);
27 | }
28 |
29 | public AnimationTextView(Context context, AttributeSet attrs) {
30 | super(context, attrs);
31 | }
32 |
33 | public AnimationTextView(Context context, AttributeSet attrs, int defStyleAttr) {
34 | super(context, attrs, defStyleAttr);
35 | }
36 |
37 | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
38 | public AnimationTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
39 | super(context, attrs, defStyleAttr, defStyleRes);
40 | }
41 |
42 | public void setmMainHandler(Handler mMainHandler) {
43 | this.mMainHandler = mMainHandler;
44 | }
45 |
46 | public void setmAnimation(Animation mAnimation) {
47 | this.mAnimation = mAnimation;
48 | }
49 |
50 | public void start(String text, int message) {
51 | if (mAnimation == null || mMainHandler == null) {
52 | return;
53 | }
54 | this.setVisibility(VISIBLE);
55 | mTimes++;
56 | this.setText(text);
57 | this.startAnimation(mAnimation);
58 | new Thread(new SleepThread(mMainHandler, message, 1000, Integer.valueOf(mTimes))).start();
59 | }
60 |
61 | public void stop() {
62 | this.setVisibility(GONE);
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/view/AutoFitTextureView.java:
--------------------------------------------------------------------------------
1 | package camera.cn.cameramaster.view;
2 |
3 | import android.content.Context;
4 | import android.graphics.Matrix;
5 | import android.util.AttributeSet;
6 | import android.view.TextureView;
7 |
8 | /**
9 | * 自定义 TextureView
10 | * 重新计算预览宽高
11 | *
12 | * @fileName: AutoFitTextureView
13 | * @date: 2019/1/28 17:00
14 | * @author: ymc
15 | * @QQ:745612618
16 | */
17 |
18 | public class AutoFitTextureView extends TextureView {
19 |
20 | private int mRatioWidth = 0;
21 | private int mRatioHeight = 0;
22 |
23 | public AutoFitTextureView(Context context) {
24 | this(context, null);
25 | }
26 |
27 | public AutoFitTextureView(Context context, AttributeSet attrs) {
28 | this(context, attrs, 0);
29 | }
30 |
31 | public AutoFitTextureView(Context context, AttributeSet attrs, int defStyle) {
32 | super(context, attrs, defStyle);
33 | }
34 |
35 | /**
36 | * 设置此视图的纵横比。将根据比率测量视图的大小 根据参数计算。注意,参数的实际大小无关紧要
37 | * 调用setAspectRatio(2,3)和setAspectRatio(4,6)会产生相同的结果。
38 | *
39 | * @param width Relative horizontal size
40 | * @param height Relative vertical size
41 | */
42 | public void setAspectRatio(int width, int height) {
43 | if (width < 0 || height < 0) {
44 | throw new IllegalArgumentException("Size cannot be negative.");
45 | }
46 | mRatioWidth = width;
47 | mRatioHeight = height;
48 |
49 | float mRatio = (float) mRatioWidth / (float) mRatioHeight; //算出相机的缩放比例
50 |
51 | float w = mRatio * getHeight();
52 | float scale;
53 | if (w > getWidth())
54 | scale = w / (float) getWidth();
55 | else
56 | scale = (float) getWidth() / w;
57 |
58 | Matrix matrix = new Matrix();
59 | matrix.postScale(scale, 1, getWidth() / 2, getHeight() / 2);
60 | setTransform(matrix);
61 | }
62 |
63 | /**
64 | * 视频宽度适配
65 | * @param width
66 | * @param height
67 | */
68 | public void setVideoAspectRatio(int width, int height)
69 | {
70 | if (width < 0 || height < 0) {
71 | throw new IllegalArgumentException("Size cannot be negative.");
72 | }
73 | mRatioWidth = width;
74 | mRatioHeight = height;
75 |
76 | float mRatio = (float) mRatioWidth / (float) mRatioHeight; //算出相机的缩放比例
77 | if(mRatio < 1.0)
78 | {
79 | setAspectRatio(width, height);
80 | }else {
81 | float h = getWidth() / mRatio;
82 | float scale;
83 | if (h > getHeight())
84 | scale = (float) getHeight() / h;
85 | else
86 | scale = h / (float) getHeight();
87 |
88 | Matrix matrix = new Matrix();
89 | matrix.postScale(1, scale, getWidth() / 2, getHeight() / 2);
90 | setTransform(matrix);
91 | }
92 | }
93 |
94 | }
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/view/AutoTextureView.java:
--------------------------------------------------------------------------------
1 | package camera.cn.cameramaster.view;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.TextureView;
6 |
7 | /**
8 | * 自定义 正方形预览界面
9 | *
10 | * @packageName: camera.cn.cameramaster.view
11 | * @fileName: AutoTextureView
12 | * @date: 2019/5/9 16:15
13 | * @author: ymc
14 | * @QQ:745612618
15 | */
16 |
17 | public class AutoTextureView extends TextureView {
18 |
19 | private int mRatioWidth = 0;
20 | private int mRatioHeight = 0;
21 |
22 | public AutoTextureView(Context context) {
23 | super(context);
24 | }
25 |
26 | public AutoTextureView(Context context, AttributeSet attrs) {
27 | super(context, attrs);
28 | }
29 |
30 | public AutoTextureView(Context context, AttributeSet attrs, int defStyleAttr) {
31 | super(context, attrs, defStyleAttr);
32 | }
33 | /**
34 | * Sets the aspect ratio for this view. The size of the view will be measured based on the ratio
35 | * calculated from the parameters. Note that the actual sizes of parameters don't matter, that
36 | * is, calling setAspectRatio(2, 3) and setAspectRatio(4, 6) make the same result.
37 | *
38 | * @param width Relative horizontal size
39 | * @param height Relative vertical size
40 | */
41 | public void setAspectRatio(int width, int height) {
42 | if (width < 0 || height < 0) {
43 | throw new IllegalArgumentException("Size cannot be negative.");
44 | }
45 | mRatioWidth = width;
46 | mRatioHeight = height;
47 | requestLayout();
48 | }
49 |
50 | @Override
51 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
52 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
53 | int width = MeasureSpec.getSize(widthMeasureSpec);
54 | int height = MeasureSpec.getSize(heightMeasureSpec);
55 | if (0 == mRatioWidth || 0 == mRatioHeight) {
56 | setMeasuredDimension(width, height);
57 | } else {
58 | if (width < height * mRatioWidth / mRatioHeight) {
59 | setMeasuredDimension(width, width * mRatioHeight / mRatioWidth);
60 | } else {
61 | setMeasuredDimension(height * mRatioWidth / mRatioHeight, height);
62 | }
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/view/AwbSeekBar.java:
--------------------------------------------------------------------------------
1 | package camera.cn.cameramaster.view;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.content.Context;
5 | import android.os.Build;
6 | import android.support.annotation.RequiresApi;
7 | import android.util.AttributeSet;
8 | import android.widget.SeekBar;
9 |
10 | /**
11 | * 自定义 8种白平衡状态 选择 seekBar
12 | *
13 | * @author ymc
14 | */
15 |
16 | @SuppressLint("AppCompatCustomView")
17 | public class AwbSeekBar extends SeekBar {
18 |
19 | private int mProgress;
20 | private AwbSeekBar mAwbSeekBar = this;
21 | private OnAwbSeekBarChangeListener mOnAwbSeekBarChangeListener;
22 |
23 | public AwbSeekBar(Context context) {
24 | super(context);
25 | init();
26 | }
27 |
28 | public AwbSeekBar(Context context, AttributeSet attrs) {
29 | super(context, attrs);
30 | init();
31 | }
32 |
33 | public AwbSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
34 | super(context, attrs, defStyleAttr);
35 | init();
36 | }
37 |
38 | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
39 | public AwbSeekBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
40 | super(context, attrs, defStyleAttr, defStyleRes);
41 | init();
42 | }
43 | public void setmOnAwbSeekBarChangeListener(OnAwbSeekBarChangeListener mOnAwbSeekBarChangeListener) {
44 | this.mOnAwbSeekBarChangeListener = mOnAwbSeekBarChangeListener;
45 | }
46 |
47 | private void init() {
48 | this.setMax(70);
49 | this.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
50 | @Override
51 | public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
52 | mProgress = progress;
53 | if (mOnAwbSeekBarChangeListener != null) {
54 | if (0 <= mProgress && mProgress < 5) {
55 | mOnAwbSeekBarChangeListener.doInProgress1();
56 | } else if (5 <= mProgress && mProgress < 15) {
57 | mOnAwbSeekBarChangeListener.doInProgress2();
58 | } else if (15 <= mProgress && mProgress < 25) {
59 | mOnAwbSeekBarChangeListener.doInProgress3();
60 | } else if (25 <= mProgress && mProgress < 35) {
61 | mOnAwbSeekBarChangeListener.doInProgress4();
62 | } else if (35 <= mProgress && mProgress < 45) {
63 | mOnAwbSeekBarChangeListener.doInProgress5();
64 | } else if (45 <= mProgress && mProgress < 55) {
65 | mOnAwbSeekBarChangeListener.doInProgress6();
66 | } else if (55 <= mProgress && mProgress < 65) {
67 | mOnAwbSeekBarChangeListener.doInProgress7();
68 | } else if (65 <= mProgress && mProgress < 70) {
69 | mOnAwbSeekBarChangeListener.doInProgress8();
70 | }
71 | }
72 | }
73 |
74 | @Override
75 | public void onStartTrackingTouch(SeekBar seekBar) {
76 | mOnAwbSeekBarChangeListener.onStartTrackingTouch(seekBar);
77 | }
78 |
79 | @Override
80 | public void onStopTrackingTouch(SeekBar seekBar) {
81 | int num = 0;
82 | if (0 <= mProgress && mProgress < 5) {
83 | mAwbSeekBar.setProgress(0);
84 | num = 0;
85 | } else if (5 <= mProgress && mProgress < 15) {
86 | mAwbSeekBar.setProgress(10);
87 | num = 10;
88 | } else if (15 <= mProgress && mProgress < 25) {
89 | mAwbSeekBar.setProgress(20);
90 | num = 20;
91 | } else if (25 <= mProgress && mProgress < 35) {
92 | mAwbSeekBar.setProgress(30);
93 | num = 30;
94 | } else if (35 <= mProgress && mProgress < 45) {
95 | mAwbSeekBar.setProgress(40);
96 | num = 40;
97 | } else if (45 <= mProgress && mProgress < 55) {
98 | mAwbSeekBar.setProgress(50);
99 | num = 50;
100 | } else if (55 <= mProgress && mProgress < 65) {
101 | mAwbSeekBar.setProgress(60);
102 | num = 60;
103 | } else if (65 <= mProgress && mProgress < 70) {
104 | mAwbSeekBar.setProgress(70);
105 | num = 70;
106 | }
107 | if (mOnAwbSeekBarChangeListener != null) {
108 | mOnAwbSeekBarChangeListener.onStopTrackingTouch(num);
109 | }
110 | }
111 | });
112 | }
113 |
114 | public interface OnAwbSeekBarChangeListener {
115 | public abstract void doInProgress1();
116 |
117 | public abstract void doInProgress2();
118 |
119 | public abstract void doInProgress3();
120 |
121 | public abstract void doInProgress4();
122 |
123 | public abstract void doInProgress5();
124 |
125 | public abstract void doInProgress6();
126 |
127 | public abstract void doInProgress7();
128 |
129 | public abstract void doInProgress8();
130 |
131 | public abstract void onStopTrackingTouch(int num);
132 |
133 | public abstract void onStartTrackingTouch(SeekBar seekBar);
134 | }
135 |
136 | }
137 |
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/view/AwbSeekBarChangeListener.java:
--------------------------------------------------------------------------------
1 | package camera.cn.cameramaster.view;
2 |
3 | import android.content.Context;
4 | import android.hardware.camera2.CameraAccessException;
5 | import android.hardware.camera2.CameraCaptureSession;
6 | import android.hardware.camera2.CameraMetadata;
7 | import android.hardware.camera2.CaptureRequest;
8 | import android.os.Build;
9 | import android.os.Handler;
10 | import android.support.annotation.RequiresApi;
11 | import android.util.Log;
12 | import android.view.View;
13 | import android.view.animation.Animation;
14 | import android.view.animation.AnimationUtils;
15 | import android.widget.SeekBar;
16 | import android.widget.TextView;
17 |
18 | import camera.cn.cameramaster.R;
19 | import camera.cn.cameramaster.view.AwbSeekBar;
20 |
21 |
22 | /**
23 | * 自定义 seekbar 滑动监听事件
24 | * @author ymc
25 | */
26 |
27 | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
28 | public class AwbSeekBarChangeListener implements AwbSeekBar.OnAwbSeekBarChangeListener {
29 | private TextView mTextView;
30 | private CaptureRequest.Builder mPreviewBuilder;
31 | private CameraCaptureSession mCameraCaptureSession;
32 | private Handler mHandler;
33 | private CameraCaptureSession.CaptureCallback mPreviewSessionCallback;
34 |
35 | private Animation mAlphaInAnimation;
36 | private Animation mAlphaOutAnimation;
37 |
38 | public AwbSeekBarChangeListener(Context mContext, TextView mTextView, CaptureRequest.Builder mPreviewBuilder,
39 | CameraCaptureSession mCameraCaptureSession, Handler mHandler,
40 | CameraCaptureSession.CaptureCallback mPreviewSessionCallback) {
41 | this.mTextView = mTextView;
42 | this.mPreviewBuilder = mPreviewBuilder;
43 | this.mCameraCaptureSession = mCameraCaptureSession;
44 | this.mHandler = mHandler;
45 | this.mPreviewSessionCallback = mPreviewSessionCallback;
46 | mAlphaInAnimation = AnimationUtils.loadAnimation(mContext, R.anim.alpha_in);
47 | mAlphaOutAnimation = AnimationUtils.loadAnimation(mContext, R.anim.alpha_out);
48 | }
49 |
50 | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
51 | @Override
52 | public void doInProgress1() {
53 | mTextView.setText("自动");
54 | mPreviewBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_AUTO);
55 | updatePreview();
56 | }
57 |
58 | @Override
59 | public void doInProgress2() {
60 | mTextView.setText("多云");
61 | mPreviewBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_CLOUDY_DAYLIGHT);
62 | updatePreview();
63 | }
64 |
65 | @Override
66 | public void doInProgress3() {
67 | mTextView.setText("白天");
68 | mPreviewBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_DAYLIGHT);
69 | updatePreview();
70 | }
71 |
72 |
73 | @Override
74 | public void doInProgress4() {
75 | mTextView.setText("日光灯");
76 | mPreviewBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_FLUORESCENT);
77 | updatePreview();
78 | }
79 |
80 | @Override
81 | public void doInProgress5() {
82 | mTextView.setText("白炽灯");
83 | mPreviewBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_INCANDESCENT);
84 | updatePreview();
85 | }
86 |
87 | @Override
88 | public void doInProgress6() {
89 | mTextView.setText("阴影");
90 | mPreviewBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_SHADE);
91 | updatePreview();
92 | }
93 |
94 | @Override
95 | public void doInProgress7() {
96 | mTextView.setText("黄昏");
97 | mPreviewBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_TWILIGHT);
98 | updatePreview();
99 | }
100 |
101 | @Override
102 | public void doInProgress8() {
103 | mTextView.setText("暖光");
104 | mPreviewBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_WARM_FLUORESCENT);
105 | updatePreview();
106 | }
107 |
108 | @Override
109 | public void onStopTrackingTouch(int num) {
110 | switch (num) {
111 | case 0:
112 | mTextView.setText("自动");
113 | mPreviewBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_AUTO);
114 | break;
115 | case 10:
116 | mTextView.setText("多云");
117 | mPreviewBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_CLOUDY_DAYLIGHT);
118 | break;
119 | case 20:
120 | mTextView.setText("白天");
121 | mPreviewBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_DAYLIGHT);
122 | break;
123 | case 30:
124 | mTextView.setText("日光灯");
125 | mPreviewBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_FLUORESCENT);
126 | break;
127 | case 40:
128 | mTextView.setText("白炽灯");
129 | mPreviewBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_INCANDESCENT);
130 | break;
131 | case 50:
132 | mTextView.setText("阴影");
133 | mPreviewBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_SHADE);
134 | break;
135 | case 60:
136 | mTextView.setText("黄昏");
137 | mPreviewBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_TWILIGHT);
138 | break;
139 | case 70:
140 | mTextView.setText("暖光");
141 | mPreviewBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_WARM_FLUORESCENT);
142 | break;
143 | }
144 | updatePreview();
145 | mTextView.startAnimation(mAlphaOutAnimation);
146 | mTextView.setVisibility(View.INVISIBLE);
147 | }
148 |
149 | @Override
150 | public void onStartTrackingTouch(SeekBar seekBar) {
151 | mTextView.setVisibility(View.VISIBLE);
152 | mTextView.startAnimation(mAlphaInAnimation);
153 | }
154 |
155 | /**
156 | * 更新预览
157 | */
158 | private void updatePreview() {
159 | try {
160 | mCameraCaptureSession.setRepeatingRequest(mPreviewBuilder.build(), mPreviewSessionCallback, mHandler);
161 | } catch (CameraAccessException e) {
162 | e.printStackTrace();
163 | } catch (Exception e) {
164 | e.printStackTrace();
165 | Log.i("updatePreview", "ExceptionExceptionException");
166 | }
167 | }
168 | }
169 |
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/view/CameraV2GLSurfaceView.java:
--------------------------------------------------------------------------------
1 | package camera.cn.cameramaster.view;
2 |
3 | import android.content.Context;
4 | import android.opengl.GLSurfaceView;
5 |
6 | import camera.cn.cameramaster.util.render.CameraV2Renderer;
7 | import camera.cn.cameramaster.util.CameraV2;
8 |
9 |
10 | /**
11 | * CameraV2 GLSurfaceView
12 | * 参考url : [https://blog.csdn.net/lb377463323/article/details/78054892]
13 | *
14 | * @date 2019年2月12日 13:41:16
15 | * @author ymc
16 | */
17 |
18 | public class CameraV2GLSurfaceView extends GLSurfaceView {
19 | public static boolean shouldTakePic = false;
20 |
21 | public void init(CameraV2 camera, boolean isPreviewStarted, Context context) {
22 | setEGLContextClientVersion(2);
23 | CameraV2Renderer mCameraV2Renderer = new CameraV2Renderer();
24 | mCameraV2Renderer.init(this, camera, isPreviewStarted, context);
25 | setRenderer(mCameraV2Renderer);
26 | setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
27 | }
28 |
29 | public CameraV2GLSurfaceView(Context context) {
30 | super(context);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/view/ShowSurfaceView.java:
--------------------------------------------------------------------------------
1 | package camera.cn.cameramaster.view;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.Canvas;
6 | import android.graphics.Color;
7 | import android.graphics.Paint;
8 | import android.util.AttributeSet;
9 | import android.view.SurfaceHolder;
10 | import android.view.SurfaceView;
11 |
12 | /**
13 | * @packageName: cn.tongue.tonguecamera.view
14 | * @fileName: ShowSurfaceView
15 | * @date: 2019/3/7 13:17
16 | * @author: ymc
17 | * @QQ:745612618
18 | */
19 |
20 | public class ShowSurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable {
21 | private SurfaceHolder mSurfaceHolder;
22 | /**
23 | * 绘图的Canvas
24 | */
25 | private Canvas mCanvas;
26 | /**
27 | * 子线程标志位
28 | */
29 | private boolean mIsDrawing;
30 | private Bitmap bitmap;
31 | private Paint mPaint;
32 |
33 | public ShowSurfaceView(Context context) {
34 | this(context, null);
35 | }
36 |
37 | public ShowSurfaceView(Context context, AttributeSet attrs) {
38 | this(context, attrs, 0);
39 | }
40 |
41 | public ShowSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
42 | super(context, attrs, defStyleAttr);
43 | mSurfaceHolder = getHolder();
44 | mSurfaceHolder.addCallback(this);
45 | setFocusable(true);
46 | setKeepScreenOn(true);
47 | setFocusableInTouchMode(true);
48 | mPaint = new Paint();
49 | mPaint.setColor(Color.BLACK);
50 | mPaint.setStyle(Paint.Style.STROKE);
51 | mPaint.setAntiAlias(true);
52 | mPaint.setStrokeWidth(5);
53 | }
54 |
55 | @Override
56 | public void surfaceCreated(SurfaceHolder holder) {
57 | mIsDrawing = true;
58 | //开启子线程
59 | new Thread(this).start();
60 | }
61 |
62 | @Override
63 | public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
64 | //改变
65 | }
66 |
67 | @Override
68 | public void surfaceDestroyed(SurfaceHolder holder) {
69 | mIsDrawing = false;
70 | }
71 |
72 | @Override
73 | public void run() {
74 | while (mIsDrawing) {
75 | drawSomething();
76 | }
77 | }
78 |
79 | //绘图逻辑
80 | private void drawSomething() {
81 | try {
82 | //获得canvas对象
83 | mCanvas = mSurfaceHolder.lockCanvas();
84 | // Bitmap bitmap1= BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
85 | if (bitmap != null) {
86 | mCanvas.drawBitmap(bitmap, 0, 0, mPaint);
87 | }
88 | //绘图
89 | } catch (Exception e) {
90 |
91 | } finally {
92 | if (mCanvas != null) {
93 | //释放canvas对象并提交画布
94 | mSurfaceHolder.unlockCanvasAndPost(mCanvas);
95 | }
96 | }
97 | }
98 |
99 | public Bitmap getBitmap() {
100 | return bitmap;
101 | }
102 |
103 | public void setBitmap(Bitmap bitmap) {
104 | this.bitmap = bitmap;
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/app/src/main/java/camera/cn/cameramaster/view/SleepThread.java:
--------------------------------------------------------------------------------
1 | package camera.cn.cameramaster.view;
2 |
3 | import android.os.Handler;
4 | import android.os.Message;
5 |
6 | /**
7 | * 睡眠线程
8 | *
9 | * @author ymc
10 | */
11 | public class SleepThread implements Runnable {
12 | private Handler mMainHandler;
13 | private int what;
14 | private long mTime;
15 | private Object mObject;
16 |
17 | public SleepThread(Handler mainHandler, int what, long mTime, Object mObject) {
18 | this.mMainHandler = mainHandler;
19 | this.what = what;
20 | this.mTime = mTime;
21 | this.mObject = mObject;
22 | }
23 |
24 | @Override
25 | public void run() {
26 | try {
27 | Thread.sleep(mTime);
28 | } catch (InterruptedException e) {
29 | e.printStackTrace();
30 | }
31 | Message message = mMainHandler.obtainMessage();
32 | message.what = what;
33 | message.obj = mObject;
34 | mMainHandler.sendMessage(message);
35 |
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/alpha_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/alpha_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_camera.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_fouces.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_camera.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_camera.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
17 |
18 |
19 |
20 |
26 |
27 |
32 |
33 |
34 |
35 |
36 |
42 |
43 |
52 |
53 |
61 |
62 |
63 |
64 |
73 |
74 |
81 |
82 |
86 |
87 |
94 |
95 |
96 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_camera2.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
15 |
16 |
17 |
18 |
24 |
25 |
34 |
35 |
43 |
44 |
45 |
46 |
55 |
56 |
63 |
64 |
68 |
69 |
76 |
77 |
78 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_camera_sv.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
14 |
15 |
21 |
22 |
31 |
32 |
40 |
41 |
42 |
43 |
53 |
54 |
61 |
62 |
66 |
67 |
74 |
75 |
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_look_camera.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
8 |
11 |
12 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
18 |
19 |
28 |
29 |
38 |
39 |
48 |
49 |
59 |
60 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_show_pic.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
18 |
19 |
26 |
27 |
28 |
35 |
36 |
40 |
41 |
48 |
49 |
50 |
51 |
58 |
59 |
63 |
64 |
71 |
72 |
73 |
80 |
81 |
85 |
86 |
93 |
94 |
95 |
96 |
101 |
102 |
103 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_age.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_rv_text.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/btn_ae.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/btn_ae.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/btn_album.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/btn_album.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/btn_awb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/btn_awb.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/btn_camera_turn_n.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/btn_camera_turn_n.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/btn_change_camera_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/btn_change_camera_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/btn_effect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/btn_effect.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/btn_flash_auto_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/btn_flash_auto_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/btn_flash_off_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/btn_flash_off_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/btn_flash_on_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/btn_flash_on_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/btn_iso.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/btn_iso.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/btn_sense.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/btn_sense.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/btn_zoom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/btn_zoom.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/flash_auto.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/flash_auto.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/flash_close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/flash_close.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/flash_open.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/flash_open.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/ic_add.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_camera_wb_auto.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/ic_camera_wb_auto.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_camera_wb_cloudy_daylight.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/ic_camera_wb_cloudy_daylight.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_camera_wb_daylight.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/ic_camera_wb_daylight.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_camera_wb_fluorescent.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/ic_camera_wb_fluorescent.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_camera_wb_incandescent.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/ic_camera_wb_incandescent.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_camera_wb_shade.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/ic_camera_wb_shade.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_camera_wb_twilight.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/ic_camera_wb_twilight.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_camera_wb_warm_fluorescent.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/ic_camera_wb_warm_fluorescent.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/ic_close.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/ic_delete.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_minus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/ic_minus.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_pause.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/ic_pause.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/ic_play.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_recording.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/ic_recording.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_save.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/ic_save.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_switch_camera.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/ic_switch_camera.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_video_close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/ic_video_close.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/icon_back.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/icon_camera_a.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/icon_camera_a.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/icon_camera_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/icon_camera_off.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/icon_camera_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xhdpi/icon_camera_on.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/raw/base_fragment_shader.glsl:
--------------------------------------------------------------------------------
1 | #extension GL_OES_EGL_image_external : require
2 | uniform samplerExternalOES uTextureSampler;
3 | precision mediump float;
4 | uniform int vColorType;
5 | varying vec2 vTextureCoord;
6 | uniform int vArraysSize;
7 | uniform vec3 vChangeColor;
8 | uniform vec3 vChangeColorB;
9 | uniform vec3 vChangeColorC;
10 |
11 | float debugFloatA;
12 | float debugFloatB;
13 |
14 | void main()
15 | {
16 | vec4 vCameraColor = texture2D(uTextureSampler, vTextureCoord);
17 | gl_FragColor = vec4(vCameraColor.r, vCameraColor.g, vCameraColor.b, 1.0);
18 | for(int i = 0;i
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 | #FF03A9F4
8 | #44a7d4
9 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | SunCamera
3 | 启动服务器
4 | 停止服务器
5 | 在浏览器中打开
6 |
7 | 服务器停止了
8 | 没有获取到服务器IP地址
9 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/file_paths.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/test/java/camera/cn/cameramaster/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package camera.cn.cameramaster;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 |
5 | repositories {
6 | google()
7 | jcenter()
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:4.0.2'
11 | // classpath 'com.jakewharton:butterknife-gradle-plugin:8.4.0'
12 |
13 | // NOTE: Do not place your application dependencies here; they belong
14 | // in the individual module build.gradle files
15 | }
16 | }
17 |
18 | allprojects {
19 | repositories {
20 | google()
21 | jcenter()
22 | maven { url "https://jitpack.io" }
23 | maven { url 'https://maven.google.com' }
24 | }
25 | }
26 |
27 | task clean(type: Delete) {
28 | delete rootProject.buildDir
29 | }
30 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 | android.enableAapt2=true
19 | android.useAndroidX=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yangmingchuan/CameraMaster/5340823cd85fea2c819b096efaeb7baa27707c46/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Dec 09 09:54:58 CST 2020
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------