Full Code of yangmingchuan/CameraMaster for AI

master 5340823cd85f cached
103 files
501.9 KB
125.0k tokens
735 symbols
1 requests
Download .txt
Showing preview only (555K chars total). Download the full file or copy to clipboard to get everything.
Repository: yangmingchuan/CameraMaster
Branch: master
Commit: 5340823cd85f
Files: 103
Total size: 501.9 KB

Directory structure:
gitextract_43xg_rh9/

├── .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
│       │   │       ├── 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/
│       │       │   ├── ic_camera.xml
│       │       │   ├── ic_fouces.xml
│       │       │   ├── ic_launcher_background.xml
│       │       │   └── ic_launcher_camera.xml
│       │       ├── drawable-v24/
│       │       │   └── ic_launcher_foreground.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-xhdpi/
│       │       │   ├── ic_launcher_background.xml
│       │       │   └── icon_back.xml
│       │       ├── 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/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
└── settings.gradle

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
.externalNativeBuild


================================================
FILE: .idea/codeStyles/Project.xml
================================================
<component name="ProjectCodeStyleConfiguration">
  <code_scheme name="Project" version="173">
    <codeStyleSettings language="XML">
      <indentOptions>
        <option name="CONTINUATION_INDENT_SIZE" value="4" />
      </indentOptions>
      <arrangement>
        <rules>
          <section>
            <rule>
              <match>
                <AND>
                  <NAME>xmlns:android</NAME>
                  <XML_ATTRIBUTE />
                  <XML_NAMESPACE>^$</XML_NAMESPACE>
                </AND>
              </match>
            </rule>
          </section>
          <section>
            <rule>
              <match>
                <AND>
                  <NAME>xmlns:.*</NAME>
                  <XML_ATTRIBUTE />
                  <XML_NAMESPACE>^$</XML_NAMESPACE>
                </AND>
              </match>
              <order>BY_NAME</order>
            </rule>
          </section>
          <section>
            <rule>
              <match>
                <AND>
                  <NAME>.*:id</NAME>
                  <XML_ATTRIBUTE />
                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
                </AND>
              </match>
            </rule>
          </section>
          <section>
            <rule>
              <match>
                <AND>
                  <NAME>.*:name</NAME>
                  <XML_ATTRIBUTE />
                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
                </AND>
              </match>
            </rule>
          </section>
          <section>
            <rule>
              <match>
                <AND>
                  <NAME>name</NAME>
                  <XML_ATTRIBUTE />
                  <XML_NAMESPACE>^$</XML_NAMESPACE>
                </AND>
              </match>
            </rule>
          </section>
          <section>
            <rule>
              <match>
                <AND>
                  <NAME>style</NAME>
                  <XML_ATTRIBUTE />
                  <XML_NAMESPACE>^$</XML_NAMESPACE>
                </AND>
              </match>
            </rule>
          </section>
          <section>
            <rule>
              <match>
                <AND>
                  <NAME>.*</NAME>
                  <XML_ATTRIBUTE />
                  <XML_NAMESPACE>^$</XML_NAMESPACE>
                </AND>
              </match>
              <order>BY_NAME</order>
            </rule>
          </section>
          <section>
            <rule>
              <match>
                <AND>
                  <NAME>.*</NAME>
                  <XML_ATTRIBUTE />
                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
                </AND>
              </match>
              <order>ANDROID_ATTRIBUTE_ORDER</order>
            </rule>
          </section>
          <section>
            <rule>
              <match>
                <AND>
                  <NAME>.*</NAME>
                  <XML_ATTRIBUTE />
                  <XML_NAMESPACE>.*</XML_NAMESPACE>
                </AND>
              </match>
              <order>BY_NAME</order>
            </rule>
          </section>
        </rules>
      </arrangement>
    </codeStyleSettings>
  </code_scheme>
</component>

================================================
FILE: .idea/gradle.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="GradleMigrationSettings" migrationVersion="1" />
  <component name="GradleSettings">
    <option name="linkedExternalProjectsSettings">
      <GradleProjectSettings>
        <option name="testRunner" value="PLATFORM" />
        <option name="distributionType" value="DEFAULT_WRAPPED" />
        <option name="externalProjectPath" value="$PROJECT_DIR$" />
        <option name="modules">
          <set>
            <option value="$PROJECT_DIR$" />
            <option value="$PROJECT_DIR$/app" />
          </set>
        </option>
        <option name="resolveModulePerSourceSet" value="false" />
      </GradleProjectSettings>
    </option>
  </component>
</project>

================================================
FILE: .idea/inspectionProfiles/Project_Default.xml
================================================
<component name="InspectionProjectProfileManager">
  <profile version="1.0">
    <option name="myName" value="Project Default" />
    <inspection_tool class="JavaDoc" enabled="true" level="WARNING" enabled_by_default="true">
      <option name="TOP_LEVEL_CLASS_OPTIONS">
        <value>
          <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
          <option name="REQUIRED_TAGS" value="" />
        </value>
      </option>
      <option name="INNER_CLASS_OPTIONS">
        <value>
          <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
          <option name="REQUIRED_TAGS" value="" />
        </value>
      </option>
      <option name="METHOD_OPTIONS">
        <value>
          <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
          <option name="REQUIRED_TAGS" value="@return@param@throws or @exception" />
        </value>
      </option>
      <option name="FIELD_OPTIONS">
        <value>
          <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
          <option name="REQUIRED_TAGS" value="" />
        </value>
      </option>
      <option name="IGNORE_DEPRECATED" value="false" />
      <option name="IGNORE_JAVADOC_PERIOD" value="true" />
      <option name="IGNORE_DUPLICATED_THROWS" value="false" />
      <option name="IGNORE_POINT_TO_ITSELF" value="false" />
      <option name="myAdditionalJavadocTags" value="date,fileName:,date:,author:,QQ:745612618,packageName:" />
    </inspection_tool>
  </profile>
</component>

================================================
FILE: .idea/jarRepositories.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="RemoteRepositoriesConfiguration">
    <remote-repository>
      <option name="id" value="central" />
      <option name="name" value="Maven Central repository" />
      <option name="url" value="https://repo1.maven.org/maven2" />
    </remote-repository>
    <remote-repository>
      <option name="id" value="jboss.community" />
      <option name="name" value="JBoss Community repository" />
      <option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
    </remote-repository>
    <remote-repository>
      <option name="id" value="maven2" />
      <option name="name" value="maven2" />
      <option name="url" value="https://maven.google.com" />
    </remote-repository>
    <remote-repository>
      <option name="id" value="BintrayJCenter" />
      <option name="name" value="BintrayJCenter" />
      <option name="url" value="https://jcenter.bintray.com/" />
    </remote-repository>
    <remote-repository>
      <option name="id" value="maven" />
      <option name="name" value="maven" />
      <option name="url" value="https://jitpack.io" />
    </remote-repository>
    <remote-repository>
      <option name="id" value="Google" />
      <option name="name" value="Google" />
      <option name="url" value="https://dl.google.com/dl/android/maven2/" />
    </remote-repository>
    <remote-repository>
      <option name="id" value="$USER_HOME$/Library/Android/sdk/extras/google/m2repository" />
      <option name="name" value="$USER_HOME$/Library/Android/sdk/extras/google/m2repository" />
      <option name="url" value="file:$USER_HOME$/Library/Android/sdk/extras/google/m2repository/" />
    </remote-repository>
    <remote-repository>
      <option name="id" value="$USER_HOME$/Library/Android/sdk/extras/m2repository" />
      <option name="name" value="$USER_HOME$/Library/Android/sdk/extras/m2repository" />
      <option name="url" value="file:$USER_HOME$/Library/Android/sdk/extras/m2repository/" />
    </remote-repository>
    <remote-repository>
      <option name="id" value="$USER_HOME$/Library/Android/sdk/extras/android/m2repository" />
      <option name="name" value="$USER_HOME$/Library/Android/sdk/extras/android/m2repository" />
      <option name="url" value="file:$USER_HOME$/Library/Android/sdk/extras/android/m2repository/" />
    </remote-repository>
  </component>
</project>

================================================
FILE: .idea/misc.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="ASMPluginConfiguration">
    <asm skipDebug="false" skipFrames="false" skipCode="false" expandFrames="false" />
    <groovy codeStyle="LEGACY" />
  </component>
  <component name="NullableNotNullManager">
    <option name="myDefaultNullable" value="android.support.annotation.Nullable" />
    <option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
    <option name="myNullables">
      <value>
        <list size="12">
          <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
          <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
          <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
          <item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
          <item index="4" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
          <item index="5" class="java.lang.String" itemvalue="androidx.annotation.Nullable" />
          <item index="6" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNullable" />
          <item index="7" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.qual.Nullable" />
          <item index="8" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableDecl" />
          <item index="9" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableType" />
          <item index="10" class="java.lang.String" itemvalue="android.annotation.Nullable" />
          <item index="11" class="java.lang.String" itemvalue="com.android.annotations.Nullable" />
        </list>
      </value>
    </option>
    <option name="myNotNulls">
      <value>
        <list size="11">
          <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
          <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
          <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
          <item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
          <item index="4" class="java.lang.String" itemvalue="androidx.annotation.NonNull" />
          <item index="5" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNonNull" />
          <item index="6" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.qual.NonNull" />
          <item index="7" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullDecl" />
          <item index="8" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullType" />
          <item index="9" class="java.lang.String" itemvalue="android.annotation.NonNull" />
          <item index="10" class="java.lang.String" itemvalue="com.android.annotations.NonNull" />
        </list>
      </value>
    </option>
  </component>
  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
    <output url="file://$PROJECT_DIR$/build/classes" />
  </component>
  <component name="ProjectType">
    <option name="id" value="Android" />
  </component>
  <component name="masterDetails">
    <states>
      <state key="ProjectJDKs.UI">
        <settings>
          <last-edited>1.8</last-edited>
          <splitter-proportions>
            <option name="proportions">
              <list>
                <option value="0.2" />
              </list>
            </option>
          </splitter-proportions>
        </settings>
      </state>
    </states>
  </component>
</project>

================================================
FILE: .idea/modules.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="ProjectModuleManager">
    <modules>
      <module fileurl="file://$PROJECT_DIR$/CameraMaster.iml" filepath="$PROJECT_DIR$/CameraMaster.iml" />
      <module fileurl="file://$PROJECT_DIR$/.idea/modules/app/CameraMaster-app.iml" filepath="$PROJECT_DIR$/.idea/modules/app/CameraMaster-app.iml" group="CameraMaster/app" />
      <module fileurl="file://$PROJECT_DIR$/.idea/modules/camerax/CameraMaster-camerax.iml" filepath="$PROJECT_DIR$/.idea/modules/camerax/CameraMaster-camerax.iml" group="CameraMaster/camerax" />
      <module fileurl="file://$PROJECT_DIR$/.idea/modules/Downloads-githubwork-CameraMaster.iml" filepath="$PROJECT_DIR$/.idea/modules/Downloads-githubwork-CameraMaster.iml" group="CameraMaster" />
      <module fileurl="file://$PROJECT_DIR$/.idea/modules/app/Downloads-githubwork-CameraMaster-app.iml" filepath="$PROJECT_DIR$/.idea/modules/app/Downloads-githubwork-CameraMaster-app.iml" group="CameraMaster/app" />
      <module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
      <module fileurl="file://$PROJECT_DIR$/.idea/modules/app/camerax/camerax.iml" filepath="$PROJECT_DIR$/.idea/modules/app/camerax/camerax.iml" group="CameraMaster/app/camerax" />
      <module fileurl="file://$PROJECT_DIR$/.idea/modules/githubwork-CameraMaster.iml" filepath="$PROJECT_DIR$/.idea/modules/githubwork-CameraMaster.iml" group="CameraMaster" />
      <module fileurl="file://$PROJECT_DIR$/.idea/modules/app/githubwork-CameraMaster-app.iml" filepath="$PROJECT_DIR$/.idea/modules/app/githubwork-CameraMaster-app.iml" group="CameraMaster/app" />
      <module fileurl="file://$PROJECT_DIR$/.idea/modules/yangmingchuan-Downloads-githubwork-CameraMaster.iml" filepath="$PROJECT_DIR$/.idea/modules/yangmingchuan-Downloads-githubwork-CameraMaster.iml" group="CameraMaster" />
    </modules>
  </component>
</project>

================================================
FILE: .idea/runConfigurations.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="RunConfigurationProducerService">
    <option name="ignoredProducers">
      <set>
        <option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
      </set>
    </option>
  </component>
</project>

================================================
FILE: .idea/vcs.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="VcsDirectoryMappings">
    <mapping directory="$PROJECT_DIR$" vcs="Git" />
  </component>
</project>

================================================
FILE: README.md
================================================
# SunCamera

一个 学习自定义的 Camera1 、Camera2 、Camera X 和 OpenglES 的Demo

# 版本迭代
 
 -  1.3 完善部分bug (暂时停止维护,抽空整理成底层SDK,相对架构来一次深度的学习)
 -  1.2 添加 拍照录像及硬件设备信息调节界面
 -  1.1 添加 Camera 2 相机使用界面
 -  1.0 添加 Camera 1 相机使用界面

# 感谢

https://github.com/chensowf/Camera   录像代码部分参考和学习。感谢开源


# 效果图

1. 目前 拍照 摄像界面 效果界面主要 在 CameraVideoActivity 界面中。

![image](https://github.com/yangmingchuan/CameraMaster/blob/5d92dda84ff32038e7abe94a7a15c40eea7f1a66/app/src/main/res/drawable-v24/64F105A2D530CDE27A0F21CBC6C0B877.gif)

2.camera+surfaceview 博客地址:https://www.jianshu.com/p/af39024896ce

![image](https://upload-images.jianshu.io/upload_images/6188347-cd61d9a329522b0a?imageMogr2/auto-orient/)


3. camera2 + TextureView   博客地址 : https://www.jianshu.com/p/c99fd9dfd77f

4. camera2 + glSurfaceview  + opengles  博客地址 : https://www.jianshu.com/p/e4ece3f21ec8

![image](https://img-blog.csdnimg.cn/2019040210145280.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI3OTQ4NjU5,size_16,color_FFFFFF,t_70)



================================================
FILE: app/.gitignore
================================================
/build


================================================
FILE: app/build.gradle
================================================
apply plugin: 'com.android.application'

android {
    compileSdkVersion 27
    defaultConfig {
        applicationId "camera.cn.cameramaster"
        minSdkVersion 17
        targetSdkVersion 27
        versionCode 103
        versionName "1.0.3"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        debug {
            debuggable true
            zipAlignEnabled false
            minifyEnabled false
            shrinkResources false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }

        release {
            debuggable false
            zipAlignEnabled true
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    buildToolsVersion '27.0.3'
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    implementation 'com.android.support:cardview-v7:27.1.1'
    implementation 'com.android.support:recyclerview-v7:27.1.1'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    // butterknife
    implementation 'com.jakewharton:butterknife:8.8.1'
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
    // permission
    implementation 'com.yanzhenjie:permission:2.0.0-rc4'
    implementation 'com.android.support:exifinterface:27.1.1'
    // api
    implementation 'com.yanzhenjie.andserver:api:2.0.4'
    annotationProcessor 'com.yanzhenjie.andserver:processor:2.0.4'
    // load json
    implementation 'com.alibaba:fastjson:1.2.48'
    implementation 'com.yanzhenjie:loading:1.0.0'
    // event bus
    implementation 'org.greenrobot:eventbus:3.1.1'

    api "io.reactivex.rxjava2:rxjava:2.1.0"
    api "io.reactivex.rxjava2:rxandroid:2.1.0"
}


================================================
FILE: app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile


================================================
FILE: app/src/androidTest/java/camera/cn/cameramaster/ExampleInstrumentedTest.java
================================================
package camera.cn.cameramaster;

import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;

import static org.junit.Assert.*;

/**
 * Instrumented test, which will execute on an Android device.
 *
 * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
 */
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
    @Test
    public void useAppContext() throws Exception {
        // Context of the app under test.
        Context appContext = InstrumentationRegistry.getTargetContext();

        assertEquals("camera.cn.cameramaster", appContext.getPackageName());
    }
}


================================================
FILE: app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="camera.cn.cameramaster">

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.FLASHLIGHT" />

    <uses-permission android:name="android.permission.MODIFY_PHONE_STATE"
        tools:ignore="ProtectedPermissions" />

    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />

    <application
        android:name=".base.App"
        android:allowBackup="true"
        android:hardwareAccelerated="true"
        android:icon="@drawable/ic_launcher_camera"
        android:label="@string/app_name"
        android:largeHeap="true"
        android:roundIcon="@drawable/ic_launcher_camera"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <!-- 首页 -->
        <activity android:name=".ui.MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
                <!-- 设置为开机显示应用 -->
                <!-- <category android:name="android.intent.category.HOME" /> -->
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.MONKEY" />
            </intent-filter>
        </activity>

        <!-- 5.0- 拍照界面 -->
        <activity android:name=".ui.CameraActivity" />

        <!-- 显示图像界面 -->
        <activity android:name=".ui.ShowPicActivity" />

        <!-- 开机广播接受者 -->
        <receiver android:name=".OpenReceiver">
            <intent-filter>

                <!-- 注册开机广播地址 -->
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>

        <activity android:name=".ui.Camera2Activity" />
        <activity android:name=".ui.GoogleCameraActivity"></activity>
        <activity android:name=".ui.CameraSurfaceViewActivity"></activity>

        <service
            android:name=".server.CoreService"
            android:exported="false" />

        <activity android:name=".ui.CameraVideoActivity"></activity>

        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="${applicationId}.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>
    </application>

</manifest>

================================================
FILE: app/src/main/assets/web/css/login.css
================================================
.sec_body { color:#404040;background:#EBEBEB;text-shadow:#ddd 0 1px 0px;font-family:Helvetica;line-height:1.5;font-size:small; }
.center_father {color:#404040;text-align: center;}
.center_son { margin-right: auto; margin-left: auto; }

================================================
FILE: app/src/main/assets/web/index.html
================================================
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
    <meta name="format-detection" content="telephone=no"/>
    <title>AndServer Sample</title>
    <style>
        .center_horizontal{margin:0 auto;text-align:center;}
    </style>
</head>
<body>
<div class="center_horizontal"><img src="./image/logo.png" width="100%"></div>
<div>
    <a href="/login.html">Login</a><br/><br/>
    More, please see the sample code.
</div>
</body>
</html>

================================================
FILE: app/src/main/assets/web/login.html
================================================
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
    <meta name="format-detection" content="telephone=no"/>
    <link rel="stylesheet" type="text/css" href="css/login.css">

    <title>Sign In</title>

</head>
<body class="sec_body">
<div class="center_father">
    <h1 class="center" style="margin:0 0;font-size:x-large;padding:0;">Sign In</h1>
</div>
<form id="form1" method="post" action="/user/login">
    <table align="center" cellpadding="0" cellspacing="0">
        <tr>
            <td width="100" align="right">Account:&nbsp;&nbsp;</td>
            <td width="276"><input name="account" type="text" id="account" value="123"/></td>
        </tr>
        <tr>
            <td width="100">&nbsp;&nbsp;</td>
            <td width="276">&nbsp;&nbsp;</td>
        </tr>
        <tr>
            <td align="right">Password:&nbsp;&nbsp;</td>
            <td><input name="password" type="password" id="password" value="123"/></td>
        </tr>
        <tr>
            <td width="100">&nbsp;&nbsp;</td>
            <td width="276">&nbsp;&nbsp;</td>
        </tr>
        <tr>
            <td colspan="2" align="center">
                <input type="submit" name="Submit" value="Sign In"/>
            </td>
        </tr>
    </table>
    <p>Account:&nbsp;123, Password:&nbsp;123</p>
</form>
</body>
</html>


================================================
FILE: app/src/main/java/camera/cn/cameramaster/OpenReceiver.java
================================================
package camera.cn.cameramaster;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

import camera.cn.cameramaster.ui.MainActivity;

/**
 * 开机
 * @packageName: cn.tongue.tonguecamera
 * @fileName: OpenReceiver
 * @date: 2019/1/28  13:09
 * @author: ymc
 * @QQ:745612618
 */

public class OpenReceiver  extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {

        Log.i("broadCastReceiver","onReceiver...");

        Intent mBootIntent = new Intent(context, MainActivity.class);
        // 必须设置FLAG_ACTIVITY_NEW_TASK
        mBootIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(mBootIntent);

    }

}

================================================
FILE: app/src/main/java/camera/cn/cameramaster/adapter/EffectAdapter.java
================================================
package camera.cn.cameramaster.adapter;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import butterknife.BindView;
import butterknife.ButterKnife;
import camera.cn.cameramaster.R;

/**
 * effect 适配器
 *
 * @packageName: cn.tongue.tonguecamera.adapter
 * @fileName: EffectAdapter
 * @date: 2019/4/17  14:33
 * @author: ymc
 * @QQ:745612618
 */

public class EffectAdapter extends RecyclerView.Adapter<EffectAdapter.EffectViewHolder> {
    private LayoutInflater mLayoutInflater;
    private String[] effectArr;

    public EffectAdapter(Context mContext,String[] arr) {
        this.effectArr = arr;
        mLayoutInflater = LayoutInflater.from(mContext);
    }

    @NonNull
    @Override
    public EffectViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new EffectViewHolder(mLayoutInflater.inflate(R.layout.item_rv_text, parent, false));
    }

    @Override
    public void onBindViewHolder(@NonNull EffectViewHolder holder, int position) {
        holder.mTextView.setText(effectArr[position]);
    }

    @Override
    public int getItemCount() {
        return effectArr.length;
    }

    public class EffectViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        @BindView(R.id.text_view)
        TextView mTextView;

        EffectViewHolder(View view) {
            super(view);
            ButterKnife.bind(this, view);
            view.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {
            if (effectOnItemClickListener != null) {
                effectOnItemClickListener.itemOnClick(getPosition());
            }
        }
    }

    private EffectOnItemClickListener effectOnItemClickListener;

    public interface EffectOnItemClickListener {

        void itemOnClick(int position);

    }

    public void setEffectOnItemClickListener(EffectOnItemClickListener effectOnItemClickListener) {
        this.effectOnItemClickListener = effectOnItemClickListener;
    }
}


================================================
FILE: app/src/main/java/camera/cn/cameramaster/adapter/MenuAdapter.java
================================================
package camera.cn.cameramaster.adapter;

import android.content.Context;
import android.graphics.Color;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.List;

import camera.cn.cameramaster.R;
import camera.cn.cameramaster.view.AutoLocateHorizontalView;

/**
 * 选项适配器
 *
 * @author ymc
 * @date 2019年5月8日 10:38:54
 */

public class MenuAdapter extends RecyclerView.Adapter<MenuAdapter.ItemViewHolder>
        implements AutoLocateHorizontalView.IAutoLocateHorizontalView {
    private Context context;
    private View view;
    private List<String> ages;
    private AutoLocateHorizontalView recyclerView;

    public MenuAdapter(Context context, List<String> ages, AutoLocateHorizontalView recyclerView){
        this.context = context;
        this.ages = ages;
        this.recyclerView = recyclerView;
    }

    @NonNull
    @Override
    public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        view = LayoutInflater.from(context).inflate(R.layout.item_age,parent,false);
        return new ItemViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) {
        holder.tvAge.setText(ages.get(position));
    }

    @Override
    public int getItemCount() {
        return  ages.size();
    }

    @Override
    public View getItemView() {
        return view;
    }

    @Override
    public void onViewSelected(boolean isSelected, int pos, RecyclerView.ViewHolder holder, int itemWidth) {
        if(isSelected) {
            ((ItemViewHolder) holder).tvAge.setTextSize(TypedValue.COMPLEX_UNIT_SP,16);
            ((ItemViewHolder) holder).tvAge.setTextColor(Color.WHITE);
            ((ItemViewHolder) holder).tvAge.setAlpha(1.0f);
        }else{
            ((ItemViewHolder) holder).tvAge.setTextSize(TypedValue.COMPLEX_UNIT_SP,14);
            ((ItemViewHolder) holder).tvAge.setTextColor(Color.rgb(0xfe,0xfe,0xfe));
            ((ItemViewHolder) holder).tvAge.setAlpha(0.5f);
        }
    }

    class ItemViewHolder extends RecyclerView.ViewHolder{
        TextView tvAge;
        ItemViewHolder(View itemView) {
            super(itemView);
            tvAge = itemView.findViewById(R.id.tv_age);
            tvAge.setTag(this);
            tvAge.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    ItemViewHolder itemViewHolder = (ItemViewHolder)v.getTag();
                    int position = recyclerView.getChildAdapterPosition(itemViewHolder.itemView);
                    position--;
                    recyclerView.moveToPosition(position);
                }
            });
        }
    }
}


================================================
FILE: app/src/main/java/camera/cn/cameramaster/adapter/SenseAdapter.java
================================================
package camera.cn.cameramaster.adapter;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import butterknife.BindView;
import butterknife.ButterKnife;
import camera.cn.cameramaster.R;

/**
 * effect 适配器
 *
 * @packageName: cn.tongue.tonguecamera.adapter
 * @fileName: EffectAdapter
 * @date: 2019/4/17  14:33
 * @author: ymc
 * @QQ:745612618
 */

public class SenseAdapter extends RecyclerView.Adapter<SenseAdapter.EffectViewHolder> {
    private LayoutInflater mLayoutInflater;
    private String[] senseArr;

    public SenseAdapter(Context mContext,String[] arr) {
        this.senseArr = arr;
        mLayoutInflater = LayoutInflater.from(mContext);
    }

    @NonNull
    @Override
    public EffectViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new EffectViewHolder(mLayoutInflater.inflate(R.layout.item_rv_text, parent, false));
    }

    @Override
    public void onBindViewHolder(@NonNull EffectViewHolder holder, int position) {
        holder.mTextView.setText(senseArr[position]);
    }

    @Override
    public int getItemCount() {
        return senseArr.length;
    }

    public class EffectViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        @BindView(R.id.text_view)
        TextView mTextView;

        EffectViewHolder(View view) {
            super(view);
            ButterKnife.bind(this, view);
            view.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {
            if (senseOnItemClickListener != null) {
                senseOnItemClickListener.itemOnClick(getPosition());
            }
        }
    }

    private SenseOnItemClickListener senseOnItemClickListener;

    public interface SenseOnItemClickListener {

        void itemOnClick(int position);

    }

    public void setSenseOnItemClickListener(SenseOnItemClickListener senseOnItemClickListener) {
        this.senseOnItemClickListener = senseOnItemClickListener;
    }
}


================================================
FILE: app/src/main/java/camera/cn/cameramaster/base/App.java
================================================
/*
 * Copyright 2018 Yan Zhenjie.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package camera.cn.cameramaster.base;

import android.app.Application;
import android.content.Context;
import android.os.Environment;
import android.support.annotation.NonNull;

import com.yanzhenjie.andserver.util.IOUtils;

import java.io.File;

import camera.cn.cameramaster.server.util.FileUtils;


/**
 * application
 *
 * Created by YanZhenjie on 2018/6/9.
 * @author ymc
 */

public class App extends Application {

    private static App mInstance;

    private File mRootDir;

    @Override
    public void onCreate() {
        super.onCreate();

        if (mInstance == null) {
            mInstance = this;
            initRootPath(this);
        }
    }

    @NonNull
    public static App getInstance() {
        return mInstance;
    }

    @NonNull
    public File getRootDir() {
        return mRootDir;
    }

    private void initRootPath(Context context) {
        if (mRootDir != null) {
            return;
        }

        if (FileUtils.storageAvailable()) {
            mRootDir = Environment.getExternalStorageDirectory();
        } else {
            mRootDir = context.getFilesDir();
        }
        mRootDir = new File(mRootDir, "AndServer");
        IOUtils.createFolder(mRootDir);
    }
}

================================================
FILE: app/src/main/java/camera/cn/cameramaster/base/BaseActivity.java
================================================
package camera.cn.cameramaster.base;

import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.view.ViewCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;

import butterknife.ButterKnife;
import butterknife.Unbinder;
import camera.cn.cameramaster.R;

/**
 *  基础Activity
 *
 * @packageName: cn.ymc.vip.suntimejava.base
 * @fileName: BaseActivity
 * @date: 2019/1/8  17:35
 * @author: ymc
 * @QQ:745612618
 */

public abstract class BaseActivity extends AppCompatActivity {

    protected BaseActivity activity;
    private Unbinder bun;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //去除标题栏
        supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
        //去除状态栏
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(getLayoutId());
//        getSupportActionBar().hide();
        bun = ButterKnife.bind(this);
        activity = this;
        initStatusColor();
        initView();
        initData();
    }

    /**
     * 设置透明状态栏,这样才能让 ContentView 向上  6.0小米手机设置 tootlbar 会被挤上去
     * window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
     */
    private void initStatusColor() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
            Window window = activity.getWindow();
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            //设置状态栏颜色
            window.setStatusBarColor(getColor(R.color.theme));

            ViewGroup mContentView = activity.findViewById(Window.ID_ANDROID_CONTENT);
            View mChildView = mContentView.getChildAt(0);
            if (mChildView != null) {
                //注意不是设置 ContentView 的 FitsSystemWindows, 而是设置 ContentView 的第一个子 View . 使其不为系统 View 预留空间.
                ViewCompat.setFitsSystemWindows(mChildView, false);
            }
        }
    }

    protected abstract int getLayoutId();
    protected abstract void initView();
    protected abstract void initData();

    @Override
    protected void onDestroy() {
        bun.unbind();
        super.onDestroy();
    }
}


================================================
FILE: app/src/main/java/camera/cn/cameramaster/bean/Lab.java
================================================
package camera.cn.cameramaster.bean;

/**
 * lab 实体类
 *
 * @packageName: cn.tongue.tonguecamera.bean
 * @fileName: Lab
 * @date: 2019/4/3  13:37
 * @author: ymc
 * @QQ:745612618
 */

public class Lab {

    public double L;
    public double a;
    public double b;

    public double getL() {
        return L;
    }

    public void setL(double l) {
        L = l;
    }

    public double getA() {
        return a;
    }

    public void setA(double a) {
        this.a = a;
    }

    public double getB() {
        return b;
    }

    public void setB(double b) {
        this.b = b;
    }

    @Override
    public String toString() {
        return "Lab l:" + L + " Lab a:" + a + " Lab b:" + b;
    }
}


================================================
FILE: app/src/main/java/camera/cn/cameramaster/filter/AFilter.java
================================================
/*
 *
 * AFilter.java
 * 
 * Created by Wuwang on 2016/11/19
 * Copyright © 2016年 深圳哎吖科技. All rights reserved.
 */
package camera.cn.cameramaster.filter;

import android.content.res.Resources;
import android.opengl.GLES20;
import android.util.Log;
import android.util.SparseArray;

import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import java.util.Arrays;

import camera.cn.cameramaster.util.MatrixUtils;


/**
 * Description:
 */
public abstract class AFilter {

    private static final String TAG="Filter";

    public static final int KEY_OUT=0x101;
    public static final int KEY_IN=0x102;
    public static final int KEY_INDEX=0x201;

    public static boolean DEBUG=true;
    /**
     * 单位矩阵
     */
    public static final float[] OM= MatrixUtils.getOriginalMatrix();
    /**
     * 程序句柄
     */
    protected int mProgram;
    /**
     * 顶点坐标句柄
     */
    protected int mHPosition;
    /**
     * 纹理坐标句柄
     */
    protected int mHCoord;
    /**
     * 总变换矩阵句柄
     */
    protected int mHMatrix;
    /**
     * 默认纹理贴图句柄
     */
    protected int mHTexture;

    protected Resources mRes;


    /**
     * 顶点坐标Buffer
     */
    protected FloatBuffer mVerBuffer;

    /**
     * 纹理坐标Buffer
     */
    protected FloatBuffer mTexBuffer;

    /**
     * 索引坐标Buffer
     */
    protected ShortBuffer mindexBuffer;

    protected int mFlag=0;

    private float[] matrix= Arrays.copyOf(OM,16);

    private int textureType=0;      //默认使用Texture2D0
    private int textureId=0;
    //顶点坐标
    private float pos[] = {
        -1.0f,  1.0f,
        -1.0f, -1.0f,
        1.0f, 1.0f,
        1.0f,  -1.0f,
    };

    //纹理坐标
    private float[] coord={
        0.0f, 0.0f,
        0.0f,  1.0f,
        1.0f,  0.0f,
        1.0f, 1.0f,
    };

    private SparseArray<boolean[]> mBools;
    private SparseArray<int[]> mInts;
    private SparseArray<float[]> mFloats;

    public AFilter(Resources mRes){
        this.mRes=mRes;
        initBuffer();
    }

    public final void create(){
        onCreate();
    }

    public final void setSize(int width,int height){
        onSizeChanged(width,height);
    }

    public void draw(){
        onClear();
        onUseProgram();
        onSetExpandData();
        onBindTexture();
        onDraw();
    }

    public void setMatrix(float[] matrix){
        this.matrix=matrix;
    }

    public float[] getMatrix(){
        return matrix;
    }

    public final void setTextureType(int type){
        this.textureType=type;
    }

    public final int getTextureType(){
        return textureType;
    }

    public final int getTextureId(){
        return textureId;
    }

    public final void setTextureId(int textureId){
        this.textureId=textureId;
    }

    public void setFlag(int flag){
        this.mFlag=flag;
    }

    public int getFlag(){
        return mFlag;
    }

    public void setFloat(int type,float ... params){
        if(mFloats==null){
            mFloats=new SparseArray<>();
        }
        mFloats.put(type,params);
    }
    public void setInt(int type,int ... params){
        if(mInts==null){
            mInts=new SparseArray<>();
        }
        mInts.put(type,params);
    }
    public void setBool(int type,boolean ... params){
        if(mBools==null){
            mBools=new SparseArray<>();
        }
        mBools.put(type,params);
    }

    public boolean getBool(int type,int index) {
        if (mBools == null){
            return false;
        }
        boolean[] b = mBools.get(type);
        return !(b == null || b.length <= index) && b[index];
    }

    public int getInt(int type,int index){
        if (mInts == null){
            return 0;
        }
        int[] b = mInts.get(type);
        if(b == null || b.length <= index){
            return 0;
        }
        return b[index];
    }

    public float getFloat(int type,int index){
        if (mFloats == null) {
            return 0;
        }
        float[] b = mFloats.get(type);
        if(b == null || b.length <= index){
            return 0;
        }
        return b[index];
    }

    public int getOutputTexture(){
        return -1;
    }

    /**
     * 实现此方法,完成程序的创建,可直接调用createProgram来实现
     */
    protected abstract void onCreate();
    protected abstract void onSizeChanged(int width,int height);

    protected final void createProgram(String vertex, String fragment){
        mProgram= uCreateGlProgram(vertex,fragment);
        mHPosition= GLES20.glGetAttribLocation(mProgram, "vPosition");
        mHCoord= GLES20.glGetAttribLocation(mProgram,"vCoord");
        mHMatrix= GLES20.glGetUniformLocation(mProgram,"vMatrix");
        mHTexture= GLES20.glGetUniformLocation(mProgram,"vTexture");
    }

    protected final void createProgramByAssetsFile(String vertex, String fragment){
        createProgram(uRes(mRes,vertex),uRes(mRes,fragment));
    }

    /**
     * Buffer初始化
     */
    protected void initBuffer(){
        ByteBuffer a= ByteBuffer.allocateDirect(32);
        a.order(ByteOrder.nativeOrder());
        mVerBuffer=a.asFloatBuffer();
        mVerBuffer.put(pos);
        mVerBuffer.position(0);
        ByteBuffer b= ByteBuffer.allocateDirect(32);
        b.order(ByteOrder.nativeOrder());
        mTexBuffer=b.asFloatBuffer();
        mTexBuffer.put(coord);
        mTexBuffer.position(0);
    }

    protected void onUseProgram(){
        GLES20.glUseProgram(mProgram);
    }

    /**
     * 启用顶点坐标和纹理坐标进行绘制
     */
    protected void onDraw(){
        GLES20.glEnableVertexAttribArray(mHPosition);
        GLES20.glVertexAttribPointer(mHPosition,2, GLES20.GL_FLOAT, false, 0,mVerBuffer);
        GLES20.glEnableVertexAttribArray(mHCoord);
        GLES20.glVertexAttribPointer(mHCoord, 2, GLES20.GL_FLOAT, false, 0, mTexBuffer);
        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP,0,4);
        GLES20.glDisableVertexAttribArray(mHPosition);
        GLES20.glDisableVertexAttribArray(mHCoord);
    }

    /**
     * 清除画布
     */
    protected void onClear(){
        GLES20.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
    }

    /**
     * 设置其他扩展数据
     */
    protected void onSetExpandData(){
        GLES20.glUniformMatrix4fv(mHMatrix,1,false,matrix,0);
    }

    /**
     * 绑定默认纹理
     */
    protected void onBindTexture(){
        GLES20.glActiveTexture(GLES20.GL_TEXTURE0+textureType);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,getTextureId());
        GLES20.glUniform1i(mHTexture,textureType);
    }

    public static void glError(int code,Object index){
        if(DEBUG&&code!=0){
            Log.e(TAG,"glError:"+code+"---"+index);
        }
    }

    //通过路径加载Assets中的文本内容
    public static String uRes(Resources mRes, String path){
        StringBuilder result=new StringBuilder();
        try{
            InputStream is=mRes.getAssets().open(path);
            int ch;
            byte[] buffer=new byte[1024];
            while (-1!=(ch=is.read(buffer))){
                result.append(new String(buffer,0,ch));
            }
        }catch (Exception e){
            return null;
        }
        return result.toString().replaceAll("\\r\\n","\n");
    }

    //创建GL程序
    public static int uCreateGlProgram(String vertexSource, String fragmentSource){
        int vertex=uLoadShader(GLES20.GL_VERTEX_SHADER,vertexSource);
        if(vertex==0){
            return 0;
        }
        int fragment=uLoadShader(GLES20.GL_FRAGMENT_SHADER,fragmentSource);
        if(fragment==0){
            return 0;
        }
        int program= GLES20.glCreateProgram();
        if(program!=0){
            GLES20.glAttachShader(program,vertex);
            GLES20.glAttachShader(program,fragment);
            GLES20.glLinkProgram(program);
            int[] linkStatus=new int[1];
            GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS,linkStatus,0);
            if(linkStatus[0]!= GLES20.GL_TRUE){
                glError(1,"Could not link program:"+ GLES20.glGetProgramInfoLog(program));
                GLES20.glDeleteProgram(program);
                program=0;
            }
        }
        return program;
    }

    //加载shader
    public static int uLoadShader(int shaderType,String source){
        int shader= GLES20.glCreateShader(shaderType);
        if(0!=shader){
            GLES20.glShaderSource(shader,source);
            GLES20.glCompileShader(shader);
            int[] compiled=new int[1];
            GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS,compiled,0);
            if(compiled[0]==0){
                glError(1,"Could not compile shader:"+shaderType);
                glError(1,"GLES20 Error:"+ GLES20.glGetShaderInfoLog(shader));
                GLES20.glDeleteShader(shader);
                shader=0;
            }
        }
        return shader;
    }


}


================================================
FILE: app/src/main/java/camera/cn/cameramaster/filter/TextureFilter.java
================================================
package camera.cn.cameramaster.filter;

import android.content.res.Resources;
import android.graphics.SurfaceTexture;

import java.nio.ByteBuffer;

/**
 * @packageName: cn.tongue.tonguecamera.filter
 * @fileName: TextureFilter
 * @date: 2019/3/15  14:40
 * @author: ymc
 * @QQ:745612618
 */

public class TextureFilter extends  AFilter{
    private int width=0;
    private int height=0;

    private int[] fFrame = new int[1];
    private int[] fTexture = new int[1];
    private int[] mCameraTexture=new int[1];

    private SurfaceTexture mSurfaceTexture;
    private float[] mCoordOM=new float[16];
    /**
     * 获取Track数据
     */
    private ByteBuffer tBuffer;


    public TextureFilter(Resources mRes) {
        super(mRes);
    }

    @Override
    protected void onCreate() {

    }

    @Override
    protected void onSizeChanged(int width, int height) {

    }
}


================================================
FILE: app/src/main/java/camera/cn/cameramaster/server/AnyEventType.java
================================================
package camera.cn.cameramaster.server;

/**
 * event bus 消息类
 *
 * @packageName: cn.tongue.tonguecamera.eventbus
 * @fileName: AnyEventType
 * @date: 2019/4/24  18:36
 * @author: ymc
 * @QQ:745612618
 */

public class AnyEventType {

    public AnyEventType(){}

}


================================================
FILE: app/src/main/java/camera/cn/cameramaster/server/CoreService.java
================================================
/*
 * Copyright © 2018 Yan Zhenjie.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package camera.cn.cameramaster.server;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;

import com.yanzhenjie.andserver.AndServer;
import com.yanzhenjie.andserver.Server;

import java.util.concurrent.TimeUnit;

import camera.cn.cameramaster.server.util.NetUtils;


/**
 * server
 *
 * Created by Yan Zhenjie on 2018/6/9.
 * @author ymc
 */
public class CoreService extends Service {
    private static final String TAG = "CoreService";
    private Server mServer;

    @Override
    public void onCreate() {
        mServer = AndServer.serverBuilder()
            .inetAddress(NetUtils.getLocalIPAddress())
            .port(8081)
            .timeout(10, TimeUnit.SECONDS)
            .listener(new Server.ServerListener() {
                @Override
                public void onStarted() {
                    String hostAddress = mServer.getInetAddress().getHostAddress();
                    ServerManager.onServerStart(CoreService.this, hostAddress);
                    Log.e(TAG, "onStarted: ");
                }

                @Override
                public void onStopped() {
                    ServerManager.onServerStop(CoreService.this);
                    Log.e(TAG, "onStopped: ");
                }

                @Override
                public void onException(Exception e) {
                    ServerManager.onServerError(CoreService.this, e.getMessage());
                    Log.e(TAG, "onException: ");
                }
            })
            .build();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        startServer();
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        stopServer();
        super.onDestroy();
    }

    /**
     * Start server.
     */
    private void startServer() {
        if (mServer.isRunning()) {
            String hostAddress = mServer.getInetAddress().getHostAddress();
            ServerManager.onServerStart(CoreService.this, hostAddress);
        } else {
            mServer.startup();
        }
    }

    /**
     * Stop server.
     */
    private void stopServer() {
        mServer.shutdown();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

================================================
FILE: app/src/main/java/camera/cn/cameramaster/server/ServerManager.java
================================================
/*
 * Copyright © 2018 Yan Zhenjie.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package camera.cn.cameramaster.server;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.support.annotation.RequiresApi;

import camera.cn.cameramaster.ui.GoogleCameraActivity;


/**
 *
 * Created by Yan Zhenjie on 2018/6/9.
 * @author ymc
 */

public class ServerManager extends BroadcastReceiver {

    private static final String ACTION = "com.yanzhenjie.andserver.receiver";

    private static final String CMD_KEY = "CMD_KEY";
    private static final String MESSAGE_KEY = "MESSAGE_KEY";

    private static final int CMD_VALUE_START = 1;
    private static final int CMD_VALUE_ERROR = 2;
    private static final int CMD_VALUE_STOP = 4;

    /**
     * Notify serverStart.
     *
     * @param context context.
     */
    public static void onServerStart(Context context, String hostAddress) {
        sendBroadcast(context, CMD_VALUE_START, hostAddress);
    }

    /**
     * Notify serverStop.
     *
     * @param context context.
     */
    public static void onServerError(Context context, String error) {
        sendBroadcast(context, CMD_VALUE_ERROR, error);
    }

    /**
     * Notify serverStop.
     *
     * @param context context.
     */
    public static void onServerStop(Context context) {
        sendBroadcast(context, CMD_VALUE_STOP);
    }

    private static void sendBroadcast(Context context, int cmd) {
        sendBroadcast(context, cmd, null);
    }

    private static void sendBroadcast(Context context, int cmd, String message) {
        Intent broadcast = new Intent(ACTION);
        broadcast.putExtra(CMD_KEY, cmd);
        broadcast.putExtra(MESSAGE_KEY, message);
        context.sendBroadcast(broadcast);
    }

    private GoogleCameraActivity mActivity;
    private Intent mService;

    public ServerManager(GoogleCameraActivity activity) {
        this.mActivity = activity;
        mService = new Intent(activity, CoreService.class);
    }

    /**
     * Register broadcast.
     */
    public void register() {
        IntentFilter filter = new IntentFilter(ACTION);
        mActivity.registerReceiver(this, filter);
    }

    /**
     * UnRegister broadcast.
     */
    public void unRegister() {
        mActivity.unregisterReceiver(this);
    }

    public void startServer() {
        mActivity.startService(mService);
    }

    public void stopServer() {
        mActivity.stopService(mService);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (ACTION.equals(action)) {
            int cmd = intent.getIntExtra(CMD_KEY, 0);
            switch (cmd) {
                case CMD_VALUE_START: {
                    String ip = intent.getStringExtra(MESSAGE_KEY);
                    mActivity.onServerStart(ip);
                    break;
                }
                case CMD_VALUE_ERROR: {
                    String error = intent.getStringExtra(MESSAGE_KEY);
                    mActivity.onServerError(error);
                    break;
                }
                case CMD_VALUE_STOP: {
                    mActivity.onServerStop();
                    break;
                }
                default:
                    break;
            }
        }
    }
}

================================================
FILE: app/src/main/java/camera/cn/cameramaster/server/TestController.java
================================================
package camera.cn.cameramaster.server;

import android.os.Build;
import android.support.annotation.RequiresApi;
import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.yanzhenjie.andserver.annotation.Addition;
import com.yanzhenjie.andserver.annotation.CookieValue;
import com.yanzhenjie.andserver.annotation.FormPart;
import com.yanzhenjie.andserver.annotation.GetMapping;
import com.yanzhenjie.andserver.annotation.PathVariable;
import com.yanzhenjie.andserver.annotation.PostMapping;
import com.yanzhenjie.andserver.annotation.RequestBody;
import com.yanzhenjie.andserver.annotation.RequestMapping;
import com.yanzhenjie.andserver.annotation.RequestParam;
import com.yanzhenjie.andserver.annotation.ResponseBody;
import com.yanzhenjie.andserver.annotation.RestController;
import com.yanzhenjie.andserver.http.HttpRequest;
import com.yanzhenjie.andserver.http.HttpResponse;
import com.yanzhenjie.andserver.http.cookie.Cookie;
import com.yanzhenjie.andserver.http.multipart.MultipartFile;
import com.yanzhenjie.andserver.http.session.Session;
import com.yanzhenjie.andserver.util.MediaType;

import org.greenrobot.eventbus.EventBus;

import java.io.File;
import java.io.IOException;
import java.util.List;

import camera.cn.cameramaster.server.model.UserInfo;
import camera.cn.cameramaster.server.util.FileUtils;


/**
 * 测试控制器
 *
 * @packageName: ymc.cn.servertest
 * @fileName: TestController
 * @date: 2019/4/23  16:15
 * @author: ymc
 * @QQ:745612618
 */

@RestController
@RequestMapping(path = "/test")
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class TestController {

    private static final String TAG = "TestController";

    private static final String LOGIN_ATTRIBUTE = "USER.LOGIN.SIGN";

    @ResponseBody
    @GetMapping("/take")
    public void takeCamera() {
        EventBus.getDefault().post(new AnyEventType());
    }

    @GetMapping(path = "/get/{userId}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    String info(@PathVariable(name = "userId") String userId) {
        return userId;
    }

    @PostMapping(path = "/login", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    String login(HttpRequest request, HttpResponse response, @RequestParam(name = "account",required = false
    ) String account, @RequestParam(name = "password",required = false) String password) {
        Session session = request.getValidSession();
        session.setAttribute(LOGIN_ATTRIBUTE, true);

        Cookie cookie = new Cookie("account", account + "=" + password);
        response.addCookie(cookie);
        return "login successful";
    }

    @Addition(stringType = "login", booleanType = true)
    @GetMapping(path = "/userInfo", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    UserInfo userInfo(@CookieValue("account") String account) {
        Log.e(TAG, "Account: " + account);
        UserInfo userInfo = new UserInfo();
        userInfo.setmUserId("123");
        userInfo.setmUserName("AndServer");
        return userInfo;
    }

    @PostMapping(path = "/upload", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    String upload(@RequestParam(name = "header") MultipartFile file) throws IOException {
        File localFile = FileUtils.createRandomFile(file);
        file.transferTo(localFile);
        return localFile.getAbsolutePath();
    }

    @GetMapping(path = "/consume", consumes = {"application/json", "!application/xml"})
    String consume() {
        return "Consume is successful";
    }

    @GetMapping(path = "/produce", produces = {"application/json; charset=utf-8"})
    String produce() {
        return "Produce is successful";
    }

    @GetMapping(path = "/include", params = {"name=123"})
    String include(@RequestParam(name = "name") String name) {
        return name;
    }

    @GetMapping(path = "/exclude", params = "name!=123")
    String exclude() {
        return "Exclude is successful.";
    }

    @GetMapping(path = {"/mustKey", "/getName"}, params = "name")
    String getMustKey(@RequestParam(name = "name") String name) {
        return name;
    }

    @PostMapping(path = {"/mustKey", "/postName"}, params = "name")
    String postMustKey(@RequestParam(name = "name") String name) {
        return name;
    }

    @GetMapping(path = "/noName", params = "!name")
    String noName() {
        return "NoName is successful.";
    }

    @PostMapping(path = "/formPart")
    String forPart(@FormPart(name = "user") UserInfo userInfo) {
        return JSON.toJSONString(userInfo);
    }

    @PostMapping(path = "/jsonBody")
    String jsonBody(@RequestBody UserInfo userInfo) {
        return JSON.toJSONString(userInfo);
    }

    @PostMapping(path = "/listBody")
    String jsonBody(@RequestBody List<UserInfo> infoList) {
        return JSON.toJSONString(infoList);
    }
}


================================================
FILE: app/src/main/java/camera/cn/cameramaster/server/component/LoggerInterceptor.java
================================================
/*
 * Copyright 2018 Yan Zhenjie.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package camera.cn.cameramaster.server.component;

import android.support.annotation.NonNull;
import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.yanzhenjie.andserver.annotation.Interceptor;
import com.yanzhenjie.andserver.framework.HandlerInterceptor;
import com.yanzhenjie.andserver.framework.handler.RequestHandler;
import com.yanzhenjie.andserver.http.HttpMethod;
import com.yanzhenjie.andserver.http.HttpRequest;
import com.yanzhenjie.andserver.http.HttpResponse;
import com.yanzhenjie.andserver.util.MultiValueMap;

/**
 * 拦截器
 *
 * @author ymc
 */

@Interceptor
public class LoggerInterceptor implements HandlerInterceptor {

    private static final String TAG = "LoggerInterceptor";

    @Override
    public boolean onIntercept(@NonNull HttpRequest request, @NonNull HttpResponse response,
                               @NonNull RequestHandler handler) {
        String path = request.getPath();
        HttpMethod method = request.getMethod();
        MultiValueMap<String, String> valueMap = request.getParameter();
        Log.e(TAG, "Path: " + path);
        Log.e(TAG, "Method: " + method.value());
        Log.e(TAG, "Param: " + JSON.toJSONString(valueMap));
        return false;
    }
}

================================================
FILE: app/src/main/java/camera/cn/cameramaster/server/model/UserInfo.java
================================================
package camera.cn.cameramaster.server.model;

import android.os.Parcel;
import android.os.Parcelable;

import com.alibaba.fastjson.annotation.JSONField;

/**
 * 用户
 *
 * @packageName: ymc.cn.servertest.model
 * @fileName: UserInfo
 * @date: 2019/4/23  17:31
 * @author: ymc
 * @QQ:745612618
 */

public class UserInfo implements Parcelable {

    @JSONField(name = "userId")
    private String mUserId;
    @JSONField(name = "userName")
    private String mUserName;

    public static final Creator<UserInfo> CREATOR = new Creator<UserInfo>() {
        @Override
        public UserInfo createFromParcel(Parcel in) {
            return new UserInfo(in);
        }

        @Override
        public UserInfo[] newArray(int size) {
            return new UserInfo[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(mUserId);
        dest.writeString(mUserName);
    }

    public UserInfo() {
    }

    protected UserInfo(Parcel in) {
        mUserId = in.readString();
        mUserName = in.readString();
    }

    public String getmUserId() {
        return mUserId;
    }

    public void setmUserId(String mUserId) {
        this.mUserId = mUserId;
    }

    public String getmUserName() {
        return mUserName;
    }

    public void setmUserName(String mUserName) {
        this.mUserName = mUserName;
    }
}


================================================
FILE: app/src/main/java/camera/cn/cameramaster/server/util/FileUtils.java
================================================
/*
 * Copyright 2018 Yan Zhenjie.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package camera.cn.cameramaster.server.util;

import android.os.Environment;
import android.webkit.MimeTypeMap;

import com.yanzhenjie.andserver.http.multipart.MultipartFile;
import com.yanzhenjie.andserver.util.StringUtils;

import java.io.File;
import java.util.UUID;

import camera.cn.cameramaster.base.App;


/**
 * Created by YanZhenjie on 2018/6/9.
 */
public class FileUtils {

    /**
     * Create a random file based on mimeType.
     *
     * @param file file.
     *
     * @return file object.
     */
    public static File createRandomFile(MultipartFile file) {
        String extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(file.getContentType().toString());
        if (StringUtils.isEmpty(extension)) {
            extension = MimeTypeMap.getFileExtensionFromUrl(file.getFilename());
        }
        String uuid = UUID.randomUUID().toString();
        return new File(App.getInstance().getRootDir(), uuid + "." + extension);
    }

    /**
     * SD is available.
     *
     * @return true, otherwise is false.
     */
    public static boolean storageAvailable() {
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            File sd = new File(Environment.getExternalStorageDirectory().getAbsolutePath());
            return sd.canWrite();
        } else {
            return false;
        }
    }
}

================================================
FILE: app/src/main/java/camera/cn/cameramaster/server/util/NetUtils.java
================================================
/*
 * Copyright © 2018 Yan Zhenjie.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package camera.cn.cameramaster.server.util;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
import java.util.regex.Pattern;

/**
 * Created by YanZhenjie on 2018/6/9.
 */
public class NetUtils {

    /**
     * Ipv4 address check.
     */
    private static final Pattern IPV4_PATTERN = Pattern.compile(
        "^(" + "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}" +
            "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$");

    /**
     * Check if valid IPV4 address.
     *
     * @param input the address string to check for validity.
     *
     * @return True if the input parameter is a valid IPv4 address.
     */
    public static boolean isIPv4Address(String input) {
        return IPV4_PATTERN.matcher(input).matches();
    }

    /**
     * Get local Ip address.
     */
    public static InetAddress getLocalIPAddress() {
        Enumeration<NetworkInterface> enumeration = null;
        try {
            enumeration = NetworkInterface.getNetworkInterfaces();
        } catch (SocketException e) {
            e.printStackTrace();
        }
        if (enumeration != null) {
            while (enumeration.hasMoreElements()) {
                NetworkInterface nif = enumeration.nextElement();
                Enumeration<InetAddress> inetAddresses = nif.getInetAddresses();
                if (inetAddresses != null) {
                    while (inetAddresses.hasMoreElements()) {
                        InetAddress inetAddress = inetAddresses.nextElement();
                        if (!inetAddress.isLoopbackAddress() && isIPv4Address(inetAddress.getHostAddress())) {
                            return inetAddress;
                        }
                    }
                }
            }
        }
        return null;
    }
}


================================================
FILE: app/src/main/java/camera/cn/cameramaster/ui/Camera2Activity.java
================================================
package camera.cn.cameramaster.ui;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CaptureFailure;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.Image;
import android.media.ImageReader;
import android.os.Build;
import android.os.Environment;
import android.support.annotation.RequiresApi;
import android.support.v4.app.ActivityCompat;
import android.util.Size;
import android.util.SparseIntArray;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import butterknife.BindView;
import butterknife.OnClick;
import camera.cn.cameramaster.R;
import camera.cn.cameramaster.base.BaseActivity;
import camera.cn.cameramaster.util.AppConstant;
import camera.cn.cameramaster.util.BitmapUtils;

/**
 * 基于 camera2 自定义拍照界面  (5.0以上)
 *
 * @author ymc
 * @date 2019年1月28日 13:56:02
 */

public class Camera2Activity extends BaseActivity {
    @BindView(R.id.textureView)
    TextureView textureView;
    @BindView(R.id.iv_back2)
    ImageView ivBack;
    @BindView(R.id.camera_flash2)
    ImageView ivFlash2;
    @BindView(R.id.camera_switch2)
    ImageView ivSwitch2;
    @BindView(R.id.img_camera2)
    ImageView ivCamera2;

    private CameraDevice mCameraDevice;
    /**
     * 摄像头id(0代表后置摄像头,1代表前置摄像头)
     */
    private String mCameraId = "0";
    private ImageReader imageReader;
    public static int height;
    public static int width;
    private Size previewSize;
    private CaptureRequest.Builder captureRequestBuilder;
    private CaptureRequest mCaptureRequest;
    private CameraCaptureSession mPreviewSession;
    /**
     * 判断是否有拍照权限的标识码
     */
    private final int RESULT_CODE_CAMERA = 1;
    private CaptureRequest.Builder mCaptureRequestBuilder;

    private static final SparseIntArray ORIENTATIONS = new SparseIntArray();

    static {
        ORIENTATIONS.append(Surface.ROTATION_0, 90);
        ORIENTATIONS.append(Surface.ROTATION_90, 0);
        ORIENTATIONS.append(Surface.ROTATION_180, 270);
        ORIENTATIONS.append(Surface.ROTATION_270, 180);
    }

    @Override
    protected int getLayoutId() {
        return R.layout.activity_camera2;
    }

    @Override
    protected void initView() {
        textureView.setSurfaceTextureListener(surfaceTextureListener);
    }

    @Override
    protected void initData() {

    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @OnClick({R.id.iv_back2, R.id.img_camera2})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.iv_back2:
                finish();
                break;
            case R.id.img_camera2:
                takePicture();
                break;
            default:
                break;
        }
    }

    /**
     * 启动拍照
     */
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private void startCamera() {
        if (textureView.isAvailable()) {
            if (mCameraDevice == null) {
                openCamera();
            }
        } else {
            textureView.setSurfaceTextureListener(surfaceTextureListener);
        }
    }

    /**
     * 拍照
     */
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private void takePicture() {
        try {
            if (mCameraDevice == null) {
                return;
            }
            // 创建拍照请求
            captureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
            // 设置自动对焦模式
            captureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
            // 将imageReader的surface设为目标
            captureRequestBuilder.addTarget(imageReader.getSurface());
            // 获取设备方向
            int rotation = getWindowManager().getDefaultDisplay().getRotation();
            // 根据设备方向计算设置照片的方向
            captureRequestBuilder.set(CaptureRequest.JPEG_ORIENTATION
                    , ORIENTATIONS.get(rotation));
            // 停止连续取景
            mPreviewSession.stopRepeating();
            //拍照
            CaptureRequest captureRequest = captureRequestBuilder.build();
            //设置拍照监听
            mPreviewSession.capture(captureRequest, captureCallback, null);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    /**
     * 监听拍照结果
     */
    private CameraCaptureSession.CaptureCallback captureCallback = new CameraCaptureSession.CaptureCallback() {
        // 拍照成功
        @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        @Override
        public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
            // 重设自动对焦模式
            captureRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
            // 设置自动曝光模式
            captureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
            try {
                //重新进行预览
                mPreviewSession.setRepeatingRequest(mCaptureRequest, null, null);
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onCaptureFailed(CameraCaptureSession session, CaptureRequest request, CaptureFailure failure) {
            super.onCaptureFailed(session, request, failure);
        }
    };

    /**
     * TextureView的监听
     */
    private TextureView.SurfaceTextureListener surfaceTextureListener = new TextureView.SurfaceTextureListener() {

        @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        @Override
        public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
            Camera2Activity.width = width;
            Camera2Activity.height = height;
            openCamera();
        }

        @Override
        public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
        }

        @Override
        public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
            stopCamera();
            return true;
        }

        @Override
        public void onSurfaceTextureUpdated(SurfaceTexture surface) {
        }
    };


    /**
     * 打开摄像头
     */
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private void openCamera() {
        CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
        //设置摄像头特性
        setCameraCharacteristics(manager);
        try {
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                String[] perms = {"android.permission.CAMERA"};
                ActivityCompat.requestPermissions(Camera2Activity.this, perms, RESULT_CODE_CAMERA);
            } else {
                manager.openCamera(mCameraId, stateCallback, null);
            }

        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }


    /**
     * 设置摄像头的参数
     */
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private void setCameraCharacteristics(CameraManager manager) {
        try {
            // 获取指定摄像头的特性
            CameraCharacteristics characteristics
                    = manager.getCameraCharacteristics(mCameraId);
            // 获取摄像头支持的配置属性
            StreamConfigurationMap map = characteristics.get(
                    CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
            // 获取摄像头支持的最大尺寸
            Size largest = Collections.max(
                    Arrays.asList(map.getOutputSizes(ImageFormat.JPEG)), new CompareSizesByArea());
            // 创建一个ImageReader对象,用于获取摄像头的图像数据
            imageReader = ImageReader.newInstance(largest.getWidth(), largest.getHeight(),
                    ImageFormat.JPEG, 2);
            //设置获取图片的监听
            imageReader.setOnImageAvailableListener(imageAvailableListener, null);
            // 获取最佳的预览尺寸
            previewSize = chooseOptimalSize(map.getOutputSizes(
                    SurfaceTexture.class), width, height, largest);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        } catch (NullPointerException e) {
        }
    }

    /**
     * 为Size定义一个比较器Comparator
     */
    static class CompareSizesByArea implements Comparator<Size> {
        @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        @Override
        public int compare(Size lhs, Size rhs) {
            return Long.signum((long) lhs.getWidth() * lhs.getHeight() -
                    (long) rhs.getWidth() * rhs.getHeight());
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private static Size chooseOptimalSize(Size[] choices
            , int width, int height, Size aspectRatio) {
        // 收集摄像头支持的大过预览Surface的分辨率
        List<Size> bigEnough = new ArrayList<>();
        int w = aspectRatio.getWidth();
        int h = aspectRatio.getHeight();
        for (Size option : choices) {
            if (option.getHeight() == option.getWidth() * h / w &&
                    option.getWidth() >= width && option.getHeight() >= height) {
                bigEnough.add(option);
            }
        }
        if (bigEnough.size() > 0) {
            return Collections.min(bigEnough, new CompareSizesByArea());
        } else {
            //没有合适的预览尺寸
            return choices[0];
        }
    }

    /**
     * 摄像头状态的监听
     */
    private CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {
        // 摄像头被打开时触发该方法
        @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        @Override
        public void onOpened(CameraDevice cameraDevice) {
            mCameraDevice = cameraDevice;
            // 开始预览
            takePreview();
        }

        // 摄像头断开连接时触发该方法
        @Override
        public void onDisconnected(CameraDevice cameraDevice) {
            stopCamera();
        }

        // 打开摄像头出现错误时触发该方法
        @Override
        public void onError(CameraDevice cameraDevice, int error) {
            stopCamera();
        }
    };

    /**
     * 开始预览
     */
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private void takePreview() {
        SurfaceTexture mSurfaceTexture = textureView.getSurfaceTexture();
        //设置TextureView的缓冲区大小
        mSurfaceTexture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());
        //获取Surface显示预览数据
        Surface mSurface = new Surface(mSurfaceTexture);
        try {
            //创建预览请求
            mCaptureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
            // 设置自动对焦模式
            mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
            //设置Surface作为预览数据的显示界面
            mCaptureRequestBuilder.addTarget(mSurface);
            //创建相机捕获会话,第一个参数是捕获数据的输出Surface列表,第二个参数是CameraCaptureSession的状态回调接口,当它创建好后会回调onConfigured方法,第三个参数用来确定Callback在哪个线程执行,为null的话就在当前线程执行
            mCameraDevice.createCaptureSession(Arrays.asList(mSurface, imageReader.getSurface()), new CameraCaptureSession.StateCallback() {
                @Override
                public void onConfigured(CameraCaptureSession session) {
                    try {
                        //开始预览
                        mCaptureRequest = mCaptureRequestBuilder.build();
                        mPreviewSession = session;
                        //设置反复捕获数据的请求,这样预览界面就会一直有数据显示
                        mPreviewSession.setRepeatingRequest(mCaptureRequest, null, null);
                    } catch (CameraAccessException e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onConfigureFailed(CameraCaptureSession session) {
                }
            }, null);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    /**
     * 释放
     */
    private void stopCamera() {
        if (mCameraDevice != null) {
            mCameraDevice.close();
            mCameraDevice = null;
        }
    }

    /**
     * 监听拍照的图片
     */
    private ImageReader.OnImageAvailableListener imageAvailableListener = new ImageReader.OnImageAvailableListener() {
        // 当照片数据可用时激发该方法
        @Override
        public void onImageAvailable(ImageReader reader) {
            //先验证手机是否有sdcard
            String status = Environment.getExternalStorageState();
            if (!status.equals(Environment.MEDIA_MOUNTED)) {
                Toast.makeText(getApplicationContext(), "你的sd卡不可用。", Toast.LENGTH_SHORT).show();
                return;
            }
            Image image = reader.acquireNextImage();
            ByteBuffer buffer = image.getPlanes()[0].getBuffer();
            byte[] data = new byte[buffer.remaining()];
            buffer.get(data);
            String filePath = Environment.getExternalStorageDirectory().getPath() + "/DCIM/Camera/" +
                    System.currentTimeMillis() + ".jpg";
            Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
            BitmapUtils.saveJPGE_After(getApplicationContext(), bitmap, filePath, 100);
            if (!bitmap.isRecycled()) {
                bitmap.recycle();
            }
            Intent intent = new Intent();
            intent.putExtra(AppConstant.KEY.IMG_PATH, filePath);
            intent.putExtra(AppConstant.KEY.PIC_WIDTH, width);
            intent.putExtra(AppConstant.KEY.PIC_HEIGHT, height);
            setResult(AppConstant.RESULT_CODE.RESULT_OK, intent);
            finish();
        }

    };

    @Override
    protected void onPause() {
        super.onPause();
        if (mCameraDevice != null) {
            stopCamera();
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void onResume() {
        super.onResume();
        startCamera();
    }

}


================================================
FILE: app/src/main/java/camera/cn/cameramaster/ui/CameraActivity.java
================================================
package camera.cn.cameramaster.ui;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.hardware.Camera;
import android.os.Environment;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;

import butterknife.BindView;
import butterknife.OnClick;
import camera.cn.cameramaster.R;
import camera.cn.cameramaster.base.BaseActivity;
import camera.cn.cameramaster.util.AppConstant;
import camera.cn.cameramaster.util.BitmapUtils;
import camera.cn.cameramaster.util.CameraUtil;
import camera.cn.cameramaster.view.ShowSurfaceView;

/**
 * 拍照界面
 * 5.0 版本以前的拍照
 *
 * @author ymc
 */

public class CameraActivity extends BaseActivity implements SurfaceHolder.Callback {
    private static final String TAG = "CameraActivity";
    @BindView(R.id.surfaceView2)
    ShowSurfaceView svShow;
    @BindView(R.id.surfaceView)
    SurfaceView svContent;
    @BindView(R.id.img_camera)
    ImageView ivCamera;
    @BindView(R.id.camera_flash)
    ImageView ivFlash;
    @BindView(R.id.camera_switch)
    ImageView ivSwitch;
    @BindView(R.id.iv_back)
    ImageView ivBack;

    private Camera mCamera;
    private SurfaceHolder mHolder;
    private CameraUtil cameraInstance;
    /**
     * 屏幕宽高
     */
    private int screenWidth;
    private int screenHeight;
    /**
     * 图片宽高
     */
    private int picWidth;

    /**
     * 是否有界面
     */
    private boolean isView = true;
    /**
     * 拍照id  1: 前摄像头  0:后摄像头
     */
    private int mCameraId = 0;
    /**
     * 闪光灯类型 0 :关闭 1: 打开 2:自动
     */
    private int light_type = 0;

    /**
     * 图片高度
     */
    private int picHeight;

    @Override
    protected int getLayoutId() {
        return R.layout.activity_camera;
    }

    @Override
    protected void initView() {
        mHolder = svContent.getHolder();
        mHolder.addCallback(this);
    }

    @Override
    protected void initData() {
        cameraInstance = CameraUtil.getInstance();
        DisplayMetrics dm = getResources().getDisplayMetrics();
        screenWidth = dm.widthPixels;
        screenHeight = dm.heightPixels;

    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mCamera == null) {
            mCamera = getCamera(mCameraId);
            if (mHolder != null) {
                startPreview(mCamera, mHolder);
            }
        }
    }

    @OnClick({R.id.img_camera, R.id.camera_flash, R.id.camera_switch, R.id.iv_back})
    public void OnClick(View view) {
        switch (view.getId()) {
            // 点击拍照
            case R.id.img_camera:
                switch (light_type) {
                    case 0:
                        //关闭
                        cameraInstance.turnLightOff(mCamera);
                        break;
                    case 1:
                        cameraInstance.turnLightOn(mCamera);
                        break;
                    case 2:
                        //自动
                        cameraInstance.turnLightAuto(mCamera);
                        break;
                    default:
                        break;
                }
                takePhoto();
                break;
            // 切换闪光灯
            case R.id.camera_flash:
                if (mCameraId == 1) {
                    Toast.makeText(this, "请切换到后置摄像头", Toast.LENGTH_LONG).show();
                    return;
                }
                Camera.Parameters parameters = mCamera.getParameters();
                switch (light_type) {
                    case 0:
                        //打开
                        light_type = 1;
                        ivFlash.setImageResource(R.mipmap.icon_camera_on);
                        parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);//开启
                        mCamera.setParameters(parameters);
                        break;
                    case 1:
                        //自动
                        light_type = 2;
                        parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
                        mCamera.setParameters(parameters);
                        ivFlash.setImageResource(R.mipmap.icon_camera_a);
                        break;
                    case 2:
                        //关闭
                        light_type = 0;
                        //关闭
                        parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
                        mCamera.setParameters(parameters);
                        ivFlash.setImageResource(R.mipmap.icon_camera_off);
                        break;
                    default:
                        break;
                }
                break;
            //切换前后摄像头
            case R.id.camera_switch:
                switchCamera();
                break;
            // 返回按钮
            case R.id.iv_back:
                finish();
                break;
            default:
                break;
        }
    }

    /**
     * 切换前后摄像头
     */
    public void switchCamera() {
        releaseCamera();
        mCameraId = (mCameraId + 1) % Camera.getNumberOfCameras();
        mCamera = getCamera(mCameraId);
        if (mHolder != null) {
            startPreview(mCamera, mHolder);
        }
    }

    /**
     * 拍照
     */
    private void takePhoto() {
        mCamera.takePicture(null, null, new Camera.PictureCallback() {
            @Override
            public void onPictureTaken(byte[] data, Camera camera) {
                isView = false;
                //将data 转换为位图 或者你也可以直接保存为文件使用 FileOutputStream
                //这里我相信大部分都有其他用处把 比如加个水印 后续再讲解
                Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
                Bitmap saveBitmap = cameraInstance.setTakePicktrueOrientation(mCameraId, bitmap);
                saveBitmap = Bitmap.createScaledBitmap(saveBitmap, screenWidth, screenHeight, true);
                String imgpath = getExternalFilesDir(Environment.DIRECTORY_DCIM).getPath() +
                        File.separator + System.currentTimeMillis() + ".jpeg";
                Log.e(TAG, "imgpath: ---  " + imgpath);
                BitmapUtils.saveJPGE_After(getApplicationContext(), saveBitmap, imgpath, 100);
                if (!bitmap.isRecycled()) {
                    bitmap.recycle();
                }
                if (!saveBitmap.isRecycled()) {
                    saveBitmap.recycle();
                }
                Intent intent = new Intent();
                intent.putExtra(AppConstant.KEY.IMG_PATH, imgpath);
                intent.putExtra(AppConstant.KEY.PIC_WIDTH, picWidth);
                intent.putExtra(AppConstant.KEY.PIC_HEIGHT, picHeight);
                setResult(AppConstant.RESULT_CODE.RESULT_OK, intent);
                finish();
            }
        });

    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        startPreview(mCamera, holder);
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        mCamera.stopPreview();
        startPreview(mCamera, holder);
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        releaseCamera();
    }

    /**
     * 释放相机资源
     */
    private void releaseCamera() {
        if (mCamera != null) {
            mCamera.setPreviewCallback(null);
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }
    }

    /**
     * 预览相机
     */
    private void startPreview(Camera camera, SurfaceHolder holder) {
        try {
            setupCamera(camera);
            camera.setPreviewDisplay(holder);
            mCamera.setPreviewCallback(new Camera.PreviewCallback() {
                @Override
                public void onPreviewFrame(byte[] data, Camera camera) {
                    Camera.Size size = camera.getParameters().getPreviewSize();
                    ByteArrayOutputStream stream = new ByteArrayOutputStream();
                    try{
                        // YUV转为RGB
                        YuvImage image = new YuvImage(data, ImageFormat.NV21, size.width, size.height, null);
                        image.compressToJpeg(new Rect(0, 0, size.width/2, size.height/2), 20, stream);
                        Bitmap bmp = BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.size());
                        svShow.setBitmap(BitmapUtils.rotateMyBitmap(BitmapUtils.ImgaeToNegative(bmp)));
                        stream.close();
                    }catch(Exception ex){
                        Log.e("Sys","Error:"+ex.getMessage());
                    }
                }
            });
            cameraInstance.setCameraDisplayOrientation(this, mCameraId, camera);
            camera.startPreview();
            isView = true;
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 设置surfaceView的尺寸 因为camera默认是横屏,所以取得支持尺寸也都是横屏的尺寸
     * 我们在startPreview方法里面把它矫正了过来,但是这里我们设置设置surfaceView的尺寸的时候要注意 previewSize.height<previewSize.width
     * previewSize.width才是surfaceView的高度
     * 一般相机都是屏幕的宽度 这里设置为屏幕宽度 高度自适应 你也可以设置自己想要的大小
     */
    private void setupCamera(Camera camera) {
        Camera.Parameters parameters = camera.getParameters();
        if (parameters.getSupportedFocusModes().contains(
                Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
            parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
        }
        //根据屏幕尺寸获取最佳 大小
        Camera.Size previewSize = cameraInstance.getPicPreviewSize(parameters.getSupportedPreviewSizes(),
                screenHeight, screenWidth);
        parameters.setPreviewSize(previewSize.width, previewSize.height);

        Camera.Size pictrueSize = cameraInstance.getPicPreviewSize(parameters.getSupportedPictureSizes(),
                screenHeight,screenWidth);
        parameters.setPictureSize(pictrueSize.width, pictrueSize.height);
        camera.setParameters(parameters);
//        picHeight = (screenWidth * pictrueSize.width) / pictrueSize.height;
        picWidth = pictrueSize.width;
        picHeight = pictrueSize.height;
//        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(screenWidth,
//                (screenWidth * pictrueSize.width) / pictrueSize.height);
//        svContent.setLayoutParams(params);
    }

    /**
     * 获取Camera实例
     *
     * @return Camera
     */
    private Camera getCamera(int id) {
        Camera camera = null;
        try {
            camera = Camera.open(id);
        } catch (Exception e) {
            Log.e(TAG, "getCamera: " + e);
        }
        return camera;
    }

}


================================================
FILE: app/src/main/java/camera/cn/cameramaster/ui/CameraSurfaceViewActivity.java
================================================
package camera.cn.cameramaster.ui;

import android.os.Build;
import android.support.annotation.RequiresApi;
import android.support.constraint.ConstraintLayout;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.Size;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;

import butterknife.BindView;
import butterknife.OnClick;
import camera.cn.cameramaster.R;
import camera.cn.cameramaster.base.BaseActivity;
import camera.cn.cameramaster.util.CameraV2;
import camera.cn.cameramaster.view.CameraV2GLSurfaceView;

/**
 * 基于 camera2 surfaceview 过滤界面
 * 参考url : [https://blog.csdn.net/lb377463323/article/details/78054892]
 *
 * @author ymc
 * @date 2019年2月12日 14:32:37
 */

public class CameraSurfaceViewActivity extends BaseActivity {
    private static final String TAG = "CameraSVActivity";
    @BindView(R.id.frame_layout)
    FrameLayout frameLayout;
    private CameraV2 mCamera;
    private CameraV2GLSurfaceView mCameraV2GLSurfaceView;

    @Override
    protected int getLayoutId() {
        return R.layout.activity_camera_sv;
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void initView() {
        mCameraV2GLSurfaceView = new CameraV2GLSurfaceView(this);
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        mCamera = new CameraV2(this);
        Size size = mCamera.setUpCameraOutputs(dm.widthPixels, dm.heightPixels);
        if (!mCamera.openCamera()) {
            Log.e(TAG, "mCamera openCamera err");
            return;
        }
        mCameraV2GLSurfaceView.init(mCamera, false,
                CameraSurfaceViewActivity.this);
        // 将 surfaceview 添加到布局中
        ConstraintLayout.LayoutParams lp = new ConstraintLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        lp.width = size.getHeight();
        lp.height = size.getWidth();
        mCameraV2GLSurfaceView.setLayoutParams(lp);
        frameLayout.addView(mCameraV2GLSurfaceView);
    }

    @Override
    protected void initData() {

    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @OnClick({R.id.iv_back, R.id.img_camera})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.iv_back:
                finish();
                break;
            case R.id.img_camera:
                mCamera.lockFocus();
                break;
            default:
                break;
        }
    }

    // TODO: 2019/4/3 会退到当前界面如何重新启动相机
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void onResume() {
        super.onResume();
        mCamera.startBackgroundThread();
        // 存在关联则打开相机,没有则绑定事件
//        mCamera.openCamera();
    }

    @Override
    protected void onPause() {
        mCamera.closeCamera();
        mCamera.stopBackgroundThread();
        super.onPause();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

}


================================================
FILE: app/src/main/java/camera/cn/cameramaster/ui/CameraVideoActivity.java
================================================
package camera.cn.cameramaster.ui;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.SurfaceTexture;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.params.RggbChannelVector;
import android.media.MediaRecorder;
import android.net.Uri;
import android.os.Build;
import android.os.Looper;
import android.support.annotation.RequiresApi;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import android.view.animation.TranslateAnimation;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.Switch;
import android.widget.TextView;

import java.io.File;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import butterknife.BindView;
import butterknife.OnClick;
import camera.cn.cameramaster.R;
import camera.cn.cameramaster.adapter.EffectAdapter;
import camera.cn.cameramaster.adapter.MenuAdapter;
import camera.cn.cameramaster.adapter.SenseAdapter;
import camera.cn.cameramaster.base.BaseActivity;
import camera.cn.cameramaster.view.AwbSeekBarChangeListener;
import camera.cn.cameramaster.util.AppConstant;
import camera.cn.cameramaster.util.cameravideo.CameraHelper;
import camera.cn.cameramaster.util.cameravideo.ICamera2;
import camera.cn.cameramaster.util.cameravideo.IVideoControl;
import camera.cn.cameramaster.util.cameravideo.VideoPlayer;
import camera.cn.cameramaster.view.AutoFitTextureView;
import camera.cn.cameramaster.view.AutoLocateHorizontalView;
import camera.cn.cameramaster.view.AwbSeekBar;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;

import static camera.cn.cameramaster.util.AppConstant.SHOW_AE;
import static camera.cn.cameramaster.util.AppConstant.SHOW_AWB;
import static camera.cn.cameramaster.util.AppConstant.SHOW_EFFECT;
import static camera.cn.cameramaster.util.AppConstant.SHOW_SENSE;

/**
 * 拍照 视频
 *
 * @author ymc
 * @date 2019年5月7日 13:49:17
 */

@RequiresApi(api = Build.VERSION_CODES.M)
public class CameraVideoActivity extends BaseActivity implements IVideoControl.PlaySeekTimeListener,
        IVideoControl.PlayStateListener, ICamera2.TakePhotoListener,
        SensorEventListener, ICamera2.CameraReady, AutoLocateHorizontalView.OnSelectedPositionChangedListener {

    private static final String TAG = "CameraVideoActivity";

    /**
     * 当前的显示面板状态
     */
    public int TEXTURE_STATE = AppConstant.TEXTURE_PREVIEW_STATE;

    @BindView(R.id.video_photo)
    ImageView videoPhoto;
    @BindView(R.id.video_texture)
    AutoFitTextureView videoTexture;
    @BindView(R.id.video_record_seek_bar)
    SeekBar videoRecordSeekBar;
    @BindView(R.id.video_time)
    TextView videoTime;
    @BindView(R.id.video_switch_flash)
    ImageView videoSwitchFlash;
    @BindView(R.id.video_switch_camera)
    ImageView videoSwitchCamera;
    @BindView(R.id.video_play)
    ImageButton videoPlay;
    @BindView(R.id.video_delete)
    ImageButton videoDelete;
    @BindView(R.id.video_menu)
    AutoLocateHorizontalView videoMenu;
    @BindView(R.id.video_record)
    ImageButton videoRecord;
    @BindView(R.id.video_save)
    ImageButton videoSave;
    @BindView(R.id.video_mine_play)
    ImageButton videoMinePlay;
    @BindView(R.id.video_seek_bar)
    SeekBar videoSeekBar;
    @BindView(R.id.video_seek_time)
    TextView videoSeekTime;
    @BindView(R.id.video_hint_text)
    TextView videoHintText;
    /**
     * 焦点框
     */
    @BindView(R.id.video_fouces)
    ImageView videoFouces;
    /**
     * zoom 缩小
     */
    @BindView(R.id.video_minus)
    ImageView videoMinus;
    /**
     * scale zoom 条
     */
    @BindView(R.id.video_scale)
    SeekBar videoScale;
    /**
     *  zoom 放大
     */
    @BindView(R.id.video_add)
    ImageView videoAdd;
    @BindView(R.id.video_scale_bar_layout)
    RelativeLayout videoScaleBarLayout;
    /**
     * 底部切换布局
     */
    @BindView(R.id.layout_bottom)
    RelativeLayout mLayoutBottom;

    /**
     * ae 修改布局
     */
    @BindView(R.id.layout_ae)
    LinearLayout layoutAe;
    /**
     * 特效
     */
    @BindView(R.id.layout_effect)
    LinearLayout llEffect;
    @BindView(R.id.rv_effect_list)
    RecyclerView evEffectList;
    /**
     * sense 布局
     */
    @BindView(R.id.layout_sense)
    LinearLayout llSense;
    @BindView(R.id.rv_sense_list)
    RecyclerView evSenseList;
    @BindView(R.id.sb_ae)
    SeekBar sbAe;

    /**
     * awb 手动设置布局
     */
    @BindView(R.id.layout_setting)
    LinearLayout llAWBSetting;
    @BindView(R.id.awb_seek_bar)
    SeekBar sbAWB;

    @BindView(R.id.sb_awb)
    AwbSeekBar sbAwb;

    /**
     * awb
     */
    @BindView(R.id.layout_awb)
    LinearLayout layoutAwb;

    @BindView(R.id.rl_camera)
    RelativeLayout rlCamera;

    @BindView(R.id.switch_ae)
    Switch switchAe;

    @BindView(R.id.txt_sb_txt)
    TextView tvSbTxt;

    /**
     * 视频播放器
     */
    private VideoPlayer mVideoPlayer;
    /**
     * 相机模式
     */
    private int MODE;
    /**
     * 视频保存路径
     */
    private String mVideoPath;
    /**
     * 拍照工具类
     */
    private CameraHelper cameraHelper;
    /**
     * 菜单适配器
     */
    private MenuAdapter mMenuAdapter;
    /**
     * 当前拍照模式
     */
    private int NOW_MODE;
    /**
     * 触摸事件处理类
     */
    private CameraTouch mCameraTouch;
    /**
     * 放大缩小seekBar 是否可以隐藏
     */
    private boolean isCanHind;
    /**
     * 手动对焦 动画
     */
    private FoucesAnimation mFoucesAnimation;
    /**
     * 前 后 摄像头标识
     */
    private ICamera2.CameraType mNowCameraType = ICamera2.CameraType.BACK;
    /**
     * 单点标识
     */
    private boolean hasRecordClick = false;
    /**
     * 是否在 录制中
     */
    private boolean hasRecording = false;
    /**
     * 图片路径
     */
    private String mCameraPath;
    /**
     * 倒计时
     */
    private Disposable mDisposable;
    /**
     * 是否正在播放 标识
     */
    private boolean hasPlaying = false;
    /**
     * 是否有拍照权限
     */
    private boolean isNoPremissionPause;

    /**
     * 定义文字动画
     */
    private AlphaAnimation mAlphaInAnimation;
    private AlphaAnimation mAlphaOutAnimation;
    private SenseAdapter sAdapter;
    private EffectAdapter effectAdapter;
    private Runnable mImageFoucesRunnable = new Runnable() {
        @Override
        public void run() {
            videoFouces.setVisibility(View.GONE);
        }
    };
    /**
     * 3s后隐藏的runnable
     */
    private Runnable SeekBarLayoutRunnalbe = new Runnable() {
        @Override
        public void run() {
            videoScaleBarLayout.setVisibility(View.GONE);
        }
    };
    /**
     * 视频播放模式控件隐藏
     */
    private Runnable mHindViewRunnable = new Runnable() {
        @Override
        public void run() {
            hindPlayView();
        }
    };
    /**
     * 底部 布局集合
     */
    private List<View> mLayoutList = new LinkedList<>();
    /**
     * visible与invisible之间切换的动画
     */
    private TranslateAnimation mShowAction;

    /**
     * 设置 rgb 色域
     * @param whiteBalance 0- 100
     * @return RggbChannelVector
     */
    public static RggbChannelVector colorTemperature(int whiteBalance) {
        float temperature = whiteBalance/100;
        float red;
        float green;
        float blue;

        //Calculate red
        if (temperature <= 66)
            red = 255;
        else {
            red = temperature - 60;
            red = (float) (329.698727446 * (Math.pow((double) red, -0.1332047592)));
            if (red < 0)
                red = 0;
            if (red > 255)
                red = 255;
        }


        //Calculate green
        if (temperature <= 66) {
            green = temperature;
            green = (float) (99.4708025861 * Math.log(green) - 161.1195681661);
            if (green < 0)
                green = 0;
            if (green > 255)
                green = 255;
        } else {
            green = temperature - 60;
            green = (float) (288.1221695283 * (Math.pow((double) green, -0.0755148492)));
            if (green < 0)
                green = 0;
            if (green > 255)
                green = 255;
        }

        //calculate blue
        if (temperature >= 66)
            blue = 255;
        else if (temperature <= 19)
            blue = 0;
        else {
            blue = temperature - 10;
            blue = (float) (138.5177312231 * Math.log(blue) - 305.0447927307);
            if (blue < 0)
                blue = 0;
            if (blue > 255)
                blue = 255;
        }

        Log.e(TAG, "red=" + red + ", green=" + green + ", blue=" + blue + ", paroess:"+whiteBalance);
        return new RggbChannelVector((red/255) * 2, (green/255), (green/255), (blue/255) * 2);
    }

    @Override
    protected int getLayoutId() {
        return R.layout.activity_camera_video;
    }

    @Override
    protected void initView() {
        // 将底部布局 依次添加到 列表中
        mLayoutList.clear();
        mLayoutList.add(mLayoutBottom);
        mLayoutList.add(layoutAe);
        mLayoutList.add(layoutAwb);
        mLayoutList.add(llEffect);
        mLayoutList.add(llSense);
        mLayoutList.add(llAWBSetting);
        // 初始化 切换动画
        mShowAction = new TranslateAnimation(Animation.RELATIVE_TO_SELF,
                0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
                Animation.RELATIVE_TO_SELF, -1.0f,
                Animation.RELATIVE_TO_SELF, 0.0f);
        mShowAction.setDuration(100);

        mVideoPlayer = new VideoPlayer();
        //设置时间戳回调
        mVideoPlayer.setPlaySeekTimeListener(this);
        MODE = getIntent().getIntExtra("mode", AppConstant.CAMERA_MODE);

        if (MODE == AppConstant.CAMERA_MODE) {
            //摄像头模式
            initCameraMode();
        } else if (MODE == AppConstant.VIDEO_MODE) {
            //视频播放模式
            mVideoPath = getIntent().getStringExtra("videoPath");
            initVideoMode();
        }
        mFoucesAnimation = new FoucesAnimation();
        // 淡入动画
        mAlphaInAnimation = new AlphaAnimation(0.0f, 1.0f);
        mAlphaInAnimation.setDuration(500);
        // 淡出动画
        mAlphaOutAnimation = new AlphaAnimation(1.0f, 0.0f);
        mAlphaOutAnimation.setDuration(500);

        sbAwb.setmOnAwbSeekBarChangeListener(cameraHelper);

        LinearLayoutManager ms = new LinearLayoutManager(this);
        ms.setOrientation(LinearLayoutManager.HORIZONTAL);
        LinearLayoutManager ms1 = new LinearLayoutManager(this);
        ms1.setOrientation(LinearLayoutManager.HORIZONTAL);
        evSenseList.setLayoutManager(ms);
        evEffectList.setLayoutManager(ms1);
        sAdapter = new SenseAdapter(this, AppConstant.senseArr);
        effectAdapter = new EffectAdapter(this,AppConstant.effectArr);
        evSenseList.setAdapter(sAdapter);
        evEffectList.setAdapter(effectAdapter);
        // rv 点击事件
        initListener();
    }

    @Override
    protected void initData() {
        mCameraPath = cameraHelper.getPhotoFilePath();
        mVideoPath = cameraHelper.getVideoFilePath();
        sbAWB.setOnSeekBarChangeListener(new awbSettingSeekBarListener());
        sbAe.setOnSeekBarChangeListener(new CameraSeekBarListener());
    }

    /**
     * 初始化 录像
     */
    private void initVideoMode() {
        hindMenu();
        hindSwitchCamera();
        hindVideoRecordSeekBar();
        mVideoPlayer.setPlayStateListener(this);
        videoRecord.setVisibility(View.GONE);
        videoHintText.setVisibility(View.GONE);
        videoTexture.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {     //单机屏幕显示出控件
                if (videoMinePlay.getVisibility() == View.VISIBLE) {
                    hindPlayView();
                } else {
                    showPlayView();
                    videoTexture.postDelayed(mHindViewRunnable, 3000);
                }
            }
        });

        videoSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            private int progress;
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                if (fromUser) {
                    this.progress = progress;
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                //触摸进度条取消几秒后隐藏的事件
                videoTexture.removeCallbacks(mHindViewRunnable);
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                mVideoPlayer.seekTo(progress);
                videoTexture.postDelayed(mHindViewRunnable, 3000);
            }
        });
    }

    /**
     * 初始化 拍照
     */
    @RequiresApi(api = Build.VERSION_CODES.M)
    @SuppressLint("ClickableViewAccessibility")
    private void initCameraMode() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) !=
                PackageManager.PERMISSION_GRANTED ||
                ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) !=
                        PackageManager.PERMISSION_GRANTED ||
                ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
                        != PackageManager.PERMISSION_GRANTED) {
            isNoPremissionPause = true;
        }
        initCamera(mNowCameraType);
        cameraHelper = new CameraHelper(this);
        cameraHelper.setTakePhotoListener(this);
        cameraHelper.setCameraReady(this);
        cameraHelper.setShowTextView(tvSbTxt);
        mVideoPlayer.setLoopPlay(true);
        List<String> menus = new ArrayList<>();
        menus.add("拍照");
        menus.add("录像");
        menus.add("曝光");
        menus.add("白平衡");
        menus.add("效果");
        menus.add("感觉");
        menus.add("手动设置");

        mMenuAdapter = new MenuAdapter(this, menus, videoMenu);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        videoMenu.setLayoutManager(linearLayoutManager);
        videoMenu.setAdapter(mMenuAdapter);
        videoMenu.setOnSelectedPositionChangedListener(this);

        mCameraTouch = new CameraTouch();

        videoMenu.setOnTouchListener(new HorizontalViewTouchListener());
        registerSensor();
        initScaleSeekbar();
    }

    /**
     * 初始化摄像头
     *
     * @param cameraType
     */
    private void initCamera(ICamera2.CameraType cameraType) {
        if (cameraHelper == null) {
            return;
        }
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
                != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        cameraHelper.setTextureView(videoTexture);
        cameraHelper.openCamera(cameraType);
    }

    /**
     * 初始化 scale seekBar
     */
    private void initScaleSeekbar() {
        videoScale.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {

            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                if (fromUser) {
                    float scale = (float) progress / (float) seekBar.getMax() * cameraHelper.getMaxZoom();
                    cameraHelper.cameraZoom(scale);
                    mCameraTouch.setScale(scale);
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                removeSeekBarRunnable();
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                seekBarDelayedHind();
            }
        });
    }

    /**
     * 点击事件
     *
     * @param view view
     */
    @RequiresApi(api = Build.VERSION_CODES.M)
    @OnClick({R.id.video_switch_camera, R.id.video_switch_flash})
    public void cameraOnClickListener(View view) {
        switch (view.getId()) {
            // 切换摄像头状态
            case R.id.video_switch_camera:
                if (mNowCameraType == ICamera2.CameraType.FRONT) {
                    cameraHelper.switchCamera(ICamera2.CameraType.BACK);
                    mNowCameraType = ICamera2.CameraType.BACK;
                } else {
                    cameraHelper.switchCamera(ICamera2.CameraType.FRONT);
                    mNowCameraType = ICamera2.CameraType.FRONT;
                }
                mCameraTouch.resetScale();
                break;
            case R.id.video_switch_flash:
                Object o = videoSwitchFlash.getTag();
                if (o == null || ((int) o) == 0) {
                    videoSwitchFlash.setBackgroundResource(R.mipmap.flash_auto);
                    videoSwitchFlash.setTag(1);
                    cameraHelper.flashSwitchState(ICamera2.FlashState.AUTO);
                } else if (((int) o) == 1) {
                    videoSwitchFlash.setBackgroundResource(R.mipmap.flash_open);
                    videoSwitchFlash.setTag(2);
                    cameraHelper.flashSwitchState(ICamera2.FlashState.OPEN);
                } else {
                    videoSwitchFlash.setBackgroundResource(R.mipmap.flash_close);
                    videoSwitchFlash.setTag(0);
                    cameraHelper.flashSwitchState(ICamera2.FlashState.CLOSE);
                }
                break;
            default:
                break;
        }
    }

    /**
     * 传感器继承方法 重力发生改变
     * 根据重力方向 动态旋转拍照图片角度(暂时关闭该方法)
     *
     * 使用以下方法
     * int rotation = getWindowManager().getDefaultDisplay().getRotation();
     * @param event event
     */
    @Override
    public void onSensorChanged(SensorEvent event) {
        if (event.sensor.getType() == Sensor.TYPE_ORIENTATION) {
            float x = event.values[0];
            float y = event.values[1];
            float z = event.values[2];
//            Log.e(TAG, "onSensorChanged: x: " + x +"   y: "+y +"  z : "+z);
            if (z > 55.0f) {
                //向左横屏
            } else if (z < -55.0f) {
                //向右横屏
            } else if (y > 60.0f) {
                //是倒竖屏
            } else {
                //正竖屏
            }
        }
        if (event.sensor.getType() == Sensor.TYPE_LIGHT) {
            float light = event.values[0];
            cameraHelper.setLight(light);
        }
    }

    /**
     * 注册陀螺仪传感器
     */
    private void registerSensor() {
        SensorManager mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        Sensor mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
        Sensor mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
        if (mSensor == null) {
            return;
        }
        mSensorManager.registerListener(this, mSensor, Sensor.TYPE_ORIENTATION);
        mSensorManager.registerListener(this, mLightSensor, Sensor.TYPE_LIGHT);
    }

    /**
     * 当已注册传感器的精度发生变化时调用
     *
     * @param sensor   sensor
     * @param accuracy 传感器的新精度
     */
    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }

    @Override
    public void onSeekTime(int allTime, final int time) {
        if (videoSeekBar ==null || videoSeekBar.getVisibility() != View.VISIBLE){
            return;
        }
        if (videoSeekBar.getMax() != allTime){
            videoSeekBar.setMax(allTime);
        }
        videoSeekBar.setProgress(time);
        videoSeekTime.post(new Runnable() {
            @Override
            public void run() {
                float t = (float) time / 1000.0f;
                videoSeekTime.setText(cameraHelper.secToTime(Math.round(t)));
            }
        });
    }

    @Override
    public void onStartListener(int width, int height) {
        videoTexture.setVideoAspectRatio(width, height);
        videoMinePlay.setImageResource(R.mipmap.ic_pause);
        videoPlay.setImageResource(R.mipmap.ic_pause);
    }

    @Override
    public void onCompletionListener() {
        hasPlaying = false;
        videoMinePlay.setImageResource(R.mipmap.ic_play);
        videoPlay.setImageResource(R.mipmap.ic_play);
        videoPlay.setVisibility(View.VISIBLE);
    }

    /**
     * 拍照完成回调
     *
     * @param file          文件
     * @param photoRotation 角度
     * @param width         宽度
     * @param height        高度
     */
    @Override
    public void onTakePhotoFinish(final File file, int photoRotation, int width, int height) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                hindSwitchCamera();
                hindMenu();
                showRecordEndView();
                videoSwitchFlash.setVisibility(View.GONE);
                videoRecord.setVisibility(View.GONE);
                videoHintText.setVisibility(View.GONE);
                TEXTURE_STATE = AppConstant.TEXTURE_PHOTO_STATE;
                videoTexture.setVisibility(View.GONE);
                videoPhoto.setImageURI(cameraHelper.getUriFromFile(CameraVideoActivity.this, file));
                videoPhoto.setVisibility(View.VISIBLE);
            }
        });
    }

    /**
     * 相机准备完毕
     */
    @Override
    public void onCameraReady() {
        videoRecord.setClickable(true);
    }

    /**
     * 横向菜单列表 修改点击事件
     *
     * @param pos
     */
    @Override
    public void selectedPositionChanged(int pos) {
        Log.e(TAG, "selectedPositionChanged: "+pos);
        switch (pos){
            case 0:{
                showLayout(0, false);
                NOW_MODE = AppConstant.VIDEO_TAKE_PHOTO;
                cameraHelper.setCameraState(ICamera2.CameraMode.TAKE_PHOTO);
                videoHintText.setText("点击拍照");
                break;
            }
            case 1:{
                showLayout(0, false);
                NOW_MODE = AppConstant.VIDEO_RECORD_MODE;
                cameraHelper.setCameraState(ICamera2.CameraMode.RECORD_VIDEO);
                videoHintText.setText("点击录像");
                break;
            }
            // 调整 曝光
            case 2:{
                showLayout(SHOW_AE, true);
                break;
            }
            // 调整 白平衡
            case 3:{
                showLayout(SHOW_AWB, true);
                break;
            }
            // 调整 效果
            case 4:{
                showLayout(3, true);
                break;
            }
            // 调整 感觉
            case 5:{
                showLayout(4, true);
                break;
            }
            // 调整 感觉
            case 6:{
                showLayout(5, true);
                break;
            }
        }
    }

    /**
     * 录像时长倒计时
     */
    @SuppressLint("SetTextI18n")
    private void recordCountDown() {
        videoTime.setVisibility(View.VISIBLE);
        videoRecordSeekBar.setVisibility(View.VISIBLE);
        final int count = 10;
        mDisposable = Observable.interval(1, 1, TimeUnit.SECONDS)
                .take(count + 1)
                .map(new Function<Long, Long>() {
                    @Override
                    public Long apply(Long aLong) {
                        return count - aLong;
                    }
                }).observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Long>() {
                    @Override
                    public void accept(Long aLong) {
                        long time = 11 - aLong;
                        if (time < 10) {
                            videoTime.setText("0:0" + String.valueOf(time));
                        } else {
                            videoTime.setText("0:" + String.valueOf(time));
                        }
                        videoRecordSeekBar.setProgress((int) time);
                        if (time == AppConstant.VIDEO_MAX_TIME) {
                            videoTime.postDelayed(new Runnable() {
                                @Override
                                public void run() {
                                    recordVideoOrTakePhoto();
                                    hindVideoRecordSeekBar();
                                }
                            }, 300);
                        }
                    }
                });
    }

    /**
     * 拍照或者录像
     */
    @OnClick(R.id.video_record)
    public void recordVideoOrTakePhoto() {
        if (hasRecordClick) {
            return;
        }
        hasRecordClick = true;
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO)
                != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission
                (this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            Log.e(TAG, "cameraOnClickListener: 动态权限获取失败...");
            return;
        }
        //拍照
        if (NOW_MODE == AppConstant.VIDEO_TAKE_PHOTO && mCameraPath!=null) {
            int rotation = getWindowManager().getDefaultDisplay().getRotation();
            cameraHelper.setDeviceRotation(rotation);
            cameraHelper.takePhone(mCameraPath, ICamera2.MediaType.JPEG);
        }
        //录制视频
        if (NOW_MODE == AppConstant.VIDEO_RECORD_MODE) {
            if (!hasRecording) {
                // 暂停录像
                if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO)
                        != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission
                        (this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                    return;
                }

                mVideoPath = cameraHelper.getVideoFilePath();
                hasRecording = cameraHelper.startVideoRecord(mVideoPath, MediaRecorder.OutputFormat.MPEG_4);
                if (hasRecording) {
                    videoRecord.setImageResource(R.mipmap.ic_recording);
                    hindSwitchCamera();
                    recordCountDown();
                    hindMenu();
                    //      mVideoHintText.setVisibility(View.GONE);
                    videoHintText.setText("点击停止");
                    videoSwitchFlash.setVisibility(View.GONE);
                    TEXTURE_STATE = AppConstant.TEXTURE_RECORD_STATE;
                }
            } else {
                // 开始录像
                if (mDisposable != null && !mDisposable.isDisposed()){
                    mDisposable.dispose();
                }
                mDisposable = null;
                videoSeekTime.setVisibility(View.GONE);
                hasRecording = false;
                cameraHelper.stopVideoRecord();

                videoRecord.setImageResource(R.drawable.ic_camera);
                videoRecord.setVisibility(View.GONE);
                videoHintText.setVisibility(View.GONE);
                showRecordEndView();
                hindVideoRecordSeekBar();
                playVideo();
            }
        }
        hasRecordClick = false;
    }

    /**
     * 返回 取消拍照或者 录像
     */
    @OnClick(R.id.video_delete)
    public void deleteVideoOrPicture() {
        if (TEXTURE_STATE == AppConstant.TEXTURE_PLAY_STATE) {
            mVideoPlayer.stop();
            cameraHelper.startBackgroundThread();
            cameraHelper.openCamera(mNowCameraType);
            mCameraTouch.resetScale();  //重新打开摄像头重置一下放大倍数
            File file = new File(mVideoPath);
            if (file.exists()){
                file.delete();
            }
            videoHintText.setText("点击录像");
        } else if (TEXTURE_STATE == AppConstant.TEXTURE_PHOTO_STATE) {
            File file = new File(mCameraPath);
            if (file.exists()){
                file.delete();
            }
            cameraHelper.resumePreview();
            videoTexture.setVisibility(View.VISIBLE);
            videoPhoto.setVisibility(View.GONE);
            videoHintText.setText("点击拍照");
        }
        initData();
        TEXTURE_STATE = AppConstant.TEXTURE_PREVIEW_STATE;
        hindRecordEndView();
        videoSwitchCamera.setVisibility(View.VISIBLE);
        videoMenu.setVisibility(View.VISIBLE);
        videoRecord.setVisibility(View.VISIBLE);
        videoTime.setVisibility(View.GONE);
        videoTime.setText("0:00");
        videoHintText.setVisibility(View.VISIBLE);
        videoSwitchFlash.setVisibility(View.VISIBLE);
    }

    /**
     * 发送视频或者图片
     */
    @OnClick(R.id.video_save)
    public void saveVideoOrPhoto() {
        final Intent data;
        data = new Intent();
        if (NOW_MODE == AppConstant.VIDEO_TAKE_PHOTO){
            data.putExtra("path", mCameraPath);
            data.putExtra("mediaType", "image");
            saveMedia(new File(mCameraPath));
        }
        else if (NOW_MODE == AppConstant.VIDEO_RECORD_MODE) {
            data.putExtra("path", mVideoPath);
            data.putExtra("mediaType", "video");
            saveMedia(new File(mVideoPath));
        }
        setResult(RESULT_OK, data);
        finish();
    }

    /**
     * 移除对焦 消失任务
     */
    private void removeImageFoucesRunnable() {
        videoFouces.removeCallbacks(mImageFoucesRunnable);
    }

    /**
     * 添加 延时消失任务
     */
    private void imageFoucesDelayedHind() {
        videoFouces.postDelayed(mImageFoucesRunnable, 500);
    }

    /**
     * seekBar 添加延时消失任务
     */
    private void seekBarDelayedHind() {
        if (isCanHind) {
            videoScaleBarLayout.postDelayed(SeekBarLayoutRunnalbe, 2000);
        }
        isCanHind = false;
    }

    /**
     * 移除隐藏 seekBar消失的任务
     */
    private void removeSeekBarRunnable() {
        isCanHind = true;
        videoScale.removeCallbacks(SeekBarLayoutRunnalbe);
    }

    /**
     * 显示播放视频 的 确认和删除按钮
     */
    private void showRecordEndView() {
        videoSave.setVisibility(View.VISIBLE);
        videoDelete.setVisibility(View.VISIBLE);
    }

    /**
     * 隐藏视频录像的进度条
     */
    private void hindVideoRecordSeekBar() {
        videoRecordSeekBar.setVisibility(View.GONE);
        videoRecordSeekBar.setProgress(0);
    }

    /**
     * 关闭摄像头
     */
    private void closeCamera() {
        videoRecord.setClickable(false);
        cameraHelper.closeCamera();
        cameraHelper.stopBackgroundThread();
    }

    /**
     * 播放视频
     */
    private void playVideo() {
        closeCamera();
        if (mVideoPath != null && mVideoPlayer != null) {
            mVideoPlayer.setDataSourceAndPlay(mVideoPath);
            hasPlaying = true;
            //视频播放状态
            TEXTURE_STATE = AppConstant.TEXTURE_PLAY_STATE;
        }
    }

    /**
     * 移动焦点图标
     *
     * @param x x坐标
     * @param y y坐标
     */
    private void moveFouces(int x, int y) {
        videoFouces.setVisibility(View.VISIBLE);
        RelativeLayout.LayoutParams layoutParams
                = (RelativeLayout.LayoutParams) videoFouces.getLayoutParams();
        videoFouces.setLayoutParams(layoutParams);
        mFoucesAnimation.setDuration(500);
        mFoucesAnimation.setRepeatCount(0);
        mFoucesAnimation.setOldMargin(x, y);
        videoFouces.startAnimation(mFoucesAnimation);
        cameraHelper.requestFocus(x, y);
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (cameraHelper != null) {
            cameraHelper.startBackgroundThread();
        }

        if (videoTexture.isAvailable()) {
            if (MODE == AppConstant.CAMERA_MODE) {
                if (TEXTURE_STATE == AppConstant.TEXTURE_PREVIEW_STATE) {
                    //预览状态
                    initCamera(mNowCameraType);
                } else if (TEXTURE_STATE == AppConstant.TEXTURE_PLAY_STATE) {
                    //视频播放状态
                    mVideoPlayer.play();
                }
                mVideoPlayer.setVideoPlayWindow(new Surface(videoTexture.getSurfaceTexture()));
            }
        } else {
            videoTexture.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
                @Override
                public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
                    if (MODE == AppConstant.CAMERA_MODE) {
                        if (TEXTURE_STATE == AppConstant.TEXTURE_PREVIEW_STATE) {
                            //预览状态
                            initCamera(mNowCameraType);
                        } else if (TEXTURE_STATE == AppConstant.TEXTURE_PLAY_STATE) {
                            //视频播放状态
                            mVideoPlayer.play();
                        }
                        mVideoPlayer.setVideoPlayWindow(new Surface(videoTexture.getSurfaceTexture()));
                    } else if (MODE == AppConstant.VIDEO_MODE) {
                        mVideoPlayer.setVideoPlayWindow(new Surface(videoTexture.getSurfaceTexture()));
                        Log.e("videoPath", "path:" + mVideoPath);
                        mVideoPlayer.setDataSourceAndPlay(mVideoPath);
                        hasPlaying = true;
                        //视频播放状态
                        TEXTURE_STATE = AppConstant.TEXTURE_PLAY_STATE;
                    }
                }

                @Override
                public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
                }

                @Override
                public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
                    return true;
                }

                @Override
                public void onSurfaceTextureUpdated(SurfaceTexture surface) {

                }
            });
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (isNoPremissionPause) {
            isNoPremissionPause = false;
            return;
        }
        Log.e("camera", "mode:" + MODE);
        if (MODE == AppConstant.CAMERA_MODE) {
            if (TEXTURE_STATE == AppConstant.TEXTURE_PREVIEW_STATE) {
                cameraHelper.closeCamera();
                cameraHelper.stopBackgroundThread();
            } else if (TEXTURE_STATE == AppConstant.TEXTURE_PLAY_STATE) {
                mVideoPlayer.pause();
            }
        }
    }

    /**
     * 隐藏切换摄像头按钮
     */
    private void hindSwitchCamera() {
        videoSwitchCamera.setVisibility(View.GONE);
    }

    /**
     * 隐藏切换菜单
     */
    private void hindMenu() {
        videoMenu.setVisibility(View.GONE);
    }

    /**
     * 刷新相册
     *
     * @param mediaFile 文件
     */
    private void saveMedia(File mediaFile) {
        Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        Uri uri = Uri.fromFile(mediaFile);
        intent.setData(uri);
        sendBroadcast(intent);
    }

    /**
     * 隐藏录像完成后底部两个按钮
     */
    private void hindRecordEndView() {
        videoSave.setVisibility(View.GONE);
        videoDelete.setVisibility(View.GONE);
    }

    /**
     * 隐藏播放界面的控件出来
     */
    private void hindPlayView() {
        videoSeekBar.setVisibility(View.GONE);
        videoMinePlay.setVisibility(View.GONE);
        videoPlay.setVisibility(View.GONE);
        videoSeekTime.setVisibility(View.GONE);
    }

    /**
     * 显示播放界面的控件出来
     */
    private void showPlayView() {
        videoSeekBar.setVisibility(View.VISIBLE);
        videoMinePlay.setVisibility(View.VISIBLE);
        videoPlay.setVisibility(View.VISIBLE);
        videoSeekTime.setVisibility(View.VISIBLE);
    }

    /**
     * 显示和隐藏控件
     *
     * @param showWhat
     * @param showOrNot
     */
    private void showLayout(int showWhat, boolean showOrNot) {
        View v = mLayoutList.get(showWhat);
        if (showOrNot) {
            //全部隐藏但是AF/AE的显示出来
            for (int i = 0; i < mLayoutBottom.getChildCount(); i++) {
                if (mLayoutBottom.getChildAt(i).getVisibility() == View.VISIBLE) {
                    mLayoutBottom.getChildAt(i).setVisibility(View.GONE);
                }
            }
            v.startAnimation(mShowAction);
            v.setVisibility(View.VISIBLE);
        } else {
            //全部隐藏但是capture的显示出来
            for (int i = 0; i < mLayoutBottom.getChildCount(); i++) {
                if (mLayoutBottom.getChildAt(i).getVisibility() == View.VISIBLE) {
                    mLayoutBottom.getChildAt(i).setVisibility(View.GONE);
                }
            }
            rlCamera.startAnimation(mShowAction);
            rlCamera.setVisibility(View.VISIBLE);
        }
    }

    /**
     * rv点击事件 初始化
     */
    private void initListener() {
        sAdapter.setSenseOnItemClickListener(new SenseAdapter.SenseOnItemClickListener() {
            @Override
            public void itemOnClick(int position) {
                cameraHelper.setCameraBuilerMode(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_USE_SCENE_MODE);
                switch (position) {
                    case 0:
                        cameraHelper.setCameraBuilerMode(CaptureRequest.CONTROL_SCENE_MODE, CameraMetadata.CONTROL_SCENE_MODE_DISABLED);
                        break;
                    case 1:
                        cameraHelper.setCameraBuilerMode(CaptureRequest.CONTROL_SCENE_MODE, CameraMetadata.CONTROL_SCENE_MODE_FACE_PRIORITY);
                        break;
                    case 2:
                        cameraHelper.setCameraBuilerMode(CaptureRequest.CONTROL_SCENE_MODE, CameraMetadata.CONTROL_SCENE_MODE_ACTION);
                        break;
                    case 3:
                        cameraHelper.setCameraBuilerMode(CaptureRequest.CONTROL_SCENE_MODE, CameraMetadata.CONTROL_SCENE_MODE_PORTRAIT);
                        break;
                    case 4:
                        cameraHelper.setCameraBuilerMode(CaptureRequest.CONTROL_SCENE_MODE, CameraMetadata.CONTROL_SCENE_MODE_LANDSCAPE);
                        break;
                    case 5:
                        cameraHelper.setCameraBuilerMode(CaptureRequest.CONTROL_SCENE_MODE, CameraMetadata.CONTROL_SCENE_MODE_NIGHT);
                        break;
                    case 6:
                        cameraHelper.setCameraBuilerMode(CaptureRequest.CONTROL_SCENE_MODE, CameraMetadata.CONTROL_SCENE_MODE_NIGHT_PORTRAIT);
                        break;
                    case 7:
                        cameraHelper.setCameraBuilerMode(CaptureRequest.CONTROL_SCENE_MODE, CameraMetadata.CONTROL_SCENE_MODE_THEATRE);
                        break;
                    case 8:
                        cameraHelper.setCameraBuilerMode(CaptureRequest.CONTROL_SCENE_MODE, CameraMetadata.CONTROL_SCENE_MODE_BEACH);
                        break;
                    case 9:
                        cameraHelper.setCameraBuilerMode(CaptureRequest.CONTROL_SCENE_MODE, CameraMetadata.CONTROL_SCENE_MODE_SNOW);
                        break;
                    case 10:
                        cameraHelper.setCameraBuilerMode(CaptureRequest.CONTROL_SCENE_MODE, CameraMetadata.CONTROL_SCENE_MODE_SUNSET);
                        break;
                    case 11:
                        cameraHelper.setCameraBuilerMode(CaptureRequest.CONTROL_SCENE_MODE, CameraMetadata.CONTROL_SCENE_MODE_STEADYPHOTO);
                        break;
                    case 12:
                        cameraHelper.setCameraBuilerMode(CaptureRequest.CONTROL_SCENE_MODE, CameraMetadata.CONTROL_SCENE_MODE_FIREWORKS);
                        break;
                    case 13:
                        cameraHelper.setCameraBuilerMode(CaptureRequest.CONTROL_SCENE_MODE, CameraMetadata.CONTROL_SCENE_MODE_SPORTS);
                        break;
                    case 14:
                        cameraHelper.setCameraBuilerMode(CaptureRequest.CONTROL_SCENE_MODE, CameraMetadata.CONTROL_SCENE_MODE_PARTY);
                        break;
                    case 15:
                        cameraHelper.setCameraBuilerMode(CaptureRequest.CONTROL_SCENE_MODE, CameraMetadata.CONTROL_SCENE_MODE_CANDLELIGHT);
                        break;
                    case 16:
                        cameraHelper.setCameraBuilerMode(CaptureRequest.CONTROL_SCENE_MODE, CameraMetadata.CONTROL_SCENE_MODE_BARCODE);
                        break;
                    default:
                        break;
                }
            }
        });

        effectAdapter.setEffectOnItemClickListener(new EffectAdapter.EffectOnItemClickListener() {
            @Override
            public void itemOnClick(int position) {
                switch (position) {
                    case 0:
                        cameraHelper.setCameraBuilerMode(CaptureRequest.CONTROL_EFFECT_MODE, CameraMetadata.CONTROL_EFFECT_MODE_AQUA);
                        break;
                    case 1:
                        cameraHelper.setCameraBuilerMode(CaptureRequest.CONTROL_EFFECT_MODE, CameraMetadata.CONTROL_EFFECT_MODE_BLACKBOARD);
                        break;
                    case 2:
                        cameraHelper.setCameraBuilerMode(CaptureRequest.CONTROL_EFFECT_MODE, CameraMetadata.CONTROL_EFFECT_MODE_MONO);
                        break;
                    case 3:
                        cameraHelper.setCameraBuilerMode(CaptureRequest.CONTROL_EFFECT_MODE, CameraMetadata.CONTROL_EFFECT_MODE_NEGATIVE);
                        break;
                    case 4:
                        cameraHelper.setCameraBuilerMode(CaptureRequest.CONTROL_EFFECT_MODE, CameraMetadata.CONTROL_EFFECT_MODE_POSTERIZE);
                        break;
                    case 5:
                        cameraHelper.setCameraBuilerMode(CaptureRequest.CONTROL_EFFECT_MODE, CameraMetadata.CONTROL_EFFECT_MODE_SEPIA);
                        break;
                    case 6:
                        cameraHelper.setCameraBuilerMode(CaptureRequest.CONTROL_EFFECT_MODE, CameraMetadata.CONTROL_EFFECT_MODE_SOLARIZE);
                        break;
                    case 7:
                        cameraHelper.setCameraBuilerMode(CaptureRequest.CONTROL_EFFECT_MODE, CameraMetadata.CONTROL_EFFECT_MODE_WHITEBOARD);
                        break;
                    case 8:
                        cameraHelper.setCameraBuilerMode(CaptureRequest.CONTROL_EFFECT_MODE, CameraMetadata.CONTROL_EFFECT_MODE_OFF);
                        break;
                    default:
                        break;
                }
            }
        });
    }

    /**
     * 横向列表 touch事件 (拍照预览 缩放)
     */
    private class HorizontalViewTouchListener implements View.OnTouchListener {

        private long mClickOn;
        private float mLastX;
        private float mLastY;

        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            switch (motionEvent.getActionMasked()) {
                case MotionEvent.ACTION_DOWN:
                    if (motionEvent.getPointerCount() == 1) {
                        mClickOn = System.currentTimeMillis();
                        mLastX = motionEvent.getX();
                        mLastY = motionEvent.getY();
                    }
                    break;
                // 用户两指按下事件
                case MotionEvent.ACTION_POINTER_DOWN:
                    mCameraTouch.onScaleStart(motionEvent);
                    return true;
                case MotionEvent.ACTION_MOVE:
                    if (motionEvent.getPointerCount() == 2) {
                        mCameraTouch.onScale(motionEvent);
                        return true;
                    } else {
                        float x = motionEvent.getX() - mLastX;
                        float y = motionEvent.getY() - mLastY;
                        if (Math.abs(x) >= 10 || Math.abs(y) >= 10) {
                            mClickOn = 0;
                        }
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    if (motionEvent.getPointerCount() == 1) {
                        if ((System.currentTimeMillis() - mClickOn) < 500) {
                            moveFouces((int) motionEvent.getX(), (int) motionEvent.getY());
                        }
                    }
                    break;
                case MotionEvent.ACTION_POINTER_UP:
                    mCameraTouch.onScaleEnd(motionEvent);
                    return true;
                default:
                    break;
            }
            return false;
        }
    }

    /**
     * TextureView 触摸方法
     */
    private class CameraTouch {
        private float mOldScale = 1.0f;
        private float mScale;
        private float mSpan = 0;
        private float mOldSpan;
        private float mFirstDistance = 0;

        public void onScale(MotionEvent event) {
            if (event.getPointerCount() == 2) {
                if (mFirstDistance == 0) {
                    mFirstDistance = distance(event);
                }

                float distance = distance(event);
                float scale;
                if (distance > mFirstDistance) {
                    scale = (distance - mFirstDistance) / 80;
                    scale = scale + mSpan;
                    mOldSpan = scale;
                    mScale = scale;
                } else if (distance < mFirstDistance) {
                    scale = distance / mFirstDistance;
                    mOldSpan = scale;
                    mScale = scale * mOldScale;
                } else {
                    return;
                }

                cameraHelper.cameraZoom(mScale);
                videoScale.setProgress((int) ((mScale / cameraHelper.getMaxZoom()) * videoScale.getMax()));
                if (mScale < 1.0f) {
                    videoScale.setProgress(0);
                }
            }
        }

        /**
         * scale 开始
         *
         * @param event
         */
        public void onScaleStart(MotionEvent event) {
            mFirstDistance = 0;
            setScaleMax((int) cameraHelper.getMaxZoom());
            videoScaleBarLayout.setVisibility(View.VISIBLE);
            removeSeekBarRunnable();
        }

        /**
         * scale 结束
         *
         * @param event MotionEvent
         */
        private void onScaleEnd(MotionEvent event) {
            if (mScale < 1.0f) {
                mOldScale = 1.0f;
            } else if (mScale > cameraHelper.getMaxZoom()) {
                mOldScale = cameraHelper.getMaxZoom();
            } else {
                mOldScale = mScale;
            }
            mSpan = mOldSpan;

            if (event != null) {
                seekBarDelayedHind();
            }
        }

        /**
         * 重置 缩放
         */
        public void resetScale() {
            mOldScale = 1.0f;
            mSpan = 0f;
            mFirstDistance = 0f;
            videoScale.setProgress(0);
        }

        public void setScale(float scale) {
            mScale = scale;
            mOldSpan = scale;
            onScaleEnd(null);
        }

        /**
         * 计算两个手指间的距离
         *
         * @param event MotionEvent
         * @return 距离
         */
        private float distance(MotionEvent event) {
            float dx = event.getX(1) - event.getX(0);
            float dy = event.getY(1) - event.getY(0);
            // 使用勾股定理返回两点之间的距离
            return (float) Math.sqrt(dx * dx + dy * dy);
        }

        private void setScaleMax(int max) {
            videoScale.setMax(max * 100);
        }
    }

    /**
     * camera 点击对焦动画
     */
    private class FoucesAnimation extends Animation {

        private int width = cameraHelper.dip2px(CameraVideoActivity.this, 150);
        private int W = cameraHelper.dip2px(CameraVideoActivity.this, 65);

        private int oldMarginLeft;
        private int oldMarginTop;

        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {

            RelativeLayout.LayoutParams layoutParams =
                    (RelativeLayout.LayoutParams) videoFouces.getLayoutParams();
            int w = (int) (width * (1 - interpolatedTime));
            if (w < W) {
                w = W;
            }
            layoutParams.width = w;
            layoutParams.height = w;
            if (w == W) {
                videoFouces.setLayoutParams(layoutParams);
                return;
            }
            layoutParams.leftMargin = oldMarginLeft - (w / 2);
            layoutParams.topMargin = oldMarginTop + (w / 8);
            videoFouces.setLayoutParams(layoutParams);
        }

        public void setOldMargin(int oldMarginLeft, int oldMarginTop) {
            this.oldMarginLeft = oldMarginLeft;
            this.oldMarginTop = oldMarginTop;
            removeImageFoucesRunnable();
            imageFoucesDelayedHind();
        }
    }

    /**
     * 曝光 ae 滑动监听事件
     */
    private class CameraSeekBarListener implements SeekBar.OnSeekBarChangeListener {

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            switch (seekBar.getId()){
                case R.id.sb_ae: {
                    if (switchAe.isChecked()) {
                        // 曝光增益
                        if (cameraHelper.getRange1() == null) {
                            break;
                        }
                        Log.e(TAG, "曝光增益范围:" + cameraHelper.getRange1().toString());
                        int maxmax = cameraHelper.getRange1().getUpper();
                        int minmin = cameraHelper.getRange1().getLower();
                        int all = maxmax - minmin;
                        int time = 100 / all;
                        int ae = ((progress / time) - maxmax) > maxmax ? maxmax :
                                ((progress / time) - maxmax) < minmin ? minmin : ((progress / time) - maxmax);
                        cameraHelper.setAERegions(ae);
                        tvSbTxt.setText("曝光增益:" + ae);
                    } else {
                        // 曝光时间
                        if (cameraHelper.getEtr() == null) {
                            tvSbTxt.setText("获取曝光时间失败");
                            break;
                        }
                        Log.e(TAG, "曝光时间范围:" + cameraHelper.getEtr().toString());
                        long max = cameraHelper.getEtr().getUpper();
                        long min = cameraHelper.getEtr().getLower();
                        long ae = ((progress * (max - min)) / 100 + min);
                        cameraHelper.setAeTime(ae);
                        tvSbTxt.setText("曝光时间:" + ae);
                    }
                    break;
                }
            }
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
            tvSbTxt.setVisibility(View.VISIBLE);
            tvSbTxt.startAnimation(mAlphaInAnimation);
        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
            tvSbTxt.startAnimation(mAlphaOutAnimation);
            tvSbTxt.setVisibility(View.INVISIBLE);
        }
    }

    /**
     * 手动白平衡 滑动监听事件
     */
    private class awbSettingSeekBarListener implements SeekBar.OnSeekBarChangeListener {

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

            cameraHelper.setCameraBuilerMode(CaptureRequest.CONTROL_AWB_MODE, CaptureRequest.CONTROL_AWB_MODE_OFF);
            cameraHelper.setCameraBuilerMode(CaptureRequest.COLOR_CORRECTION_MODE, CaptureRequest.COLOR_CORRECTION_MODE_TRANSFORM_MATRIX);
            // 小米华为 没有的权限
            cameraHelper.setCameraBuilerMode(CaptureRequest.COLOR_CORRECTION_GAINS, colorTemperature(progress+2000));

        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {

        }
    }
}


================================================
FILE: app/src/main/java/camera/cn/cameramaster/ui/GoogleCameraActivity.java
================================================
package camera.cn.cameramaster.ui;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.Image;
import android.media.ImageReader;
import android.media.MediaRecorder;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.annotation.RequiresApi;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.util.Range;
import android.util.Size;
import android.util.SparseIntArray;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;

import com.yanzhenjie.loading.dialog.LoadingDialog;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

import butterknife.BindView;
import butterknife.OnCheckedChanged;
import butterknife.OnClick;
import camera.cn.cameramaster.R;
import camera.cn.cameramaster.adapter.EffectAdapter;
import camera.cn.cameramaster.adapter.SenseAdapter;
import camera.cn.cameramaster.base.BaseActivity;
import camera.cn.cameramaster.server.AnyEventType;
import camera.cn.cameramaster.view.AwbSeekBarChangeListener;
import camera.cn.cameramaster.server.ServerManager;
import camera.cn.cameramaster.util.AppConstant;
import camera.cn.cameramaster.util.CompareSizesByArea;
import camera.cn.cameramaster.util.Utils;
import camera.cn.cameramaster.view.AutoTextureView;
import camera.cn.cameramaster.view.ShowSurfaceView;
import camera.cn.cameramaster.view.AnimationTextView;
import camera.cn.cameramaster.view.AwbSeekBar;

import static android.provider.MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO;
import static camera.cn.cameramaster.util.AppConstant.SHOW_AE;
import static camera.cn.cameramaster.util.AppConstant.SHOW_AWB;
import static camera.cn.cameramaster.util.AppConstant.SHOW_EFFECT;
import static camera.cn.cameramaster.util.AppConstant.SHOW_ISO;
import static camera.cn.cameramaster.util.AppConstant.SHOW_SENSE;
import static camera.cn.cameramaster.util.AppConstant.SHOW_ZOOM;

/**
 * google 拍照 demo
 *
 * @author ymc
 * @date 2019年1月28日 17:32:45
 * @url https://github.com/googlesamples/android-Camera2Basic
 */
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class GoogleCameraActivity extends BaseActivity {
    private static final String TAG = "GoogleCameraActivity";
    /**
     * 这里为了测试 相机将画布设置为 1像素,如果 想要看原版效果,
     * 则隐藏 ShowSurfaceView ,将AutoFitTextureView设置充满
     */
    @BindView(R.id.textureView_g)
    AutoTextureView mTextureView;
    @BindView(R.id.surfaceView2)
    ShowSurfaceView svShow;
    /**
     * 闪光灯
     */
    @BindView(R.id.iv_flash)
    ImageView ivFlash;
    /**
     * 曝光
     */
    @BindView(R.id.iv_ae)
    ImageView ivAW;
    /**
     * 白平衡
     */
    @BindView(R.id.iv_awb)
    ImageView ivAWB;
    /**
     * 光感度
     */
    @BindView(R.id.iv_iso)
    ImageView ivISO;
    /**
     * 放大倍数
     */
    @BindView(R.id.iv_zoom)
    ImageView ivZoom;
    /**
     * 影响
     */
    @BindView(R.id.iv_effect)
    ImageView ivEffect;
    /**
     * 感应
     */
    @BindView(R.id.iv_sense)
    ImageView ivSense;
    /**
     * 底部切换布局
     */
    @BindView(R.id.layout_bottom)
    RelativeLayout mLayoutBottom;
    /**
     * 拍照布局
     */
    @BindView(R.id.homecamera_bottom_relative2)
    RelativeLayout mLayoutCapture;
    @BindView(R.id.img_camera_g)
    ImageView ivCamereVideo;
    @BindView(R.id.switch_ae)
    Switch switchAe;
    @BindView(R.id.sb_ae)
    SeekBar sbAe;
    @BindView(R.id.layout_ae)
    LinearLayout layoutAe;
    @BindView(R.id.sb_zoom)
    SeekBar sbZoom;
    @BindView(R.id.layout_zoom)
    LinearLayout layoutZoom;
    @BindView(R.id.sb_awb)
    AwbSeekBar sbAwb;
    @BindView(R.id.layout_awb)
    LinearLayout layoutAwb;
    @BindView(R.id.switch_iso)
    Switch switchIso;
    @BindView(R.id.sb_iso)
    SeekBar sbIso;
    @BindView(R.id.layout_iso)
    LinearLayout layoutIso;
    @BindView(R.id.txt_window_txt)
    AnimationTextView txtWindowTxt;
    @BindView(R.id.txt_sb_txt)
    TextView tvSbTxt;
    @BindView(R.id.layout_effect)
    LinearLayout llEffect;
    @BindView(R.id.rv_effect_list)
    RecyclerView evEffectList;
    @BindView(R.id.layout_sense)
    LinearLayout llSense;
    @BindView(R.id.rv_sense_list)
    RecyclerView evSenseList;

    /**
     * visible与invisible之间切换的动画
     */
    private TranslateAnimation mShowAction;

    /**
     * Conversion from screen rotation to JPEG orientation.
     */
    private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
    private static final int REQUEST_CAMERA_PERMISSION = 1;
    /**
     * 相机预览状态
     */
    private static final int STATE_PREVIEW = 0;
    /**
     * 等待相机锁定
     */
    private static final int STATE_WAITING_LOCK = 1;
    /**
     * 相机状态:等待曝光处于预捕获状态。
     */
    private static final int STATE_WAITING_PRECAPTURE = 2;
    /**
     * 相机状态:等待曝光状态不是预捕获。
     */
    private static final int STATE_WAITING_NON_PRECAPTURE = 3;
    /**
     * 相机状态:已拍摄照片。
     */
    private static final int STATE_PICTURE_TAKEN = 4;
    /**
     * Camera2 API保证的最大预览宽度
     */
    private static final int MAX_PREVIEW_WIDTH = 1920;
    /**
     * Camera2 API保证的最大预览高度
     */
    private static final int MAX_PREVIEW_HEIGHT = 1280;
    /**
     * 当前拍照id
     */
    private String mCameraId;
    /**
     * 相机预览
     */
    private CameraCaptureSession mCaptureSession;
    private CameraDevice mCameraDevice;
    /**
     * 预览
     */
    private Size mPreviewSize;
    /**
     * 相机预览
     */
    private CaptureRequest.Builder mPreviewRequestBuilder;
    private CaptureRequest mPreviewRequest;
    /**
     * 视频对象
     */
    private MediaRecorder mMediaRecorder;
    /**
     * 当前相机状态.
     */
    private int mState = STATE_PREVIEW;

    /**
     * 在关闭相机之前阻止应用程序退出
     */
    private Semaphore mCameraOpenCloseLock = new Semaphore(1);

    /**
     * 当前相机设备是否支持Flash
     */
    private boolean mFlashSupported;

    /**
     * 相机传感器的方向
     */
    private int mSensorOrientation;

    private HandlerThread mBackgroundThread;

    private Handler mBackgroundHandler;

    private ImageReader mImageReader;

    private File mFile;

    private File mVideoPath;

    /**
     * true : 正在录制  /  false :反之
     */
    private boolean hasVideoOn = false;

    /**
     * 闪光灯类型 0 :关闭   1: 打开   2:自动
     */
    private int flishType = 0;

    /**
     * 是否显示底部 布局的按钮
     */
    private boolean showAeFlag = false;
    /**
     * 底部 布局集合
     */
    private List<View> mLayoutList = new LinkedList<>();
    /**
     * 文字动画
     */
    private ScaleAnimation mScaleWindowAnimation;
    /**
     * 淡入动画
     */
    private AlphaAnimation mAlphaInAnimation;
    /**
     * 淡出动画
     */
    private AlphaAnimation mAlphaOutAnimation;

    static {
        ORIENTATIONS.append(Surface.ROTATION_0, 90);
        ORIENTATIONS.append(Surface.ROTATION_90, 0);
        ORIENTATIONS.append(Surface.ROTATION_180, 270);
        ORIENTATIONS.append(Surface.ROTATION_270, 180);
    }

    /**
     * 加载动画
     */
    private LoadingDialog mDialog;

    /**
     * url
     */
    private String mRootUrl;

    /**
     * 服务管理器
     */
    private ServerManager mServerManager;
    /**
     * 是否显示Awb的按钮
     */
    private boolean showAwbFlag = false;
    /**
     * 是否显示 iso 的按钮
     */
    private boolean showIsoFlag = false;
    /**
     * 是否显示 effect 的按钮
     */
    private boolean showEffectFlag = false;
    /**
     * 是否显示 iso 的按钮
     */
    private boolean showSenseFlag = false;
    /**
     * 相机配置
     */
    private CameraCharacteristics characteristics;
    /**
     * 相机 曝光 范围
     */
    private Range<Integer> range1;
    /**
     * 曝光时间
     */
    private Range<Long> etr;
    /**
     * 相机 iso 范围
     */
    private Range<Integer> isoRange;
    /**
     * zoom 是否显示标识
     */
    private boolean showZoomFlag = false;
    /**
     * 相机 管理类
     */
    private CameraManager manager;

    private SenseAdapter sAdapter;
    private EffectAdapter effectAdapter;
    /**
     * 图片保存名称
     */
    private String fileName;
    /**
     * 静态大小
     */
    private Size largest;
    private Surface surface;
    /**
     * 是否正在录制中
     */
    private boolean isRecording = false;

    @Override
    protected int getLayoutId() {
        return R.layout.activity_google_camera;
    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    protected void initView() {
        mShowAction = new TranslateAnimation(Animation.RELATIVE_TO_SELF,
                0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
                Animation.RELATIVE_TO_SELF, -1.0f,
                Animation.RELATIVE_TO_SELF, 0.0f);
        mShowAction.setDuration(300);

        mScaleWindowAnimation = new ScaleAnimation(2.0f, 1.0f, 2.0f,
                1.0f, Animation.RELATIVE_TO_SELF, 0.5f,
                Animation.RELATIVE_TO_SELF, 0.5f);
        mScaleWindowAnimation.setDuration(300);

        mAlphaInAnimation = new AlphaAnimation(0.0f, 1.0f);
        mAlphaInAnimation.setDuration(500);
        mAlphaOutAnimation = new AlphaAnimation(1.0f, 0.0f);
        mAlphaOutAnimation.setDuration(500);
        mMediaRecorder = new MediaRecorder();
        txtWindowTxt.setmAnimation(mScaleWindowAnimation);
        sbAe.setOnSeekBarChangeListener(new CameraSeekBarListener());
        sbZoom.setOnSeekBarChangeListener(new CameraSeekBarListener());
        sbIso.setOnSeekBarChangeListener(new CameraSeekBarListener());

        LinearLayoutManager ms = new LinearLayoutManager(this);
        ms.setOrientation(LinearLayoutManager.HORIZONTAL);
        LinearLayoutManager ms1 = new LinearLayoutManager(this);
        ms1.setOrientation(LinearLayoutManager.HORIZONTAL);
        evSenseList.setLayoutManager(ms);
        evEffectList.setLayoutManager(ms1);
        sAdapter = new SenseAdapter(this, AppConstant.senseArr);
        effectAdapter = new EffectAdapter(this,AppConstant.effectArr);
        evSenseList.setAdapter(sAdapter);
        evEffectList.setAdapter(effectAdapter);
        //注册 eventbus
        EventBus.getDefault().register(this);
    }

    @Subscribe
    public void onEvent(AnyEventType event) {
        lockFocus();
    }

    @Override
    protected void initData() {

        fileName = System.currentTimeMillis() + ".jpg";
        mFile = new File(getExternalFilesDir(null), fileName);
        // 将底部布局 依次添加到 列表中
        mLayoutList.clear();
        mLayoutList.add(mLayoutBottom);
        mLayoutList.add(layoutAe);
        mLayoutList.add(layoutAwb);
        mLayoutList.add(layoutIso);
        mLayoutList.add(layoutZoom);
        mLayoutList.add(llEffect);
        mLayoutList.add(llSense);

        // AndServer run in the service.
        mServerManager = new ServerManager(this);
        mServerManager.register();
        mServerManager.startServer();
    }


    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    public void onResume() {
        super.onResume();
        startBackgroundThread();
        // 存在关联则打开相机,没有则绑定事件
        if (mTextureView.isAvailable()) {
            openCamera(mTextureView.getWidth(), mTextureView.getHeight());
        } else {
            mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
        }
    }


    /**
     * SurfaceTextureListener  监听事件
     */
    private final TextureView.SurfaceTextureListener mSurfaceTextureListener
            = new TextureView.SurfaceTextureListener() {

        @RequiresApi(api = Build.VERSION_CODES.M)
        @Override
        public void onSurfaceTextureAvailable(SurfaceTexture texture, int width, int height) {
            openCamera(width, height);
        }

        @Override
        public void onSurfaceTextureSizeChanged(SurfaceTexture texture, int width, int height) {
            configureTransform(width, height);
        }

        @Override
        public boolean onSurfaceTextureDestroyed(SurfaceTexture texture) {
            return true;
        }

        @Override
        public void onSurfaceTextureUpdated(SurfaceTexture texture) {
        }
    };

    /**
     * CameraDevice 改变状态时候 调用
     */
    private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {

        @Override
        public void onOpened(@NonNull CameraDevice cameraDevice) {
            //打开相机时会调用此方法。 我们在这里开始相机预览。
            mCameraOpenCloseLock.release();
            mCameraDevice = cameraDevice;
            createCameraPreviewSession();
        }

        @Override
        public void onDisconnected(@NonNull CameraDevice cameraDevice) {
            mCameraOpenCloseLock.release();
            cameraDevice.close();
            mCameraDevice = null;
        }

        @Override
        public void onError(@NonNull CameraDevice cameraDevice, int error) {
            mCameraOpenCloseLock.release();
            cameraDevice.close();
            mCameraDevice = null;
            finish();
        }

    };

    /**
     * ImageReader 的回调对象。 静止图像已准备好保存。
     */
    private final ImageReader.OnImageAvailableListener mOnImageAvailableListener
            = new ImageReader.OnImageAvailableListener() {
        @Override
        public void onImageAvailable(ImageReader reader) {
            Image mImage = reader.acquireNextImage();
            ByteBuffer buffer = mImage.getPlanes()[0].getBuffer();
            byte[] bytes = new byte[buffer.remaining()];
            buffer.get(bytes);
            FileOutputStream output = null;
            try {
                output = new FileOutputStream(mFile);
                output.write(bytes);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                mImage.close();
                if (null != output) {
                    try {
                        output.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            // 其次把文件插入到系统图库
            try {
                MediaStore.Images.Media.insertImage(getContentResolver(),
                        mFile.getAbsolutePath(), fileName, null);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            // 最后通知图库更新
            sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse(mFile.getPath())));
            Toast.makeText(GoogleCameraActivity.this, "保存成功", Toast.LENGTH_SHORT).show();
//            mBackgroundHandler.post(new ImageSaver(reader.acquireNextImage(), mFile));
//            Image image = reader.acquireLatestImage();
//            if (image != null) {
//                int imageWidth = image.getWidth();
//                int imageHeight = image.getHeight();
//                byte[] data68 = Camera2Util.getBytesFromImageAsType(image, 2);
//                int rgb[] = Camera2Util.decodeYUV420SP(data68, imageWidth, imageHeight);
//                Bitmap bitmap2 = Bitmap.createBitmap(rgb, 0, imageWidth,
//                        imageWidth, imageHeight, Bitmap.Config.ARGB_8888);
//                Bitmap d65bitmap = BitmapUtils.rotateMyBitmap(BitmapUtils.ImgaeToNegative(bitmap2));
//                svShow.setBitmap(d65bitmap);
//                image.close();
//            }
//            setResult(AppConstant.RESULT_CODE.RESULT_OK);
//            finish();
        }
    };

    /**
     * 处理与jpg文件捕捉的事件监听(预览)
     */
    private CameraCaptureSession.CaptureCallback mCaptureCallback
            = new CameraCaptureSession.CaptureCallback() {

        private void process(CaptureResult result) {
            switch (mState) {
                case STATE_PREVIEW: {
                    // 预览正常
                    break;
                }
                case STATE_WAITING_LOCK: {
                    Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
                    if (afState == null) {
                        captureStillPicture();
                    } else if (CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED == afState ||
                            CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED == afState) {
                        Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
                        if (aeState == null ||
                                aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED) {
                            mState = STATE_PICTURE_TAKEN;
                            captureStillPicture();
                        } else {
                            runPrecaptureSequence();
                        }
                    }
                    break;
                }
                case STATE_WAITING_PRECAPTURE: {
                    Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
                    if (aeState == null ||
                            aeState == CaptureResult.CONTROL_AE_STATE_PRECAPTURE ||
                            aeState == CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED) {
                        mState = STATE_WAITING_NON_PRECAPTURE;
                    }
                    break;
                }
                case STATE_WAITING_NON_PRECAPTURE: {
                    Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
                    if (aeState == null || aeState != CaptureResult.CONTROL_AE_STATE_PRECAPTURE) {
                        mState = STATE_PICTURE_TAKEN;
                        captureStillPicture();
                    }
                    break;
                }
                default:
                    break;
            }
        }

        @Override
        public void onCaptureProgressed(@NonNull CameraCaptureSession session,
                                        @NonNull CaptureRequest request,
                                        @NonNull CaptureResult partialResult) {
            process(partialResult);
        }

        @Override
        public void onCaptureCompleted(@NonNull CameraCaptureSession session,
                                       @NonNull CaptureRequest request,
                                       @NonNull TotalCaptureResult result) {
            process(result);
        }

    };

    /**
     * 给定摄像机支持的尺寸 否则选择最小的一个尺寸
     *
     * @param choices           相机支持预期输出的尺寸列表
     * @param textureViewWidth  纹理视图相对于传感器坐标的宽度
     * @param textureViewHeight 纹理视图相对于传感器坐标的高度
     * @param maxWidth          最大宽度
     * @param maxHeight         最大高度
     * @param aspectRatio       纵横比
     * @return size
     */
    private static Size chooseOptimalSize(Size[] choices, int textureViewWidth,
                                          int textureViewHeight, int maxWidth, int maxHeight, Size aspectRatio) {

        // 收集至少与预览Surface一样大的支持的分辨率
        List<Size> bigEnough = new ArrayList<>();
        // 收集小于预览Surface的支持的分辨率
        List<Size> notBigEnough = new ArrayList<>();
        int w = aspectRatio.getWidth();
        int h = aspectRatio.getHeight();
        for (Size option : choices) {
            if (option.getWidth() <= maxWidth && option.getHeight() <= maxHeight &&
                    option.getHeight() == option.getWidth() * h / w) {
                if (option.getWidth() >= textureViewWidth &&
                        option.getHeight() >= textureViewHeight) {
                    bigEnough.add(option);
                } else {
                    notBigEnough.add(option);
                }
            }
        }
        // 挑选适合的尺寸
        if (bigEnough.size() > 0) {
            return Collections.min(bigEnough, new CompareSizesByArea());
        } else if (notBigEnough.size() > 0) {
            return Collections.max(notBigEnough, new CompareSizesByArea());
        } else {
            Log.e(TAG, "Couldn't find any suitable preview size");
            return choices[0];
        }
    }

    @Override
    public void onPause() {
        closeCamera();
        stopBackgroundThread();
        super.onPause();
    }

    /**
     * 设置与摄像头相关的成员变量。
     *
     * @param width  摄像机预览的可用大小宽度
     * @param height 相机预览的可用尺寸高度
     */
    @SuppressWarnings("SuspiciousNameCombination")
    private void setUpCameraOutputs(int width, int height) {
        CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
        try {
            for (String cameraId : manager.getCameraIdList()) {
                characteristics = manager.getCameraCharacteristics(cameraId);
                // 仅适用后置摄像头
                Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
                if (facing != null && facing == CameraCharacteristics.LENS_FACING_FRONT) {
                    continue;
                }
                //得到相机支持的流配置(包括支持的图片分辨率等),不支持就返回
                StreamConfigurationMap map = characteristics.get(
                        CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
                if (map == null) {
                    continue;
                }
                List<CaptureRequest.Key<?>> ss = characteristics.getAvailableCaptureRequestKeys();
                Log.e(TAG, ss.toString());
                // 曝光增益 范围
                range1 = characteristics.get(CameraCharacteristics.CONTROL_AE_COMPENSATION_RANGE);
                //获取支持的iso范围
                isoRange = characteristics.get(CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE);
                // 曝光时长
                int[] avails = characteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES);
                // 白平衡
                int[] aa = characteristics.get(CameraCharacteristics.CONTROL_AWB_AVAILABLE_MODES);
                // 最大白平衡数
                Integer maxAwb = characteristics.get(CameraCharacteristics.CONTROL_MAX_REGIONS_AWB);
                //获取曝光时间
                etr = characteristics.get(CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE);




                // 静态图像捕获,选择最大可用大小。
                largest = Collections.max(
                        Arrays.asList(map.getOutputSizes(ImageFormat.JPEG)),
                        new CompareSizesByArea());
                // w: 720  h :960
//                Size largest = Collections.max(
//                        Arrays.asList(map.getOutputSizes(ImageFormat.YUV_420_888)),
//                        new CompareSizesByArea());
//                mImageReader = ImageReader.newInstance(largest.getWidth(), largest.getHeight(),
//                        ImageFormat.YUV_420_888, 2);
                mImageReader = ImageReader.newInstance(largest.getWidth(), largest.getHeight(),
                        ImageFormat.JPEG, 1);
                mImageReader.setOnImageAvailableListener(
                        mOnImageAvailableListener, mBackgroundHandler);

                //了解我们是否需要交换尺寸以获得相对于传感器的预览尺寸
                int displayRotation = getWindowManager().getDefaultDisplay().getRotation();
                mSensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
                boolean swappedDimensions = false;
                switch (displayRotation) {
                    case Surface.ROTATION_0:
                    case Surface.ROTATION_180:
                        if (mSensorOrientation == 90 || mSensorOrientation == 270) {
                            swappedDimensions = true;
                        }
                        break;
                    case Surface.ROTATION_90:
                    case Surface.ROTATION_270:
                        if (mSensorOrientation == 0 || mSensorOrientation == 180) {
                            swappedDimensions = true;
                        }
                        break;
                    default:
                        Log.e(TAG, "Display rotation is invalid: " + displayRotation);
                }
                Point displaySize = new Point();
                activity.getWindowManager().getDefaultDisplay().getSize(displaySize);
                int rotatedPreviewWidth = width;
                int rotatedPreviewHeight = height;
                int maxPreviewWidth = displaySize.x;
                int maxPreviewHeight = displaySize.y;
                //如果需要颠倒方向
                if (swappedDimensions) {
                    rotatedPreviewWidth = height;
                    rotatedPreviewHeight = width;
                    maxPreviewWidth = displaySize.y;
                    maxPreviewHeight = displaySize.x;
                }

                if (maxPreviewWidth > MAX_PREVIEW_WIDTH) {
                    maxPreviewWidth = MAX_PREVIEW_WIDTH;
                }
                if (maxPreviewHeight > MAX_PREVIEW_HEIGHT) {
                    maxPreviewHeight = MAX_PREVIEW_HEIGHT;
                }

                mPreviewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class),
                        rotatedPreviewWidth, rotatedPreviewHeight, maxPreviewWidth,
                        maxPreviewHeight, largest);

                // 将TextureView的宽高比与我们选择的预览大小相匹配。
                int orientation = getResources().getConfiguration().orientation;
                if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
                    mTextureView.setAspectRatio(
                            mPreviewSize.getWidth(), mPreviewSize.getHeight());
                } else {
                    mTextureView.setAspectRatio(
                            mPreviewSize.getHeight(), mPreviewSize.getWidth());
                }

                // 检查 远光灯
                Boolean available = characteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE);
                mFlashSupported = available == null ? false : available;
                mCameraId = cameraId;
                return;
            }
        } catch (CameraAccessException e) {
            e.printStackTrace();
        } catch (NullPointerException ignored) {
        }
    }

    /**
     * 打开相机
     *
     * @param width  宽度
     * @param height 长度
     */
    @RequiresApi(api = Build.VERSION_CODES.M)
    private void openCamera(int width, int height) {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
                != PackageManager.PERMISSION_GRANTED) {
            requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
            return;
        }
        setUpCameraOutputs(width, height);
        configureTransform(width, height);
        manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
        try {
            if (!mCameraOpenCloseLock.tryAcquire(2300, TimeUnit.MILLISECONDS)) {
                throw new RuntimeException("Time out waiting to lock camera opening.");
            }
            manager.openCamera(mCameraId, mStateCallback, mBackgroundHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            throw new RuntimeException("Interrupted while trying to lock camera opening.", e);
        }
    }

    /**
     * Closes the current {@link CameraDevice}.
     */
    private void closeCamera() {
        try {
            mCameraOpenCloseLock.acquire();
            if (null != mCaptureSession) {
                mCaptureSession.close();
                mCaptureSession = null;
            }
            if (null != mCameraDevice) {
                mCameraDevice.close();
                mCameraDevice = null;
            }
            if (null != mImageReader) {
                mImageReader.close();
                mImageReader = null;
            }
        } catch (InterruptedException e) {
            throw new RuntimeException("Interrupted while trying to lock camera closing.", e);
        } finally {
            mCameraOpenCloseLock.release();
        }
    }

    /**
     * 打开 BackgroundThread
     */
    private void startBackgroundThread() {
        mBackgroundThread = new HandlerThread("CameraBackground");
        mBackgroundThread.start();
        mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
    }

    /**
     * 关闭 BackgroundThread
     */
    private void stopBackgroundThread() {
        mBackgroundThread.quitSafely();
        try {
            mBackgroundThread.join();
            mBackgroundThread = null;
            mBackgroundHandler = null;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建一个新的相机预览
     */
    private void createCameraPreviewSession() {
        try {
            SurfaceTexture texture = mTextureView.getSurfaceTexture();
            //将默认缓冲区的大小配置为相机预览的大小。
            texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
            surface = new Surface(texture);
            //使用Surface设置CaptureRequest.Builder
            mPreviewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
            mPreviewRequestBuilder.addTarget(surface);
            //添加这句话 可以在 mImageReader 监听回调中持续获取 预览图片
//            mPreviewRequestBuilder.addTarget(mImageReader.getSurface());
            mCameraDevice.createCaptureSession(Arrays.asList(surface, mImageReader.getSurface()),
                    new CameraCaptureSession.StateCallback() {

                        @Override
                        public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
                            if (null == mCameraDevice) {
                                return;
                            }
                            mCaptureSession = cameraCaptureSession;
                            try {
                                // 自动变焦是连续的
                                mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
                                        CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
                                setAutoFlash(mPreviewRequestBuilder);
                                //禁用所有自动设置
//                                mPreviewRequestBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_OFF);
                                //而 ISO 和 Exposure Time 与之相反,仅在 aeMode 关闭时才起作用
                                //只是禁用自动曝光,白平衡继续开启,自己设置iso等值,必须禁用曝光
                                mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_OFF);
                                //设置曝光时间 ms单位
//                                mPreviewRequestBuilder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, 1000L);
//                                mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, 1);
                                // 设置 iso 灵敏度
                                mPreviewRequestBuilder.set(CaptureRequest.SENSOR_SENSITIVITY, 800);
//                                mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CaptureRequest.CONTROL_AWB_MODE_AUTO);
                                //设置曝光补偿
//                                mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, 10);
                                // 设置帧 持续时长
//                                mPreviewRequestBuilder.set(CaptureRequest.SENSOR_FRAME_DURATION, 1000L);
                                mPreviewRequest = mPreviewRequestBuilder.build();
                                mCaptureSession.setRepeatingRequest(mPreviewRequest,
                                        mCaptureCallback, mBackgroundHandler);
                                SetListener();
                            } catch (CameraAccessException e) {
                                e.printStackTrace();
                            }
                        }

                        @Override
                        public void onConfigureFailed(
                                @NonNull CameraCaptureSession cameraCaptureSession) {
                        }
                    }, null
            );
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    /**
     * Matrix 转换配置为 mTextureView
     *
     * @param viewWidth  mTextureView 宽度
     * @param viewHeight mTextureView 高度
     */
    private void configureTransform(int viewWidth, int viewHeight) {
        if (null == mTextureView || null == mPreviewSize) {
            return;
        }
        int rotation = getWindowManager().getDefaultDisplay().getRotation();
        Matrix matrix = new Matrix();
        RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);
        RectF bufferRect = new RectF(0, 0, mPreviewSize.getHeight(), mPreviewSize.getWidth());
        float centerX = viewRect.centerX();
        float centerY = viewRect.centerY();
        if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {
            bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());
            matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);
            float scale = Math.max(
                    (float) viewHeight / mPreviewSize.getHeight(),
                    (float) viewWidth / mPreviewSize.getWidth());
            matrix.postScale(scale, scale, centerX, centerY);
            matrix.postRotate(90 * (rotation - 2), centerX, centerY);
        } else if (Surface.ROTATION_180 == rotation) {
            matrix.postRotate(180, centerX, centerY);
        }
        mTextureView.setTransform(matrix);
    }

    /**
     * 锁定焦点设置
     */
    public void lockFocus() {
        try {
            // 相机锁定的方法
            mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
                    CameraMetadata.CONTROL_AF_TRIGGER_START);
            // mCaptureCallback 等待锁定
            mState = STATE_WAITING_LOCK;
            mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,
                    mBackgroundHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
            Log.e(TAG, "lockFocus: " + e.getMessage());
        }
    }

    /**
     * 运行预捕获序列以捕获静止图像。 在调用此方法时调用
     */
    private void runPrecaptureSequence() {
        try {
            // 相机触发的方法
            mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
                    CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
            // mCaptureCallback等待设置预捕获序列。
            mState = STATE_WAITING_PRECAPTURE;
            mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,
                    mBackgroundHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    /**
     * 拍摄静止图片。 当我们得到响应时,应该调用此方法
     */
    private void captureStillPicture() {
        try {
            if (null == activity || null == mCameraDevice) {
                return;
            }
            final CaptureRequest.Builder captureBuilder =
                    mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
            captureBuilder.addTarget(mImageReader.getSurface());

            // 使用与预览相同的AE和AF模式。
            captureBuilder.set(CaptureRequest.CONTROL_AF_MODE,
                    CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
            setAutoFlash(captureBuilder);

            int rotation = getWindowManager().getDefaultDisplay().getRotation();
            //对于方向为90的设备,我们只需从ORIENTATIONS返回我们的映射
            //对于方向为270的设备,我们需要将JPEG旋转180度
            captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, (ORIENTATIONS.get(rotation) + mSensorOrientation + 270) % 360);

            CameraCaptureSession.CaptureCallback CaptureCallback
                    = new CameraCaptureSession.CaptureCallback() {

                @Override
                public void onCaptureCompleted(@NonNull CameraCaptureSession session,
                                               @NonNull CaptureRequest request,
                                               @NonNull TotalCaptureResult result) {
                    Log.e(TAG, mFile.toString());
                    unlockFocus();
                }
            };

            mCaptureSession.stopRepeating();
            mCaptureSession.abortCaptures();
            mCaptureSession.capture(captureBuilder.build(), CaptureCallback, mBackgroundHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    /**
     * 解锁焦点 在静止图像捕获序列时调用此方法
     */
    private void unlockFocus() {
        try {
            // Reset the auto-focus trigger
            mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
                    CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
            setAutoFlash(mPreviewRequestBuilder);
            mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,
                    mBackgroundHandler);
            // After this, the camera will go back to the normal state of preview.
            mState = STATE_PREVIEW;
            mCaptureSession.setRepeatingRequest(mPreviewRequest, mCaptureCallback,
                    mBackgroundHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    /**
     * 更新 Preview
     */
    private void updatePreview() {
        try {
            mPreviewRequest = mPreviewRequestBuilder.build();
            mCaptureSession.setRepeatingRequest(mPreviewRequest, mCaptureCallback,
                    mBackgroundHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    @SuppressLint("MissingPermission")
    @OnClick({R.id.iv_back_g, R.id.iv_flash, R.id.iv_ae, R.id.iv_awb, R.id.iv_iso,R.id.img_camera_g,
            R.id.iv_zoom, R.id.iv_change_camera, R.id.iv_effect, R.id.iv_sense, R.id.iv_images})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.img_camera_g: {
                lockFocus();
                break;
            }
            case R.id.iv_back_g: {
                finish();
                break;
            }
            case R.id.iv_images: {
                // 挑选 相册信息  https://www.jianshu.com/p/498c9d06c193
                break;
            }
            case R.id.iv_zoom: {
                showZoomFlag = !showZoomFlag;
                showLayout(SHOW_ZOOM, showZoomFlag);
                break;
            }
            case R.id.iv_ae: {
                showAeFlag = !showAeFlag;
                showLayout(SHOW_AE, showAeFlag);
                break;
            }
            case R.id.iv_awb:
                showAwbFlag = !showAwbFlag;
                showLayout(SHOW_AWB, showAwbFlag);
                break;
            case R.id.iv_iso:
                showIsoFlag = !showIsoFlag;
                showLayout(SHOW_ISO, showIsoFlag);
                break;
            case R.id.iv_effect:
                showEffectFlag = !showEffectFlag;
                showLayout(SHOW_EFFECT, showEffectFlag);
                break;
            case R.id.iv_sense:
                showSenseFlag = !showSenseFlag;
                showLayout(SHOW_SENSE, showSenseFlag);
                break;
            case R.id.iv_change_camera: {
                if ("1".equals(mCameraId)) {
                    mCameraId = "0";
                } else if ("0".equals(mCameraId)) {
                    mCameraId = "1";
                } else {
                    mCameraId = "0";
                }
                //关闭相机再开启另外个摄像头
                if (mCaptureSession != null) {
                    mCaptureSession.close();
                    mCaptureSession = null;
                }
                if (mCameraDevice != null) {
                    mCameraDevice.close();
                    mCameraDevice = null;
                }
                try {
                    manager.openCamera(mCameraId, mStateCallback, mBackgroundHandler);
                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }
                break;
            }
            case R.id.iv_flash: {
                if (!mFlashSupported) {
                    Log.e(TAG, "该设备暂不支持 闪光灯");
                    return;
                }
                switch (flishType) {
                    case 0:
                        // 从关闭切换到打开
                        flishType = 1;
                        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
                                CameraMetadata.CONTROL_AE_MODE_ON);
                        mPreviewRequestBuilder.set(CaptureRequest.FLASH_MODE,
                                CameraMetadata.FLASH_MODE_SINGLE);
                        ivFlash.setImageResource(R.mipmap.btn_flash_on_normal);
                        break;
                    case 1:
                        //从打开切换到 自动
                        flishType = 2;
                        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
                                CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH);
                        ivFlash.setImageResource(R.mipmap.btn_flash_auto_normal);
                        break;
                    case 2:
                        //自动切换到关闭
                        flishType = 0;
                        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
                                CameraMetadata.CONTROL_AE_MODE_ON);
                        mPreviewRequestBuilder.set(CaptureRequest.FLASH_MODE,
                                CameraMetadata.FLASH_MODE_OFF);
                        ivFlash.setImageResource(R.mipmap.btn_flash_off_normal);
                        break;
                    default:
                        break;
                }
                updatePreview();
            }
            default:
                break;
        }
    }

    private void setAutoFlash(CaptureRequest.Builder requestBuilder) {
        if (mFlashSupported) {
            requestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
                    CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
        }
    }

    /**
     * 显示和隐藏控件
     *
     * @param showWhat
     * @param showOrNot
     */
    private void showLayout(int showWhat, boolean showOrNot) {
        View v = mLayoutList.get(showWhat);
        if (showOrNot) {
            //全部隐藏但是AF/AE的显示出来
            for (int i = 0; i < mLayoutBottom.getChildCount(); i++) {
                if (mLayoutBottom.getChildAt(i).getVisibility() == View.VISIBLE) {
                    mLayoutBottom.getChildAt(i).setVisibility(View.INVISIBLE);
                }
            }
            v.startAnimation(mShowAction);
            v.setVisibility(View.VISIBLE);
        } else {
            //全部隐藏但是capture的显示出来
            for (int i = 0; i < mLayoutBottom.getChildCount(); i++) {
                if (mLayoutBottom.getChildAt(i).getVisibility() == View.VISIBLE) {
                    mLayoutBottom.getChildAt(i).setVisibility(View.INVISIBLE);
                }
            }
            mLayoutCapture.startAnimation(mShowAction);
            mLayoutCapture.setVisibility(View.VISIBLE);
        }
    }

    /**
     * switch 修改事件
     *
     * @param buttonView view
     * @param isChecked  boolean
     */
    @OnCheckedChanged({R.id.switch_ae, R.id.switch_iso})
    public void CameraOnCheckChangedListener(CompoundButton buttonView, boolean isChecked) {
        //翻转的时候mPreviewRequestBuilder变为了null,会挂掉
        if (mPreviewRequestBuilder == null) {
            return;
        }
        switch (buttonView.getId()) {
       
Download .txt
gitextract_43xg_rh9/

├── .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
│       │   │       ├── 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/
│       │       │   ├── ic_camera.xml
│       │       │   ├── ic_fouces.xml
│       │       │   ├── ic_launcher_background.xml
│       │       │   └── ic_launcher_camera.xml
│       │       ├── drawable-v24/
│       │       │   └── ic_launcher_foreground.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-xhdpi/
│       │       │   ├── ic_launcher_background.xml
│       │       │   └── icon_back.xml
│       │       ├── 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/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
Download .txt
SYMBOL INDEX (735 symbols across 51 files)

FILE: app/src/androidTest/java/camera/cn/cameramaster/ExampleInstrumentedTest.java
  class ExampleInstrumentedTest (line 17) | @RunWith(AndroidJUnit4.class)
    method useAppContext (line 19) | @Test

FILE: app/src/main/java/camera/cn/cameramaster/OpenReceiver.java
  class OpenReceiver (line 19) | public class OpenReceiver  extends BroadcastReceiver {
    method onReceive (line 20) | @Override

FILE: app/src/main/java/camera/cn/cameramaster/adapter/EffectAdapter.java
  class EffectAdapter (line 26) | public class EffectAdapter extends RecyclerView.Adapter<EffectAdapter.Ef...
    method EffectAdapter (line 30) | public EffectAdapter(Context mContext,String[] arr) {
    method onCreateViewHolder (line 35) | @NonNull
    method onBindViewHolder (line 41) | @Override
    method getItemCount (line 46) | @Override
    class EffectViewHolder (line 51) | public class EffectViewHolder extends RecyclerView.ViewHolder implemen...
      method EffectViewHolder (line 55) | EffectViewHolder(View view) {
      method onClick (line 61) | @Override
    type EffectOnItemClickListener (line 71) | public interface EffectOnItemClickListener {
      method itemOnClick (line 73) | void itemOnClick(int position);
    method setEffectOnItemClickListener (line 77) | public void setEffectOnItemClickListener(EffectOnItemClickListener eff...

FILE: app/src/main/java/camera/cn/cameramaster/adapter/MenuAdapter.java
  class MenuAdapter (line 25) | public class MenuAdapter extends RecyclerView.Adapter<MenuAdapter.ItemVi...
    method MenuAdapter (line 32) | public MenuAdapter(Context context, List<String> ages, AutoLocateHoriz...
    method onCreateViewHolder (line 38) | @NonNull
    method onBindViewHolder (line 45) | @Override
    method getItemCount (line 50) | @Override
    method getItemView (line 55) | @Override
    method onViewSelected (line 60) | @Override
    class ItemViewHolder (line 73) | class ItemViewHolder extends RecyclerView.ViewHolder{
      method ItemViewHolder (line 75) | ItemViewHolder(View itemView) {

FILE: app/src/main/java/camera/cn/cameramaster/adapter/SenseAdapter.java
  class SenseAdapter (line 26) | public class SenseAdapter extends RecyclerView.Adapter<SenseAdapter.Effe...
    method SenseAdapter (line 30) | public SenseAdapter(Context mContext,String[] arr) {
    method onCreateViewHolder (line 35) | @NonNull
    method onBindViewHolder (line 41) | @Override
    method getItemCount (line 46) | @Override
    class EffectViewHolder (line 51) | public class EffectViewHolder extends RecyclerView.ViewHolder implemen...
      method EffectViewHolder (line 55) | EffectViewHolder(View view) {
      method onClick (line 61) | @Override
    type SenseOnItemClickListener (line 71) | public interface SenseOnItemClickListener {
      method itemOnClick (line 73) | void itemOnClick(int position);
    method setSenseOnItemClickListener (line 77) | public void setSenseOnItemClickListener(SenseOnItemClickListener sense...

FILE: app/src/main/java/camera/cn/cameramaster/base/App.java
  class App (line 37) | public class App extends Application {
    method onCreate (line 43) | @Override
    method getInstance (line 53) | @NonNull
    method getRootDir (line 58) | @NonNull
    method initRootPath (line 63) | private void initRootPath(Context context) {

FILE: app/src/main/java/camera/cn/cameramaster/base/BaseActivity.java
  class BaseActivity (line 27) | public abstract class BaseActivity extends AppCompatActivity {
    method onCreate (line 32) | @Override
    method initStatusColor (line 53) | private void initStatusColor() {
    method getLayoutId (line 69) | protected abstract int getLayoutId();
    method initView (line 70) | protected abstract void initView();
    method initData (line 71) | protected abstract void initData();
    method onDestroy (line 73) | @Override

FILE: app/src/main/java/camera/cn/cameramaster/bean/Lab.java
  class Lab (line 13) | public class Lab {
    method getL (line 19) | public double getL() {
    method setL (line 23) | public void setL(double l) {
    method getA (line 27) | public double getA() {
    method setA (line 31) | public void setA(double a) {
    method getB (line 35) | public double getB() {
    method setB (line 39) | public void setB(double b) {
    method toString (line 43) | @Override

FILE: app/src/main/java/camera/cn/cameramaster/filter/AFilter.java
  class AFilter (line 28) | public abstract class AFilter {
    method AFilter (line 106) | public AFilter(Resources mRes){
    method create (line 111) | public final void create(){
    method setSize (line 115) | public final void setSize(int width,int height){
    method draw (line 119) | public void draw(){
    method setMatrix (line 127) | public void setMatrix(float[] matrix){
    method getMatrix (line 131) | public float[] getMatrix(){
    method setTextureType (line 135) | public final void setTextureType(int type){
    method getTextureType (line 139) | public final int getTextureType(){
    method getTextureId (line 143) | public final int getTextureId(){
    method setTextureId (line 147) | public final void setTextureId(int textureId){
    method setFlag (line 151) | public void setFlag(int flag){
    method getFlag (line 155) | public int getFlag(){
    method setFloat (line 159) | public void setFloat(int type,float ... params){
    method setInt (line 165) | public void setInt(int type,int ... params){
    method setBool (line 171) | public void setBool(int type,boolean ... params){
    method getBool (line 178) | public boolean getBool(int type,int index) {
    method getInt (line 186) | public int getInt(int type,int index){
    method getFloat (line 197) | public float getFloat(int type,int index){
    method getOutputTexture (line 208) | public int getOutputTexture(){
    method onCreate (line 215) | protected abstract void onCreate();
    method onSizeChanged (line 216) | protected abstract void onSizeChanged(int width,int height);
    method createProgram (line 218) | protected final void createProgram(String vertex, String fragment){
    method createProgramByAssetsFile (line 226) | protected final void createProgramByAssetsFile(String vertex, String f...
    method initBuffer (line 233) | protected void initBuffer(){
    method onUseProgram (line 246) | protected void onUseProgram(){
    method onDraw (line 253) | protected void onDraw(){
    method onClear (line 266) | protected void onClear(){
    method onSetExpandData (line 274) | protected void onSetExpandData(){
    method onBindTexture (line 281) | protected void onBindTexture(){
    method glError (line 287) | public static void glError(int code,Object index){
    method uRes (line 294) | public static String uRes(Resources mRes, String path){
    method uCreateGlProgram (line 310) | public static int uCreateGlProgram(String vertexSource, String fragmen...
    method uLoadShader (line 336) | public static int uLoadShader(int shaderType,String source){

FILE: app/src/main/java/camera/cn/cameramaster/filter/TextureFilter.java
  class TextureFilter (line 16) | public class TextureFilter extends  AFilter{
    method TextureFilter (line 32) | public TextureFilter(Resources mRes) {
    method onCreate (line 36) | @Override
    method onSizeChanged (line 41) | @Override

FILE: app/src/main/java/camera/cn/cameramaster/server/AnyEventType.java
  class AnyEventType (line 13) | public class AnyEventType {
    method AnyEventType (line 15) | public AnyEventType(){}

FILE: app/src/main/java/camera/cn/cameramaster/server/CoreService.java
  class CoreService (line 38) | public class CoreService extends Service {
    method onCreate (line 42) | @Override
    method onStartCommand (line 71) | @Override
    method onDestroy (line 77) | @Override
    method startServer (line 86) | private void startServer() {
    method stopServer (line 98) | private void stopServer() {
    method onBind (line 102) | @Nullable

FILE: app/src/main/java/camera/cn/cameramaster/server/ServerManager.java
  class ServerManager (line 34) | public class ServerManager extends BroadcastReceiver {
    method onServerStart (line 50) | public static void onServerStart(Context context, String hostAddress) {
    method onServerError (line 59) | public static void onServerError(Context context, String error) {
    method onServerStop (line 68) | public static void onServerStop(Context context) {
    method sendBroadcast (line 72) | private static void sendBroadcast(Context context, int cmd) {
    method sendBroadcast (line 76) | private static void sendBroadcast(Context context, int cmd, String mes...
    method ServerManager (line 86) | public ServerManager(GoogleCameraActivity activity) {
    method register (line 94) | public void register() {
    method unRegister (line 102) | public void unRegister() {
    method startServer (line 106) | public void startServer() {
    method stopServer (line 110) | public void stopServer() {
    method onReceive (line 114) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)

FILE: app/src/main/java/camera/cn/cameramaster/server/TestController.java
  class TestController (line 46) | @RestController
    method takeCamera (line 55) | @ResponseBody
    method info (line 61) | @GetMapping(path = "/get/{userId}", produces = MediaType.APPLICATION_J...
    method login (line 66) | @PostMapping(path = "/login", produces = MediaType.APPLICATION_JSON_UT...
    method userInfo (line 77) | @Addition(stringType = "login", booleanType = true)
    method upload (line 87) | @PostMapping(path = "/upload", produces = MediaType.APPLICATION_JSON_U...
    method consume (line 94) | @GetMapping(path = "/consume", consumes = {"application/json", "!appli...
    method produce (line 99) | @GetMapping(path = "/produce", produces = {"application/json; charset=...
    method include (line 104) | @GetMapping(path = "/include", params = {"name=123"})
    method exclude (line 109) | @GetMapping(path = "/exclude", params = "name!=123")
    method getMustKey (line 114) | @GetMapping(path = {"/mustKey", "/getName"}, params = "name")
    method postMustKey (line 119) | @PostMapping(path = {"/mustKey", "/postName"}, params = "name")
    method noName (line 124) | @GetMapping(path = "/noName", params = "!name")
    method forPart (line 129) | @PostMapping(path = "/formPart")
    method jsonBody (line 134) | @PostMapping(path = "/jsonBody")
    method jsonBody (line 139) | @PostMapping(path = "/listBody")

FILE: app/src/main/java/camera/cn/cameramaster/server/component/LoggerInterceptor.java
  class LoggerInterceptor (line 36) | @Interceptor
    method onIntercept (line 41) | @Override

FILE: app/src/main/java/camera/cn/cameramaster/server/model/UserInfo.java
  class UserInfo (line 18) | public class UserInfo implements Parcelable {
    method createFromParcel (line 26) | @Override
    method newArray (line 31) | @Override
    method describeContents (line 37) | @Override
    method writeToParcel (line 42) | @Override
    method UserInfo (line 48) | public UserInfo() {
    method UserInfo (line 51) | protected UserInfo(Parcel in) {
    method getmUserId (line 56) | public String getmUserId() {
    method setmUserId (line 60) | public void setmUserId(String mUserId) {
    method getmUserName (line 64) | public String getmUserName() {
    method setmUserName (line 68) | public void setmUserName(String mUserName) {

FILE: app/src/main/java/camera/cn/cameramaster/server/util/FileUtils.java
  class FileUtils (line 33) | public class FileUtils {
    method createRandomFile (line 42) | public static File createRandomFile(MultipartFile file) {
    method storageAvailable (line 56) | public static boolean storageAvailable() {

FILE: app/src/main/java/camera/cn/cameramaster/server/util/NetUtils.java
  class NetUtils (line 27) | public class NetUtils {
    method isIPv4Address (line 43) | public static boolean isIPv4Address(String input) {
    method getLocalIPAddress (line 50) | public static InetAddress getLocalIPAddress() {

FILE: app/src/main/java/camera/cn/cameramaster/ui/Camera2Activity.java
  class Camera2Activity (line 56) | public class Camera2Activity extends BaseActivity {
    method getLayoutId (line 95) | @Override
    method initView (line 100) | @Override
    method initData (line 105) | @Override
    method onClick (line 110) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    method startCamera (line 128) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    method takePicture (line 142) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    method onCaptureCompleted (line 175) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    method onCaptureFailed (line 190) | @Override
    method onSurfaceTextureAvailable (line 201) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    method onSurfaceTextureSizeChanged (line 209) | @Override
    method onSurfaceTextureDestroyed (line 213) | @Override
    method onSurfaceTextureUpdated (line 219) | @Override
    method openCamera (line 228) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    method setCameraCharacteristics (line 250) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    class CompareSizesByArea (line 279) | static class CompareSizesByArea implements Comparator<Size> {
      method compare (line 280) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    method chooseOptimalSize (line 288) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    method onOpened (line 314) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    method onDisconnected (line 323) | @Override
    method onError (line 329) | @Override
    method takePreview (line 338) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    method stopCamera (line 379) | private void stopCamera() {
    method onImageAvailable (line 391) | @Override
    method onPause (line 420) | @Override
    method onResume (line 428) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)

FILE: app/src/main/java/camera/cn/cameramaster/ui/CameraActivity.java
  class CameraActivity (line 39) | public class CameraActivity extends BaseActivity implements SurfaceHolde...
    method getLayoutId (line 85) | @Override
    method initView (line 90) | @Override
    method initData (line 96) | @Override
    method onResume (line 105) | @Override
    method OnClick (line 116) | @OnClick({R.id.img_camera, R.id.camera_flash, R.id.camera_switch, R.id...
    method switchCamera (line 188) | public void switchCamera() {
    method takePhoto (line 200) | private void takePhoto() {
    method surfaceCreated (line 231) | @Override
    method surfaceChanged (line 236) | @Override
    method surfaceDestroyed (line 242) | @Override
    method releaseCamera (line 250) | private void releaseCamera() {
    method startPreview (line 262) | private void startPreview(Camera camera, SurfaceHolder holder) {
    method setupCamera (line 297) | private void setupCamera(Camera camera) {
    method getCamera (line 325) | private Camera getCamera(int id) {

FILE: app/src/main/java/camera/cn/cameramaster/ui/CameraSurfaceViewActivity.java
  class CameraSurfaceViewActivity (line 28) | public class CameraSurfaceViewActivity extends BaseActivity {
    method getLayoutId (line 35) | @Override
    method initView (line 40) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    method initData (line 63) | @Override
    method onClick (line 68) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    method onResume (line 84) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    method onPause (line 93) | @Override
    method onDestroy (line 100) | @Override

FILE: app/src/main/java/camera/cn/cameramaster/ui/CameraVideoActivity.java
  class CameraVideoActivity (line 81) | @RequiresApi(api = Build.VERSION_CODES.M)
    method run (line 272) | @Override
    method run (line 281) | @Override
    method run (line 290) | @Override
    method colorTemperature (line 309) | public static RggbChannelVector colorTemperature(int whiteBalance) {
    method getLayoutId (line 363) | @Override
    method initView (line 368) | @Override
    method initData (line 422) | @Override
    method initVideoMode (line 433) | private void initVideoMode() {
    method initCameraMode (line 478) | @RequiresApi(api = Build.VERSION_CODES.M)
    method initCamera (line 523) | private void initCamera(ICamera2.CameraType cameraType) {
    method initScaleSeekbar (line 538) | private void initScaleSeekbar() {
    method cameraOnClickListener (line 567) | @RequiresApi(api = Build.VERSION_CODES.M)
    method onSensorChanged (line 611) | @Override
    method registerSensor (line 637) | private void registerSensor() {
    method onAccuracyChanged (line 654) | @Override
    method onSeekTime (line 659) | @Override
    method onStartListener (line 677) | @Override
    method onCompletionListener (line 684) | @Override
    method onTakePhotoFinish (line 700) | @Override
    method onCameraReady (line 722) | @Override
    method selectedPositionChanged (line 732) | @Override
    method recordCountDown (line 781) | @SuppressLint("SetTextI18n")
    method recordVideoOrTakePhoto (line 820) | @OnClick(R.id.video_record)
    method deleteVideoOrPicture (line 884) | @OnClick(R.id.video_delete)
    method saveVideoOrPhoto (line 921) | @OnClick(R.id.video_save)
    method removeImageFoucesRunnable (line 942) | private void removeImageFoucesRunnable() {
    method imageFoucesDelayedHind (line 949) | private void imageFoucesDelayedHind() {
    method seekBarDelayedHind (line 956) | private void seekBarDelayedHind() {
    method removeSeekBarRunnable (line 966) | private void removeSeekBarRunnable() {
    method showRecordEndView (line 974) | private void showRecordEndView() {
    method hindVideoRecordSeekBar (line 982) | private void hindVideoRecordSeekBar() {
    method closeCamera (line 990) | private void closeCamera() {
    method playVideo (line 999) | private void playVideo() {
    method moveFouces (line 1015) | private void moveFouces(int x, int y) {
    method onResume (line 1027) | @Override
    method onPause (line 1085) | @Override
    method hindSwitchCamera (line 1106) | private void hindSwitchCamera() {
    method hindMenu (line 1113) | private void hindMenu() {
    method saveMedia (line 1122) | private void saveMedia(File mediaFile) {
    method hindRecordEndView (line 1132) | private void hindRecordEndView() {
    method hindPlayView (line 1140) | private void hindPlayView() {
    method showPlayView (line 1150) | private void showPlayView() {
    method showLayout (line 1163) | private void showLayout(int showWhat, boolean showOrNot) {
    method initListener (line 1189) | private void initListener() {
    class HorizontalViewTouchListener (line 1293) | private class HorizontalViewTouchListener implements View.OnTouchListe...
      method onTouch (line 1299) | @Override
    class CameraTouch (line 1345) | private class CameraTouch {
      method onScale (line 1352) | public void onScale(MotionEvent event) {
      method onScaleStart (line 1386) | public void onScaleStart(MotionEvent event) {
      method onScaleEnd (line 1398) | private void onScaleEnd(MotionEvent event) {
      method resetScale (line 1416) | public void resetScale() {
      method setScale (line 1423) | public void setScale(float scale) {
      method distance (line 1435) | private float distance(MotionEvent event) {
      method setScaleMax (line 1442) | private void setScaleMax(int max) {
    class FoucesAnimation (line 1450) | private class FoucesAnimation extends Animation {
      method applyTransformation (line 1458) | @Override
      method setOldMargin (line 1478) | public void setOldMargin(int oldMarginLeft, int oldMarginTop) {
    class CameraSeekBarListener (line 1489) | private class CameraSeekBarListener implements SeekBar.OnSeekBarChange...
      method onProgressChanged (line 1491) | @Override
      method onStartTrackingTouch (line 1527) | @Override
      method onStopTrackingTouch (line 1533) | @Override
    class awbSettingSeekBarListener (line 1543) | private class awbSettingSeekBarListener implements SeekBar.OnSeekBarCh...
      method onProgressChanged (line 1545) | @Override
      method onStartTrackingTouch (line 1555) | @Override
      method onStopTrackingTouch (line 1560) | @Override

FILE: app/src/main/java/camera/cn/cameramaster/ui/GoogleCameraActivity.java
  class GoogleCameraActivity (line 110) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    method getLayoutId (line 400) | @Override
    method initView (line 405) | @SuppressLint("ClickableViewAccessibility")
    method onEvent (line 443) | @Subscribe
    method initData (line 448) | @Override
    method onResume (line 470) | @RequiresApi(api = Build.VERSION_CODES.M)
    method onSurfaceTextureAvailable (line 490) | @RequiresApi(api = Build.VERSION_CODES.M)
    method onSurfaceTextureSizeChanged (line 496) | @Override
    method onSurfaceTextureDestroyed (line 501) | @Override
    method onSurfaceTextureUpdated (line 506) | @Override
    method onOpened (line 516) | @Override
    method onDisconnected (line 524) | @Override
    method onError (line 531) | @Override
    method onImageAvailable (line 546) | @Override
    method process (line 602) | private void process(CaptureResult result) {
    method onCaptureProgressed (line 647) | @Override
    method onCaptureCompleted (line 654) | @Override
    method chooseOptimalSize (line 674) | private static Size chooseOptimalSize(Size[] choices, int textureViewW...
    method onPause (line 705) | @Override
    method setUpCameraOutputs (line 718) | @SuppressWarnings("SuspiciousNameCombination")
    method openCamera (line 841) | @RequiresApi(api = Build.VERSION_CODES.M)
    method closeCamera (line 866) | private void closeCamera() {
    method startBackgroundThread (line 891) | private void startBackgroundThread() {
    method stopBackgroundThread (line 900) | private void stopBackgroundThread() {
    method createCameraPreviewSession (line 914) | private void createCameraPreviewSession() {
    method configureTransform (line 980) | private void configureTransform(int viewWidth, int viewHeight) {
    method lockFocus (line 1007) | public void lockFocus() {
    method runPrecaptureSequence (line 1025) | private void runPrecaptureSequence() {
    method captureStillPicture (line 1042) | private void captureStillPicture() {
    method unlockFocus (line 1084) | private void unlockFocus() {
    method updatePreview (line 1104) | private void updatePreview() {
    method onClick (line 1114) | @SuppressLint("MissingPermission")
    method setAutoFlash (line 1222) | private void setAutoFlash(CaptureRequest.Builder requestBuilder) {
    method showLayout (line 1235) | private void showLayout(int showWhat, boolean showOrNot) {
    method CameraOnCheckChangedListener (line 1264) | @OnCheckedChanged({R.id.switch_ae, R.id.switch_iso})
    class CameraSeekBarListener (line 1302) | private class CameraSeekBarListener implements SeekBar.OnSeekBarChange...
      method onProgressChanged (line 1304) | @Override
      method onStartTrackingTouch (line 1380) | @Override
      method onStopTrackingTouch (line 1386) | @Override
    method SetListener (line 1396) | private void SetListener() {
    method startRecordingVideo (line 1506) | private void startRecordingVideo() {
    method stopRecordingVideo (line 1557) | private void stopRecordingVideo() {
    method setUpMediaRecorder (line 1571) | private void setUpMediaRecorder() throws IOException {
    method onServerStart (line 1600) | public void onServerStart(String ip) {
    method onServerError (line 1617) | public void onServerError(String message) {
    method onServerStop (line 1626) | public void onServerStop() {
    method showDialog (line 1631) | private void showDialog() {
    method closeDialog (line 1640) | private void closeDialog() {
    method onDestroy (line 1646) | @Override
    method getBuilder (line 1655) | public CaptureRequest.Builder getBuilder() {
    method getSession (line 1659) | public CameraCaptureSession getSession() {

FILE: app/src/main/java/camera/cn/cameramaster/ui/MainActivity.java
  class MainActivity (line 36) | public class MainActivity extends BaseActivity {
    method getLayoutId (line 46) | @Override
    method initView (line 51) | @Override
    method initData (line 57) | @Override
    method setDataConnectionState (line 65) | @SuppressLint("WrongConstant")
    method onClick (line 81) | @OnClick({R.id.btn_camera, R.id.btn_camera2, R.id.btn_filter_camera2, ...
    method onActivityResult (line 106) | @Override
    method requestPermission (line 152) | @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)

FILE: app/src/main/java/camera/cn/cameramaster/ui/ShowPicActivity.java
  class ShowPicActivity (line 22) | public class ShowPicActivity extends BaseActivity {
    method getLayoutId (line 48) | @Override
    method initView (line 53) | @Override
    method initData (line 61) | @Override
    method canvasBitmap (line 82) | private void canvasBitmap(String path) {
    class seekBar1Listen (line 107) | class seekBar1Listen implements SeekBar.OnSeekBarChangeListener {
      method onProgressChanged (line 109) | @Override
      method onStartTrackingTouch (line 122) | @Override
      method onStopTrackingTouch (line 124) | @Override
    class seekBar2Listen (line 131) | class seekBar2Listen implements SeekBar.OnSeekBarChangeListener {
      method onProgressChanged (line 133) | @Override
      method onStartTrackingTouch (line 146) | @Override
      method onStopTrackingTouch (line 148) | @Override
    class seekBar3Listen (line 155) | class seekBar3Listen implements SeekBar.OnSeekBarChangeListener {
      method onProgressChanged (line 157) | @Override
      method onStartTrackingTouch (line 170) | @Override
      method onStopTrackingTouch (line 172) | @Override
    class seekBar4Listen (line 179) | class seekBar4Listen implements SeekBar.OnSeekBarChangeListener {
      method onProgressChanged (line 181) | @Override
      method onStartTrackingTouch (line 194) | @Override
      method onStopTrackingTouch (line 196) | @Override

FILE: app/src/main/java/camera/cn/cameramaster/util/AppConstant.java
  class AppConstant (line 13) | public class AppConstant {
    type KEY (line 86) | public interface KEY{
    type RESULT_CODE (line 93) | public interface RESULT_CODE {

FILE: app/src/main/java/camera/cn/cameramaster/util/BitmapUtils.java
  class BitmapUtils (line 38) | public class BitmapUtils {
    method BitmapUtils (line 39) | private BitmapUtils() {
    method getSize (line 59) | private static int getSize(int config) {
    method ReadBitmapById (line 87) | public static Bitmap ReadBitmapById(Context context, int resId) {
    method readBitmap (line 103) | public static byte[] readBitmap(Bitmap bmp) {
    method rotaingImageView (line 123) | public static Bitmap rotaingImageView(int angle, Bitmap bitmap) {
    method setPictureDegree (line 145) | public static void setPictureDegree(String filename, int degree) {
    method getRightSzieBitmap (line 182) | private static Bitmap getRightSzieBitmap(Bitmap bit, int config) {
    method getRightSzieBitmap (line 209) | public static Bitmap getRightSzieBitmap(String fileName, int config) {
    method toGrayscale (line 231) | private static Bitmap toGrayscale(Bitmap bmpOriginal) {
    method replaceBitmapColor (line 247) | public static Bitmap replaceBitmapColor(Bitmap oldBitmap, int oldColor...
    method ImgaeToNegative (line 269) | public static Bitmap ImgaeToNegative(Bitmap bitmap) {
    method toGrayscale (line 354) | public static Bitmap toGrayscale(Bitmap bmpOriginal, int pixels) {
    method toRoundCorner (line 365) | private static Bitmap toRoundCorner(Bitmap bitmap, int pixels) {
    method toRoundCorner (line 395) | @SuppressWarnings("deprecation")
    method saveBefore (line 408) | public static Bitmap saveBefore(String path) {
    method createBitmapBySize (line 437) | public static Bitmap createBitmapBySize(Bitmap bitmap, int width, int ...
    method getImageFromPath (line 442) | public static Bitmap getImageFromPath(String srcPath, float maxWidth, ...
    method decodeBitmapFromResource (line 488) | public static Bitmap decodeBitmapFromResource(Resources res, int resId...
    method calculateInSampleSize (line 513) | public static BitmapFactory.Options calculateInSampleSize(
    method getAlphaBitmap (line 554) | public static Bitmap getAlphaBitmap(Bitmap mBitmap, int mColor) {
    method rotateMyBitmap (line 579) | public static Bitmap rotateMyBitmap(Bitmap bmp) {
    method readPictureDegree (line 597) | public static int readPictureDegree(String path) {
    method savePNG_After (line 628) | public static void savePNG_After(Bitmap bitmap, String name) {
    method saveJPGE_After (line 649) | public static boolean saveJPGE_After(Bitmap bitmap, String path, int q...
    method saveJPGE_After (line 671) | public static void saveJPGE_After(Context context, Bitmap bitmap, Stri...
    method saveJPGE_After_PNG (line 694) | public static void saveJPGE_After_PNG(Context context, Bitmap bitmap, ...
    method saveJPGE_After_WebP (line 717) | public static void saveJPGE_After_WebP(Context context, Bitmap bitmap,...
    method makeDir (line 734) | private static void makeDir(File file) {
    method createBitmap (line 748) | public static Bitmap createBitmap(Bitmap src, Bitmap watermark) {
    method bitmapToDrawableByBD (line 776) | public static Drawable bitmapToDrawableByBD(Bitmap bitmap) {
    method getByteFromBitmap (line 785) | public static byte[] getByteFromBitmap(Bitmap bitmap) {
    method getBitmapFromByte (line 804) | public static Bitmap getBitmapFromByte(byte[] temp) {
    method getBitemapFromFile (line 821) | public static Bitmap getBitemapFromFile(File f) {
    method convertMirrorBmp (line 837) | public Bitmap convertMirrorBmp(Bitmap bmp) {
    method convertVertical (line 854) | public static Bitmap convertVertical(Bitmap bmp) {
    method decodeFile (line 871) | public static Bitmap decodeFile(String path, int screenWidth, int scre...
    method getBitmapFromDrawable (line 907) | public static Bitmap getBitmapFromDrawable(Drawable drawable) {
    method flip (line 927) | public static Bitmap flip(Bitmap bitmap) {
    method getViewBitmap (line 944) | public static Bitmap getViewBitmap(View view) {
    method convertViewToBitmap (line 992) | public static Bitmap convertViewToBitmap(View view) {
    method getBitmapFromView (line 1007) | public static Bitmap getBitmapFromView(View view) {
    method updateResources (line 1017) | public static void updateResources(Context context, String path) {
    method returnSaturationBitmap (line 1021) | public static Bitmap returnSaturationBitmap(Context context, Bitmap bi...
    method createBitmap (line 1053) | public static Bitmap createBitmap(Bitmap bitmap, int reqWidth, int req...
    method getRoundedCornerBitmap (line 1097) | public static Bitmap getRoundedCornerBitmap(Bitmap bitmap) {
    method returnContrastBitmap (line 1121) | public static Bitmap returnContrastBitmap(Bitmap bitmap, int progress) {

FILE: app/src/main/java/camera/cn/cameramaster/util/Camera2Util.java
  class Camera2Util (line 21) | public class Camera2Util {
    method getBytesFromImageAsType (line 32) | @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    method decodeYUV420SP (line 135) | public static int[] decodeYUV420SP(byte[] yuv420sp, int width, int hei...

FILE: app/src/main/java/camera/cn/cameramaster/util/CameraUtil.java
  class CameraUtil (line 19) | public class CameraUtil {
    method CameraUtil (line 32) | private CameraUtil() {
    method getInstance (line 36) | public static CameraUtil getInstance() {
    method getRecorderRotation (line 45) | private int getRecorderRotation(int cameraId) {
    method getPropVideoSize (line 59) | private Size getPropVideoSize(List<Size> list, int minHeight) {
    method setCameraDisplayOrientation (line 82) | public void setCameraDisplayOrientation(Activity activity,
    method setTakePicktrueOrientation (line 118) | public Bitmap setTakePicktrueOrientation(int id, Bitmap bitmap) {
    method rotaingImageView (line 131) | private Bitmap rotaingImageView(int id, int angle, Bitmap bitmap) {
    method getPropPreviewSize (line 152) | private Size getPropPreviewSize(List<Size> list, int minWidth) {
    method getPropPictureSize (line 175) | private Size getPropPictureSize(List<Size> list, int minWidth) {
    method getPropSizeForHeight (line 197) | public Size getPropSizeForHeight(List<Size> list, int minHeight) {
    method getPicPreviewSize (line 220) | public  Size getPicPreviewSize(List<Size> list, int th, int minWidth){
    method getPropPictureSize (line 236) | public Size getPropPictureSize(List<Size> list, float th, int minWidth){
    class CameraAscendSizeComparatorForHeight (line 256) | private class CameraAscendSizeComparatorForHeight implements Comparato...
      method compare (line 257) | @Override
    method equalRate (line 269) | private boolean equalRate(Size s, float rate) {
    class CameraDropSizeComparator (line 277) | private class CameraDropSizeComparator implements Comparator<Size> {
      method compare (line 278) | @Override
    class CameraAscendSizeComparator (line 293) | private class CameraAscendSizeComparator implements Comparator<Size> {
      method compare (line 294) | @Override
    method printSupportPreviewSize (line 311) | private void printSupportPreviewSize(Camera.Parameters params) {
    method printSupportPictureSize (line 324) | private void printSupportPictureSize(Camera.Parameters params) {
    method printSupportFocusMode (line 336) | private void printSupportFocusMode(Camera.Parameters params) {
    method turnLightOn (line 348) | public void turnLightOn(Camera mCamera) {
    method turnLightAuto (line 375) | public void turnLightAuto(Camera mCamera) {
    method turnLightOff (line 402) | public void turnLightOff(Camera mCamera) {

FILE: app/src/main/java/camera/cn/cameramaster/util/CameraV2.java
  class CameraV2 (line 59) | public class CameraV2 {
    method CameraV2 (line 141) | public CameraV2(Activity activity) {
    method setUpCameraOutputs (line 151) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    method startBackgroundThread (line 244) | public void startBackgroundThread() {
    method stopBackgroundThread (line 253) | public void stopBackgroundThread() {
    method openCamera (line 269) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    method onOpened (line 291) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    method onDisconnected (line 300) | @Override
    method onError (line 307) | @Override
    method setPreviewTexture (line 321) | public void setPreviewTexture(SurfaceTexture surfaceTexture) {
    method createCameraPreviewSession (line 328) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    method onImageAvailable (line 374) | @Override
    class CompareSizesByArea (line 385) | static class CompareSizesByArea implements Comparator<Size> {
      method compare (line 387) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    method chooseOptimalSize (line 407) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    method lockFocus (line 442) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    method closeCamera (line 460) | public void closeCamera() {
    method process (line 489) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    method onCaptureProgressed (line 535) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    method onCaptureCompleted (line 543) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    method captureStillPicture (line 557) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    method unlockFocus (line 601) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    method getOrientation (line 624) | private int getOrientation(int rotation) {
    class ImageSaver (line 633) | private static class ImageSaver implements Runnable {
      method ImageSaver (line 637) | ImageSaver(Image image, File file) {
      method run (line 642) | @Override
    method runPrecaptureSequence (line 670) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)

FILE: app/src/main/java/camera/cn/cameramaster/util/CompareSizesByArea.java
  class CompareSizesByArea (line 19) | public class CompareSizesByArea implements Comparator<Size> {
    method compare (line 21) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)

FILE: app/src/main/java/camera/cn/cameramaster/util/FilterEngine.java
  class FilterEngine (line 45) | public class FilterEngine {
    method FilterEngine (line 88) | public FilterEngine(int oestextureid, Context context) {
    method createBuffer (line 107) | private FloatBuffer createBuffer(float[] vertexData) {
    method loadShader (line 124) | private int loadShader(int type, String shaderSource) {
    method linkProgram (line 140) | private int linkProgram(int verShader, int fragShader) {
    method drawTexture (line 155) | public void drawTexture(float[] transformMatrix) {
    method getShaderProgram (line 179) | public int getShaderProgram() {
    method getBuffer (line 183) | public FloatBuffer getBuffer() {
    method getOESTextureId (line 187) | public int getOESTextureId() {
    method setOESTextureId (line 191) | public void setOESTextureId(int OESTextureId) {

FILE: app/src/main/java/camera/cn/cameramaster/util/LabUtil.java
  class LabUtil (line 15) | public class LabUtil {
    method main (line 17) | public static void main(String[] args) {
    method Lab2XYZ (line 48) | public static double[] Lab2XYZ(double[] Lab) {
    method XYZ2Lab (line 99) | public static double[] XYZ2Lab(double[] XYZ) {
    method sRGB2XYZ (line 150) | public static double[] sRGB2XYZ(double[] RGB) {
    method XYZ2sRGB (line 197) | public static double[] XYZ2sRGB(double[] XYZ) {

FILE: app/src/main/java/camera/cn/cameramaster/util/MatrixUtils.java
  type MatrixUtils (line 15) | public enum MatrixUtils {
    method MatrixUtils (line 23) | MatrixUtils(){
    method getShowMatrix (line 30) | @Deprecated
    method getMatrix (line 48) | public static void getMatrix(float[] matrix,int type,int imgWidth,int ...
    method getCenterInsideMatrix (line 96) | public static void getCenterInsideMatrix(float[] matrix,int imgWidth,i...
    method rotate (line 113) | public static float[] rotate(float[] m,float angle){
    method flip (line 118) | public static float[] flip(float[] m,boolean x,boolean y){
    method scale (line 125) | public static float[] scale(float[] m,float x,float y){
    method getOriginalMatrix (line 130) | public static float[] getOriginalMatrix(){

FILE: app/src/main/java/camera/cn/cameramaster/util/Utils.java
  class Utils (line 29) | public class Utils {
    method createOESTextureObject (line 37) | public static int createOESTextureObject() {
    method readShaderFromResource (line 57) | public static String readShaderFromResource(Context context, int resou...
    method getOutputMediaFile (line 100) | public static File getOutputMediaFile(Context mContext, int mediaType) {

FILE: app/src/main/java/camera/cn/cameramaster/util/cameravideo/CameraHelper.java
  class CameraHelper (line 67) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    method getIsoRange (line 217) | public Range<Integer> getIsoRange() {
    method CameraHelper (line 226) | public CameraHelper(Context context) {
    method setShowTextView (line 248) | public void setShowTextView(TextView mTextView){
    method cameraZoom (line 253) | @Override
    method getMaxZoom (line 276) | public float getMaxZoom() {
    method initImageReader (line 283) | private void initImageReader() {
    method initSize (line 299) | private void initSize() {
    method openCamera (line 316) | @RequiresApi(api = Build.VERSION_CODES.M)
    method openCamera (line 403) | @SuppressLint("MissingPermission")
    method closeCamera (line 414) | @Override
    method switchCamera (line 430) | @RequiresApi(api = Build.VERSION_CODES.M)
    method startPreview (line 437) | @Override
    method updatePreview (line 488) | private void updatePreview() {
    method resumePreview (line 505) | @Override
    method startVideoRecord (line 531) | @Override
    method setVideoRecordParam (line 555) | private boolean setVideoRecordParam(String path) {
    method stopVideoRecord (line 592) | @Override
    method takePhone (line 608) | @Override
    method isLegacyLocked (line 658) | private boolean isLegacyLocked() {
    method setup3AControlsLocked (line 663) | private void setup3AControlsLocked(CaptureRequest.Builder builder) {
    method capturePhoto (line 714) | private void capturePhoto() {
    method getPreViewSize (line 768) | @Override
    method setSurface (line 773) | @Override
    method setTextureView (line 783) | @Override
    method setTakePhotoListener (line 788) | @Override
    method setCameraReady (line 793) | @Override
    method flashSwitchState (line 798) | @Override
    method setCameraState (line 807) | @Override
    method toFocusRect (line 816) | private void toFocusRect(RectF rectF) {
    method calcTapAreaForCamera2 (line 823) | private MeteringRectangle calcTapAreaForCamera2(int areaSize, int weig...
    method requestFocus (line 836) | @Override
    method startBackgroundThread (line 885) | public void startBackgroundThread() {
    method stopBackgroundThread (line 894) | public void stopBackgroundThread() {
    method setTakePhotoFlashMode (line 909) | private void setTakePhotoFlashMode(CaptureRequest.Builder builder) {
    method setRecordVideoFlashMode (line 938) | private void setRecordVideoFlashMode(CaptureRequest.Builder builder) {
    method setLight (line 963) | public void setLight(float light) {
    method startRecordVideo (line 970) | private void startRecordVideo() {
    method closePreviewSession (line 1021) | private void closePreviewSession() {
    method destroy (line 1031) | public void destroy() {
    method getOrientation (line 1035) | private int getOrientation(int rotation) {
    method setDeviceRotation (line 1044) | public void setDeviceRotation(int rotation) {
    method doInProgress1 (line 1052) | @Override
    method doInProgress2 (line 1059) | @Override
    method doInProgress3 (line 1066) | @Override
    method doInProgress4 (line 1073) | @Override
    method doInProgress5 (line 1080) | @Override
    method doInProgress6 (line 1087) | @Override
    method doInProgress7 (line 1094) | @Override
    method doInProgress8 (line 1101) | @Override
    method onStopTrackingTouch (line 1108) | @Override
    method onStartTrackingTouch (line 1149) | @Override
    class PhotoSaver (line 1160) | private class PhotoSaver implements Runnable {
      method PhotoSaver (line 1172) | public PhotoSaver(Image image, File file) {
      method run (line 1177) | @Override
    method onCaptureCompleted (line 1213) | @Override
    method onCaptureProgressed (line 1218) | @Override
    method process (line 1223) | private void process(CaptureResult result) {
    method onImageAvailable (line 1274) | @Override
    method onOpened (line 1288) | @Override
    method onDisconnected (line 1294) | @Override
    method onError (line 1300) | @Override
    method chooseVideoSize (line 1307) | private static Size chooseVideoSize(Size[] choices) {
    method chooseOptimalSize (line 1328) | private static Size chooseOptimalSize(Size[] choices, int textureViewW...
    class CompareSizesByArea (line 1363) | static class CompareSizesByArea implements Comparator<Size> {
      method compare (line 1365) | @Override
    method contains (line 1381) | private static boolean contains(int[] modes, int mode) {
    method clamp (line 1393) | private static int clamp(int x, int min, int max) {
    method getVideoFilePath (line 1409) | public String getVideoFilePath() {
    method getPhotoFilePath (line 1421) | public String getPhotoFilePath() {
    method dip2px (line 1433) | public int dip2px(Context context, float dipValue) {
    method secToTime (line 1443) | public String secToTime(int time) {
    method unitFormat (line 1474) | private String unitFormat(int i) {
    method getUriFromFile (line 1490) | public Uri getUriFromFile(Context context, File file) {
    method getRange1 (line 1498) | public Range<Integer> getRange1 (){
    method setAERegions (line 1505) | public void setAERegions(int ae){
    method getEtr (line 1515) | public Range<Long> getEtr(){
    method setAeTime (line 1522) | public void setAeTime(long aeTime){
    method setCameraBuilerMode (line 1533) | public <T> void setCameraBuilerMode(CaptureRequest.Key<T> key, T value) {

FILE: app/src/main/java/camera/cn/cameramaster/util/cameravideo/CoordinateTransformer.java
  class CoordinateTransformer (line 15) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    method CoordinateTransformer (line 27) | public CoordinateTransformer(CameraCharacteristics chr, RectF previewR...
    method toCameraSpace (line 46) | public RectF toCameraSpace(RectF source) {
    method previewToCameraTransform (line 52) | private Matrix previewToCameraTransform(boolean mirrorX, int sensorOri...
    method hasNonZeroArea (line 71) | private boolean hasNonZeroArea(RectF rect) {

FILE: app/src/main/java/camera/cn/cameramaster/util/cameravideo/ICamera2.java
  type ICamera2 (line 13) | public interface ICamera2 {
    method cameraZoom (line 19) | void cameraZoom(float zoom);
    method openCamera (line 24) | boolean openCamera(CameraType cameraType);
    method closeCamera (line 29) | void closeCamera();
    method switchCamera (line 36) | boolean switchCamera(CameraType cameraType);
    method startPreview (line 41) | boolean startPreview();
    method resumePreview (line 46) | void resumePreview();
    method startVideoRecord (line 53) | boolean startVideoRecord(String path, int mediaType);
    method stopVideoRecord (line 58) | void stopVideoRecord();
    method takePhone (line 65) | boolean takePhone(String path, MediaType mediaType);
    method getPreViewSize (line 71) | Size getPreViewSize();
    method setSurface (line 73) | void setSurface(Surface surface);
    method setTextureView (line 75) | void setTextureView(TextureView textureView);
    method setTakePhotoListener (line 77) | void setTakePhotoListener(TakePhotoListener mTakePhotoListener);
    method setCameraReady (line 79) | void setCameraReady(CameraReady mCameraReady);
    method flashSwitchState (line 81) | void flashSwitchState(FlashState mFlashState);
    method setCameraState (line 83) | void setCameraState(CameraMode cameraMode);
    method requestFocus (line 90) | void requestFocus(float x, float y);
    type CameraMode (line 95) | enum CameraMode
    type MediaType (line 104) | enum MediaType
    type CameraType (line 113) | enum CameraType
    type FlashState (line 123) | enum FlashState
    type TakePhotoListener (line 130) | interface TakePhotoListener{
      method onTakePhotoFinish (line 131) | void onTakePhotoFinish(File file, int photoRotation, int width, int ...
    type CameraReady (line 134) | interface CameraReady
      method onCameraReady (line 136) | void onCameraReady();

FILE: app/src/main/java/camera/cn/cameramaster/util/cameravideo/IVideoControl.java
  type IVideoControl (line 7) | public interface IVideoControl {
    method play (line 12) | void play();
    method pause (line 17) | void pause();
    method resume (line 22) | void resume();
    method stop (line 27) | void stop();
    method seekTo (line 33) | void seekTo(int timeStamp);
    method setPlaySeekTimeListener (line 35) | void setPlaySeekTimeListener(PlaySeekTimeListener mPlaySeekTimeListener);
    method setPlayStateListener (line 37) | void setPlayStateListener(PlayStateListener mPlayStateListener);
    type PlaySeekTimeListener (line 39) | interface PlaySeekTimeListener
      method onSeekTime (line 41) | void onSeekTime(int allTime, int time);
    type PlayStateListener (line 47) | interface PlayStateListener{
      method onStartListener (line 49) | void onStartListener(int width, int height);
      method onCompletionListener (line 51) | void onCompletionListener();

FILE: app/src/main/java/camera/cn/cameramaster/util/cameravideo/VideoPlayer.java
  class VideoPlayer (line 21) | public class VideoPlayer implements IVideoControl {
    method VideoPlayer (line 37) | public VideoPlayer()
    method setLoopPlay (line 46) | public void setLoopPlay(boolean isLoop)
    method setDataSourceAndPlay (line 52) | public void setDataSourceAndPlay(Context context, Uri uri)
    method setDataSourceAndPlay (line 89) | public void setDataSourceAndPlay(String path)
    method play (line 127) | @Override
    method pause (line 137) | @Override
    method resume (line 144) | @Override
    method stop (line 151) | @Override
    method seekTo (line 160) | @Override
    method setPlaySeekTimeListener (line 167) | @Override
    method setPlayStateListener (line 172) | @Override
    method setVideoPlayWindow (line 177) | public void setVideoPlayWindow(Surface surface)
    method isPlaying (line 182) | public boolean isPlaying(){
    method startVideoSeekTime (line 189) | private void startVideoSeekTime()
    method stopVideoSeekTime (line 219) | private void stopVideoSeekTime()
    method destroy (line 224) | @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)

FILE: app/src/main/java/camera/cn/cameramaster/util/render/CameraV2Renderer.java
  class CameraV2Renderer (line 56) | public class CameraV2Renderer implements GLSurfaceView.Renderer {
    method init (line 89) | public void init(CameraV2GLSurfaceView surfaceView, CameraV2 camera,
    method onSurfaceCreated (line 103) | @Override
    method onSurfaceChanged (line 124) | @Override
    method onDrawFrame (line 131) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    method initSurfaceTexture (line 249) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    method bindfbo (line 276) | private void bindfbo() {
    method unbindfbo (line 299) | private void unbindfbo() {

FILE: app/src/main/java/camera/cn/cameramaster/view/AnimationTextView.java
  class AnimationTextView (line 16) | @SuppressLint("AppCompatCustomView")
    method AnimationTextView (line 25) | public AnimationTextView(Context context) {
    method AnimationTextView (line 29) | public AnimationTextView(Context context, AttributeSet attrs) {
    method AnimationTextView (line 33) | public AnimationTextView(Context context, AttributeSet attrs, int defS...
    method AnimationTextView (line 37) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    method setmMainHandler (line 42) | public void setmMainHandler(Handler mMainHandler) {
    method setmAnimation (line 46) | public void setmAnimation(Animation mAnimation) {
    method start (line 50) | public void start(String text, int message) {
    method stop (line 61) | public void stop() {

FILE: app/src/main/java/camera/cn/cameramaster/view/AutoFitTextureView.java
  class AutoFitTextureView (line 18) | public class AutoFitTextureView extends TextureView {
    method AutoFitTextureView (line 23) | public AutoFitTextureView(Context context) {
    method AutoFitTextureView (line 27) | public AutoFitTextureView(Context context, AttributeSet attrs) {
    method AutoFitTextureView (line 31) | public AutoFitTextureView(Context context, AttributeSet attrs, int def...
    method setAspectRatio (line 42) | public void setAspectRatio(int width, int height) {
    method setVideoAspectRatio (line 68) | public void setVideoAspectRatio(int width, int height)

FILE: app/src/main/java/camera/cn/cameramaster/view/AutoLocateHorizontalView.java
  class AutoLocateHorizontalView (line 19) | public class AutoLocateHorizontalView extends RecyclerView {
    method AutoLocateHorizontalView (line 57) | public AutoLocateHorizontalView(Context context) {
    method AutoLocateHorizontalView (line 61) | public AutoLocateHorizontalView(Context context, @Nullable AttributeSe...
    method AutoLocateHorizontalView (line 66) | public AutoLocateHorizontalView(Context context, @Nullable AttributeSe...
    method init (line 70) | private void init() {
    method setInitPos (line 97) | public void setInitPos(int initPos) {
    method setItemCount (line 111) | public void setItemCount(int itemCount) {
    method correctDeltax (line 127) | private void correctDeltax(Adapter adapter) {
    method reCallListenerWhenRemove (line 139) | private void reCallListenerWhenRemove(int startPos) {
    method reCallListenerWhenAdd (line 153) | private void reCallListenerWhenAdd(int startPos) {
    method reCallListenerWhenChanged (line 162) | private void reCallListenerWhenChanged() {
    method setAdapter (line 168) | @Override
    method setLayoutManager (line 203) | @Override
    method onScrollStateChanged (line 211) | @Override
    method moveToPosition (line 247) | public void moveToPosition(int position) {
    method computeScroll (line 261) | @Override
    method onScrolled (line 283) | @Override
    method calculateSelectedPos (line 290) | private void calculateSelectedPos() {
    class WrapperAdapter (line 299) | class WrapperAdapter extends RecyclerView.Adapter {
      method WrapperAdapter (line 315) | public WrapperAdapter(Adapter adapter, Context context, int itemCoun...
      method onCreateViewHolder (line 326) | @Override
      method onBindViewHolder (line 347) | @SuppressWarnings("unchecked")
      method getItemCount (line 361) | @Override
      method getItemViewType (line 366) | @Override
      method isHeaderOrFooter (line 375) | private boolean isHeaderOrFooter(int pos) {
      method getHeaderFooterWidth (line 382) | public int getHeaderFooterWidth() {
      method getItemWidth (line 386) | public int getItemWidth() {
      class HeaderFooterViewHolder (line 390) | class HeaderFooterViewHolder extends RecyclerView.ViewHolder {
        method HeaderFooterViewHolder (line 392) | HeaderFooterViewHolder(View itemView) {
    type IAutoLocateHorizontalView (line 401) | public interface IAutoLocateHorizontalView {
      method getItemView (line 405) | View getItemView();
      method onViewSelected (line 415) | void onViewSelected(boolean isSelected, int pos, ViewHolder holder, ...
    type OnSelectedPositionChangedListener (line 421) | public interface OnSelectedPositionChangedListener {
      method selectedPositionChanged (line 422) | void selectedPositionChanged(int pos);
    method setOnSelectedPositionChangedListener (line 425) | public void setOnSelectedPositionChangedListener(OnSelectedPositionCha...

FILE: app/src/main/java/camera/cn/cameramaster/view/AutoTextureView.java
  class AutoTextureView (line 17) | public class AutoTextureView extends TextureView {
    method AutoTextureView (line 22) | public AutoTextureView(Context context) {
    method AutoTextureView (line 26) | public AutoTextureView(Context context, AttributeSet attrs) {
    method AutoTextureView (line 30) | public AutoTextureView(Context context, AttributeSet attrs, int defSty...
    method setAspectRatio (line 41) | public void setAspectRatio(int width, int height) {
    method onMeasure (line 50) | @Override

FILE: app/src/main/java/camera/cn/cameramaster/view/AwbSeekBar.java
  class AwbSeekBar (line 16) | @SuppressLint("AppCompatCustomView")
    method AwbSeekBar (line 23) | public AwbSeekBar(Context context) {
    method AwbSeekBar (line 28) | public AwbSeekBar(Context context, AttributeSet attrs) {
    method AwbSeekBar (line 33) | public AwbSeekBar(Context context, AttributeSet attrs, int defStyleAtt...
    method AwbSeekBar (line 38) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    method setmOnAwbSeekBarChangeListener (line 43) | public void setmOnAwbSeekBarChangeListener(OnAwbSeekBarChangeListener ...
    method init (line 47) | private void init() {
    type OnAwbSeekBarChangeListener (line 114) | public interface OnAwbSeekBarChangeListener {
      method doInProgress1 (line 115) | public abstract void doInProgress1();
      method doInProgress2 (line 117) | public abstract void doInProgress2();
      method doInProgress3 (line 119) | public abstract void doInProgress3();
      method doInProgress4 (line 121) | public abstract void doInProgress4();
      method doInProgress5 (line 123) | public abstract void doInProgress5();
      method doInProgress6 (line 125) | public abstract void doInProgress6();
      method doInProgress7 (line 127) | public abstract void doInProgress7();
      method doInProgress8 (line 129) | public abstract void doInProgress8();
      method onStopTrackingTouch (line 131) | public abstract void onStopTrackingTouch(int num);
      method onStartTrackingTouch (line 133) | public abstract void onStartTrackingTouch(SeekBar seekBar);

FILE: app/src/main/java/camera/cn/cameramaster/view/AwbSeekBarChangeListener.java
  class AwbSeekBarChangeListener (line 27) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    method AwbSeekBarChangeListener (line 38) | public AwbSeekBarChangeListener(Context mContext, TextView mTextView, ...
    method doInProgress1 (line 50) | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    method doInProgress2 (line 58) | @Override
    method doInProgress3 (line 65) | @Override
    method doInProgress4 (line 73) | @Override
    method doInProgress5 (line 80) | @Override
    method doInProgress6 (line 87) | @Override
    method doInProgress7 (line 94) | @Override
    method doInProgress8 (line 101) | @Override
    method onStopTrackingTouch (line 108) | @Override
    method onStartTrackingTouch (line 149) | @Override
    method updatePreview (line 158) | private void updatePreview() {

FILE: app/src/main/java/camera/cn/cameramaster/view/CameraV2GLSurfaceView.java
  class CameraV2GLSurfaceView (line 18) | public class CameraV2GLSurfaceView extends GLSurfaceView {
    method init (line 21) | public void init(CameraV2 camera, boolean isPreviewStarted, Context co...
    method CameraV2GLSurfaceView (line 29) | public CameraV2GLSurfaceView(Context context) {

FILE: app/src/main/java/camera/cn/cameramaster/view/ShowSurfaceView.java
  class ShowSurfaceView (line 20) | public class ShowSurfaceView extends SurfaceView implements SurfaceHolde...
    method ShowSurfaceView (line 33) | public ShowSurfaceView(Context context) {
    method ShowSurfaceView (line 37) | public ShowSurfaceView(Context context, AttributeSet attrs) {
    method ShowSurfaceView (line 41) | public ShowSurfaceView(Context context, AttributeSet attrs, int defSty...
    method surfaceCreated (line 55) | @Override
    method surfaceChanged (line 62) | @Override
    method surfaceDestroyed (line 67) | @Override
    method run (line 72) | @Override
    method drawSomething (line 80) | private void drawSomething() {
    method getBitmap (line 99) | public Bitmap getBitmap() {
    method setBitmap (line 103) | public void setBitmap(Bitmap bitmap) {

FILE: app/src/main/java/camera/cn/cameramaster/view/SleepThread.java
  class SleepThread (line 11) | public class SleepThread implements Runnable {
    method SleepThread (line 17) | public SleepThread(Handler mainHandler, int what, long mTime, Object m...
    method run (line 24) | @Override

FILE: app/src/test/java/camera/cn/cameramaster/ExampleUnitTest.java
  class ExampleUnitTest (line 12) | public class ExampleUnitTest {
    method addition_isCorrect (line 13) | @Test
Condensed preview — 103 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (559K chars).
[
  {
    "path": ".gitignore",
    "chars": 118,
    "preview": "*.iml\n.gradle\n/local.properties\n/.idea/workspace.xml\n/.idea/libraries\n.DS_Store\n/build\n/captures\n.externalNativeBuild\n"
  },
  {
    "path": ".idea/codeStyles/Project.xml",
    "chars": 3309,
    "preview": "<component name=\"ProjectCodeStyleConfiguration\">\n  <code_scheme name=\"Project\" version=\"173\">\n    <codeStyleSettings lan"
  },
  {
    "path": ".idea/gradle.xml",
    "chars": 748,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"GradleMigrationSettings\" migrationVersio"
  },
  {
    "path": ".idea/inspectionProfiles/Project_Default.xml",
    "chars": 1494,
    "preview": "<component name=\"InspectionProjectProfileManager\">\n  <profile version=\"1.0\">\n    <option name=\"myName\" value=\"Project De"
  },
  {
    "path": ".idea/jarRepositories.xml",
    "chars": 2438,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"RemoteRepositoriesConfiguration\">\n    <r"
  },
  {
    "path": ".idea/misc.xml",
    "chars": 3833,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ASMPluginConfiguration\">\n    <asm skipDe"
  },
  {
    "path": ".idea/modules.xml",
    "chars": 1933,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ProjectModuleManager\">\n    <modules>\n   "
  },
  {
    "path": ".idea/runConfigurations.xml",
    "chars": 564,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"RunConfigurationProducerService\">\n    <o"
  },
  {
    "path": ".idea/vcs.xml",
    "chars": 180,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"VcsDirectoryMappings\">\n    <mapping dire"
  },
  {
    "path": "README.md",
    "chars": 1032,
    "preview": "# SunCamera\n\n一个 学习自定义的 Camera1 、Camera2 、Camera X 和 OpenglES 的Demo\n\n# 版本迭代\n \n -  1.3 完善部分bug (暂时停止维护,抽空整理成底层SDK,相对架构来一次深"
  },
  {
    "path": "app/.gitignore",
    "chars": 7,
    "preview": "/build\n"
  },
  {
    "path": "app/build.gradle",
    "chars": 2120,
    "preview": "apply plugin: 'com.android.application'\n\nandroid {\n    compileSdkVersion 27\n    defaultConfig {\n        applicationId \"c"
  },
  {
    "path": "app/proguard-rules.pro",
    "chars": 751,
    "preview": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguar"
  },
  {
    "path": "app/src/androidTest/java/camera/cn/cameramaster/ExampleInstrumentedTest.java",
    "chars": 745,
    "preview": "package camera.cn.cameramaster;\n\nimport android.content.Context;\nimport android.support.test.InstrumentationRegistry;\nim"
  },
  {
    "path": "app/src/main/AndroidManifest.xml",
    "chars": 3072,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:to"
  },
  {
    "path": "app/src/main/assets/web/css/login.css",
    "chars": 234,
    "preview": ".sec_body { color:#404040;background:#EBEBEB;text-shadow:#ddd 0 1px 0px;font-family:Helvetica;line-height:1.5;font-size:"
  },
  {
    "path": "app/src/main/assets/web/index.html",
    "chars": 581,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n    <meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\"/>\n    <meta name=\"v"
  },
  {
    "path": "app/src/main/assets/web/login.html",
    "chars": 1453,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n    <meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\"/>\n    <meta name=\"v"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/OpenReceiver.java",
    "chars": 759,
    "preview": "package camera.cn.cameramaster;\n\nimport android.content.BroadcastReceiver;\nimport android.content.Context;\nimport androi"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/adapter/EffectAdapter.java",
    "chars": 2231,
    "preview": "package camera.cn.cameramaster.adapter;\n\nimport android.content.Context;\nimport android.support.annotation.NonNull;\nimpo"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/adapter/MenuAdapter.java",
    "chars": 2916,
    "preview": "package camera.cn.cameramaster.adapter;\n\nimport android.content.Context;\nimport android.graphics.Color;\nimport android.s"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/adapter/SenseAdapter.java",
    "chars": 2214,
    "preview": "package camera.cn.cameramaster.adapter;\n\nimport android.content.Context;\nimport android.support.annotation.NonNull;\nimpo"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/base/App.java",
    "chars": 1817,
    "preview": "/*\n * Copyright 2018 Yan Zhenjie.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not u"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/base/BaseActivity.java",
    "chars": 2390,
    "preview": "package camera.cn.cameramaster.base;\n\nimport android.os.Build;\nimport android.os.Bundle;\nimport android.support.annotati"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/bean/Lab.java",
    "chars": 712,
    "preview": "package camera.cn.cameramaster.bean;\n\n/**\n * lab 实体类\n *\n * @packageName: cn.tongue.tonguecamera.bean\n * @fileName: Lab\n "
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/filter/AFilter.java",
    "chars": 8916,
    "preview": "/*\n *\n * AFilter.java\n * \n * Created by Wuwang on 2016/11/19\n * Copyright © 2016年 深圳哎吖科技. All rights reserved.\n */\npacka"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/filter/TextureFilter.java",
    "chars": 876,
    "preview": "package camera.cn.cameramaster.filter;\n\nimport android.content.res.Resources;\nimport android.graphics.SurfaceTexture;\n\ni"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/server/AnyEventType.java",
    "chars": 265,
    "preview": "package camera.cn.cameramaster.server;\n\n/**\n * event bus 消息类\n *\n * @packageName: cn.tongue.tonguecamera.eventbus\n * @fil"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/server/CoreService.java",
    "chars": 2970,
    "preview": "/*\n * Copyright © 2018 Yan Zhenjie.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/server/ServerManager.java",
    "chars": 4010,
    "preview": "/*\n * Copyright © 2018 Yan Zhenjie.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/server/TestController.java",
    "chars": 4796,
    "preview": "package camera.cn.cameramaster.server;\n\nimport android.os.Build;\nimport android.support.annotation.RequiresApi;\nimport a"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/server/component/LoggerInterceptor.java",
    "chars": 1820,
    "preview": "/*\n * Copyright 2018 Yan Zhenjie.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not u"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/server/model/UserInfo.java",
    "chars": 1467,
    "preview": "package camera.cn.cameramaster.server.model;\n\nimport android.os.Parcel;\nimport android.os.Parcelable;\n\nimport com.alibab"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/server/util/FileUtils.java",
    "chars": 1973,
    "preview": "/*\n * Copyright 2018 Yan Zhenjie.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not u"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/server/util/NetUtils.java",
    "chars": 2452,
    "preview": "/*\n * Copyright © 2018 Yan Zhenjie.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/ui/Camera2Activity.java",
    "chars": 14789,
    "preview": "package camera.cn.cameramaster.ui;\n\nimport android.Manifest;\nimport android.content.Context;\nimport android.content.Inte"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/ui/CameraActivity.java",
    "chars": 11015,
    "preview": "package camera.cn.cameramaster.ui;\n\nimport android.content.Intent;\nimport android.graphics.Bitmap;\nimport android.graphi"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/ui/CameraSurfaceViewActivity.java",
    "chars": 3085,
    "preview": "package camera.cn.cameramaster.ui;\n\nimport android.os.Build;\nimport android.support.annotation.RequiresApi;\nimport andro"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/ui/CameraVideoActivity.java",
    "chars": 52591,
    "preview": "package camera.cn.cameramaster.ui;\n\nimport android.Manifest;\nimport android.annotation.SuppressLint;\nimport android.cont"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/ui/GoogleCameraActivity.java",
    "chars": 62562,
    "preview": "package camera.cn.cameramaster.ui;\n\nimport android.Manifest;\nimport android.annotation.SuppressLint;\nimport android.cont"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/ui/MainActivity.java",
    "chars": 6763,
    "preview": "package camera.cn.cameramaster.ui;\n\nimport android.Manifest;\nimport android.annotation.SuppressLint;\nimport android.cont"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/ui/ShowPicActivity.java",
    "chars": 6718,
    "preview": "package camera.cn.cameramaster.ui;\n\nimport android.graphics.Bitmap;\nimport android.graphics.BitmapFactory;\nimport androi"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/util/AppConstant.java",
    "chars": 3612,
    "preview": "package camera.cn.cameramaster.util;\n\n/**\n * 应用 常量类\n *\n * @packageName: cn.ymc.suncamera.util\n * @fileName: AppConstant\n"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/util/BitmapUtils.java",
    "chars": 35071,
    "preview": "package camera.cn.cameramaster.util;\n\nimport android.content.Context;\nimport android.content.res.Resources;\nimport andro"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/util/Camera2Util.java",
    "chars": 6326,
    "preview": "package camera.cn.cameramaster.util;\n\nimport android.graphics.ImageFormat;\nimport android.media.Image;\nimport android.os"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/util/CameraUtil.java",
    "chars": 11244,
    "preview": "package camera.cn.cameramaster.util;\n\nimport android.app.Activity;\nimport android.graphics.Bitmap;\nimport android.graphi"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/util/CameraV2.java",
    "chars": 24637,
    "preview": "package camera.cn.cameramaster.util;\n\nimport android.Manifest;\nimport android.app.Activity;\nimport android.content.Conte"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/util/CompareSizesByArea.java",
    "chars": 661,
    "preview": "package camera.cn.cameramaster.util;\n\nimport android.os.Build;\nimport android.support.annotation.RequiresApi;\nimport and"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/util/FilterEngine.java",
    "chars": 6551,
    "preview": "package camera.cn.cameramaster.util;\n\nimport android.annotation.SuppressLint;\nimport android.content.Context;\nimport and"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/util/LabUtil.java",
    "chars": 6231,
    "preview": "package camera.cn.cameramaster.util;\n\n\nimport java.util.Arrays;\n\n/**\n * rgb 转 lab 工具类\n *\n * @fileName: LabUtil\n * @date:"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/util/MatrixUtils.java",
    "chars": 4894,
    "preview": "/*\n *\n * FastDrawerHelper.java\n * \n * Created by Wuwang on 2016/11/17\n * Copyright © 2016年 深圳哎吖科技. All rights reserved.\n"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/util/Utils.java",
    "chars": 4272,
    "preview": "package camera.cn.cameramaster.util;\n\nimport android.content.Context;\nimport android.opengl.GLES11Ext;\nimport android.op"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/util/cameravideo/CameraHelper.java",
    "chars": 49288,
    "preview": "package camera.cn.cameramaster.util.cameravideo;\n\nimport android.annotation.SuppressLint;\nimport android.app.Activity;\ni"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/util/cameravideo/CoordinateTransformer.java",
    "chars": 2757,
    "preview": "package camera.cn.cameramaster.util.cameravideo;\n\nimport android.graphics.Matrix;\nimport android.graphics.Rect;\nimport a"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/util/cameravideo/ICamera2.java",
    "chars": 2113,
    "preview": "package camera.cn.cameramaster.util.cameravideo;\n\nimport android.util.Size;\nimport android.view.Surface;\nimport android."
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/util/cameravideo/IVideoControl.java",
    "chars": 795,
    "preview": "package camera.cn.cameramaster.util.cameravideo;\n\n/**\n * 视频接口\n */\n\npublic interface IVideoControl {\n\n    /**\n     * 播放视频"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/util/cameravideo/VideoPlayer.java",
    "chars": 6928,
    "preview": "package camera.cn.cameramaster.util.cameravideo;\n\nimport android.content.Context;\nimport android.media.MediaPlayer;\nimpo"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/util/render/CameraV2Renderer.java",
    "chars": 11908,
    "preview": "package camera.cn.cameramaster.util.render;\n\nimport android.content.Context;\nimport android.graphics.Bitmap;\nimport andr"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/view/AnimationTextView.java",
    "chars": 1769,
    "preview": "package camera.cn.cameramaster.view;\n\nimport android.annotation.SuppressLint;\nimport android.content.Context;\nimport and"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/view/AutoFitTextureView.java",
    "chars": 2517,
    "preview": "package camera.cn.cameramaster.view;\n\nimport android.content.Context;\nimport android.graphics.Matrix;\nimport android.uti"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/view/AutoLocateHorizontalView.java",
    "chars": 13465,
    "preview": "package camera.cn.cameramaster.view;\n\nimport android.content.Context;\nimport android.support.annotation.Nullable;\nimport"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/view/AutoTextureView.java",
    "chars": 2079,
    "preview": "package camera.cn.cameramaster.view;\n\nimport android.content.Context;\nimport android.util.AttributeSet;\nimport android.v"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/view/AwbSeekBar.java",
    "chars": 4946,
    "preview": "package camera.cn.cameramaster.view;\n\nimport android.annotation.SuppressLint;\nimport android.content.Context;\nimport and"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/view/AwbSeekBarChangeListener.java",
    "chars": 6130,
    "preview": "package camera.cn.cameramaster.view;\n\nimport android.content.Context;\nimport android.hardware.camera2.CameraAccessExcept"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/view/CameraV2GLSurfaceView.java",
    "chars": 933,
    "preview": "package camera.cn.cameramaster.view;\n\nimport android.content.Context;\nimport android.opengl.GLSurfaceView;\n\nimport camer"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/view/ShowSurfaceView.java",
    "chars": 2650,
    "preview": "package camera.cn.cameramaster.view;\n\nimport android.content.Context;\nimport android.graphics.Bitmap;\nimport android.gra"
  },
  {
    "path": "app/src/main/java/camera/cn/cameramaster/view/SleepThread.java",
    "chars": 840,
    "preview": "package camera.cn.cameramaster.view;\n\nimport android.os.Handler;\nimport android.os.Message;\n\n/**\n * 睡眠线程\n *\n * @author y"
  },
  {
    "path": "app/src/main/res/anim/alpha_in.xml",
    "chars": 236,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<alpha xmlns:android=\"http://schemas.android.com/apk/res/android\"\n       android:"
  },
  {
    "path": "app/src/main/res/anim/alpha_out.xml",
    "chars": 236,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<alpha xmlns:android=\"http://schemas.android.com/apk/res/android\"\n       android:"
  },
  {
    "path": "app/src/main/res/drawable/ic_camera.xml",
    "chars": 1019,
    "preview": "<vector android:height=\"16dp\" android:viewportHeight=\"1024.0\"\n    android:viewportWidth=\"1024.0\" android:width=\"16dp\" xm"
  },
  {
    "path": "app/src/main/res/drawable/ic_fouces.xml",
    "chars": 833,
    "preview": "<vector android:height=\"24dp\" android:viewportHeight=\"1024.0\"\n    android:viewportWidth=\"1228.0\" android:width=\"24dp\" xm"
  },
  {
    "path": "app/src/main/res/drawable/ic_launcher_background.xml",
    "chars": 5606,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:wi"
  },
  {
    "path": "app/src/main/res/drawable/ic_launcher_camera.xml",
    "chars": 3650,
    "preview": "<vector android:height=\"64dp\" android:viewportHeight=\"1024.0\"\n    android:viewportWidth=\"1024.0\" android:width=\"64dp\" xm"
  },
  {
    "path": "app/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "chars": 1880,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    "
  },
  {
    "path": "app/src/main/res/layout/activity_camera.xml",
    "chars": 3151,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xm"
  },
  {
    "path": "app/src/main/res/layout/activity_camera2.xml",
    "chars": 2606,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xm"
  },
  {
    "path": "app/src/main/res/layout/activity_camera_sv.xml",
    "chars": 2556,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xm"
  },
  {
    "path": "app/src/main/res/layout/activity_camera_video.xml",
    "chars": 14446,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xm"
  },
  {
    "path": "app/src/main/res/layout/activity_google_camera.xml",
    "chars": 13609,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xm"
  },
  {
    "path": "app/src/main/res/layout/activity_look_camera.xml",
    "chars": 913,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    an"
  },
  {
    "path": "app/src/main/res/layout/activity_main.xml",
    "chars": 2802,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.constraint.ConstraintLayout xmlns:android=\"http://schemas.androi"
  },
  {
    "path": "app/src/main/res/layout/activity_show_pic.xml",
    "chars": 3147,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    an"
  },
  {
    "path": "app/src/main/res/layout/item_age.xml",
    "chars": 529,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    andr"
  },
  {
    "path": "app/src/main/res/layout/item_rv_text.xml",
    "chars": 758,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.v7.widget.CardView xmlns:android=\"http://schemas.android.com/apk"
  },
  {
    "path": "app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "chars": 272,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <b"
  },
  {
    "path": "app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "chars": 272,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <b"
  },
  {
    "path": "app/src/main/res/mipmap-xhdpi/ic_launcher_background.xml",
    "chars": 5606,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:wi"
  },
  {
    "path": "app/src/main/res/mipmap-xhdpi/icon_back.xml",
    "chars": 808,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:wi"
  },
  {
    "path": "app/src/main/res/raw/base_fragment_shader.glsl",
    "chars": 851,
    "preview": "#extension GL_OES_EGL_image_external : require\nuniform samplerExternalOES uTextureSampler;\nprecision mediump float;\nunif"
  },
  {
    "path": "app/src/main/res/raw/base_vertex_shader.glsl",
    "chars": 220,
    "preview": "attribute vec4 aPosition;\nuniform mat4 uTextureMatrix;\nattribute vec4 aTextureCoordinate;\nvarying vec2 vTextureCoord;\nvo"
  },
  {
    "path": "app/src/main/res/values/colors.xml",
    "chars": 300,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"color"
  },
  {
    "path": "app/src/main/res/values/strings.xml",
    "chars": 328,
    "preview": "<resources>\n    <string name=\"app_name\">SunCamera</string>\n    <string name=\"start_server\">启动服务器</string>\n    <string na"
  },
  {
    "path": "app/src/main/res/values/styles.xml",
    "chars": 383,
    "preview": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar"
  },
  {
    "path": "app/src/main/res/xml/file_paths.xml",
    "chars": 195,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <paths>\n        <root-path path=\"\" name=\"camera_photos\" />\n      "
  },
  {
    "path": "app/src/test/java/camera/cn/cameramaster/ExampleUnitTest.java",
    "chars": 400,
    "preview": "package camera.cn.cameramaster;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit te"
  },
  {
    "path": "build.gradle",
    "chars": 695,
    "preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n\n    "
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "chars": 232,
    "preview": "#Wed Dec 09 09:54:58 CST 2020\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_"
  },
  {
    "path": "gradle.properties",
    "chars": 779,
    "preview": "# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will o"
  },
  {
    "path": "gradlew",
    "chars": 4971,
    "preview": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start "
  },
  {
    "path": "gradlew.bat",
    "chars": 2314,
    "preview": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem "
  },
  {
    "path": "settings.gradle",
    "chars": 15,
    "preview": "include ':app'\n"
  }
]

// ... and 2 more files (download for full content)

About this extraction

This page contains the full source code of the yangmingchuan/CameraMaster GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 103 files (501.9 KB), approximately 125.0k tokens, and a symbol index with 735 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!