├── .gitignore
├── settings.gradle
├── testSurfaceView.apk
├── res
├── drawable
│ └── ic_launcher.png
├── values
│ ├── colors.xml
│ ├── strings.xml
│ ├── attrs.xml
│ └── styles.xml
└── layout
│ └── activity_main.xml
├── gradle
└── wrapper
│ └── gradle-wrapper.properties
├── README.md
├── .idea
└── runConfigurations.xml
├── project.properties
├── src
└── com
│ └── example
│ └── openglcamera
│ ├── TouchActivity.java
│ ├── SurfaceTextureActivity.java
│ └── CameraPreview.java
├── app
├── build.gradle
└── app.iml
├── .project
├── OpenGLCamera.iml
├── AndroidManifest.xml
├── LICENSE
├── gradlew.bat
└── gradlew
/.gitignore:
--------------------------------------------------------------------------------
1 | local.*
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/testSurfaceView.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexcohn/OpenGLCamera/HEAD/testSurfaceView.apk
--------------------------------------------------------------------------------
/res/drawable/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexcohn/OpenGLCamera/HEAD/res/drawable/ic_launcher.png
--------------------------------------------------------------------------------
/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #66000000
4 |
5 |
6 |
--------------------------------------------------------------------------------
/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | OpenGLCamera
5 | Dummy Button
6 | DUMMY\nCONTENT
7 |
8 |
9 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Apr 10 15:27:10 PDT 2013
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | OpenGLCamera
2 | ============
3 |
4 | Android camera using SurfaceTexture
5 |
6 | This is a minimalistic example of custom camera preview app that uses SurfaceTexture and uses a matrix transform to change the way it is displayed.
7 |
8 | Here, we show front camera image not as a mirror.
9 |
10 | Many details like error checking have been skipped for brevity. In the real world, you will open the camera on a separate EventThread, so that the camera callbacks would not interfere with UI thread.
11 |
12 | Depends on android-support-v4.jar
--------------------------------------------------------------------------------
/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
--------------------------------------------------------------------------------
/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-19
15 |
--------------------------------------------------------------------------------
/src/com/example/openglcamera/TouchActivity.java:
--------------------------------------------------------------------------------
1 | package com.example.openglcamera;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.view.SurfaceView;
6 |
7 |
8 | public class TouchActivity extends Activity {
9 |
10 | static TouchActivity reference;
11 |
12 | @Override
13 | protected void onCreate(Bundle savedInstanceState) {
14 | super.onCreate(savedInstanceState);
15 | reference = this;
16 | SurfaceView sv = new SurfaceView(this);
17 | sv.getHolder().addCallback(new CameraPreview(640, 480));
18 | setContentView(sv);
19 | }
20 |
21 | TouchActivity getActivity() {
22 | return this;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 19
5 | buildToolsVersion "22.0.1"
6 |
7 | defaultConfig {
8 | applicationId "com.example.openglcamera"
9 | minSdkVersion 14
10 | targetSdkVersion 18
11 | }
12 |
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
17 | }
18 | }
19 |
20 | sourceSets {
21 | main {
22 | manifest.srcFile '../AndroidManifest.xml'
23 | java.srcDirs = ['../src']
24 | res.srcDirs = ['../res']
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | OpenGLCamera
4 |
5 |
6 |
7 |
8 |
9 | com.android.ide.eclipse.adt.ResourceManagerBuilder
10 |
11 |
12 |
13 |
14 | com.android.ide.eclipse.adt.PreCompilerBuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.jdt.core.javabuilder
20 |
21 |
22 |
23 |
24 | com.android.ide.eclipse.adt.ApkBuilder
25 |
26 |
27 |
28 |
29 |
30 | com.android.ide.eclipse.adt.AndroidNature
31 | org.eclipse.jdt.core.javanature
32 |
33 |
34 |
--------------------------------------------------------------------------------
/OpenGLCamera.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
12 |
13 |
18 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | This is free and unencumbered software released into the public domain.
2 |
3 | Anyone is free to copy, modify, publish, use, compile, sell, or
4 | distribute this software, either in source code form or as a compiled
5 | binary, for any purpose, commercial or non-commercial, and by any
6 | means.
7 |
8 | In jurisdictions that recognize copyright laws, the author or authors
9 | of this software dedicate any and all copyright interest in the
10 | software to the public domain. We make this dedication for the benefit
11 | of the public at large and to the detriment of our heirs and
12 | successors. We intend this dedication to be an overt act of
13 | relinquishment in perpetuity of all present and future rights to this
14 | software under copyright law.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 | OTHER DEALINGS IN THE SOFTWARE.
23 |
24 | For more information, please refer to
25 |
--------------------------------------------------------------------------------
/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
15 |
16 |
17 |
20 |
21 |
27 |
28 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
13 |
14 |
24 |
25 |
29 |
30 |
34 |
35 |
44 |
45 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/src/com/example/openglcamera/SurfaceTextureActivity.java:
--------------------------------------------------------------------------------
1 | package com.example.openglcamera;
2 |
3 | import java.io.IOException;
4 |
5 | import android.app.Activity;
6 | import android.content.Intent;
7 | import android.graphics.Matrix;
8 | import android.graphics.SurfaceTexture;
9 | import android.graphics.SurfaceTexture.OnFrameAvailableListener;
10 | import android.hardware.Camera;
11 | import android.hardware.Camera.PreviewCallback;
12 | import android.os.Bundle;
13 | import android.util.Log;
14 | import android.view.Gravity;
15 | import android.view.MotionEvent;
16 | import android.view.Surface;
17 | import android.view.TextureView;
18 | import android.view.View;
19 | import android.view.View.OnClickListener;
20 | import android.widget.FrameLayout;
21 |
22 | public class SurfaceTextureActivity extends Activity implements TextureView.SurfaceTextureListener, OnClickListener {
23 |
24 | private static final int CAMERA_PIC_REQUEST = 0;
25 | private Camera mCamera;
26 | private TextureView mTextureView;
27 |
28 | protected void onCreate(Bundle savedInstanceState) {
29 | super.onCreate(savedInstanceState);
30 |
31 | mTextureView = new TextureView(this);
32 | mTextureView.setSurfaceTextureListener(this);
33 | mTextureView.setOnClickListener(this);
34 |
35 | setContentView(mTextureView);
36 | }
37 |
38 | @Override
39 | public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
40 |
41 | int cameraId = 0;
42 | Camera.CameraInfo info = new Camera.CameraInfo();
43 |
44 | for (cameraId = 0; cameraId < Camera.getNumberOfCameras(); cameraId++) {
45 | Camera.getCameraInfo(cameraId, info);
46 | if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT)
47 | break;
48 | }
49 |
50 | mCamera = Camera.open(cameraId);
51 | Matrix transform = new Matrix();
52 |
53 | Camera.Size previewSize = mCamera.getParameters().getPreviewSize();
54 | int rotation = getWindowManager().getDefaultDisplay()
55 | .getRotation();
56 |
57 | Log.i("ST", "onSurfaceTextureAvailable(): CameraOrientation(" + cameraId + ")" + info.orientation + " " + previewSize.width + "x" + previewSize.height + " Rotation=" + rotation);
58 |
59 | switch (rotation) {
60 | case Surface.ROTATION_0:
61 | mCamera.setDisplayOrientation(90);
62 | mTextureView.setLayoutParams(new FrameLayout.LayoutParams(
63 | previewSize.height, previewSize.width, Gravity.CENTER));
64 | transform.setScale(-1, 1, previewSize.height/2, 0);
65 | break;
66 |
67 | case Surface.ROTATION_90:
68 | mCamera.setDisplayOrientation(0);
69 | mTextureView.setLayoutParams(new FrameLayout.LayoutParams(
70 | previewSize.width, previewSize.height, Gravity.CENTER));
71 | transform.setScale(-1, 1, previewSize.width/2, 0);
72 | break;
73 |
74 | case Surface.ROTATION_180:
75 | mCamera.setDisplayOrientation(270);
76 | mTextureView.setLayoutParams(new FrameLayout.LayoutParams(
77 | previewSize.height, previewSize.width, Gravity.CENTER));
78 | transform.setScale(-1, 1, previewSize.height/2, 0);
79 | break;
80 |
81 | case Surface.ROTATION_270:
82 | mCamera.setDisplayOrientation(180);
83 | mTextureView.setLayoutParams(new FrameLayout.LayoutParams(
84 | previewSize.width, previewSize.height, Gravity.CENTER));
85 | transform.setScale(-1, 1, previewSize.width/2, 0);
86 | break;
87 | }
88 |
89 | try {
90 | mCamera.setPreviewTexture(surface);
91 | } catch (IOException t) {
92 | }
93 |
94 | mTextureView.setTransform(transform);
95 | Log.i("ST", "onSurfaceTextureAvailable(): Transform: " + transform.toString());
96 |
97 | mCamera.startPreview();
98 |
99 | }
100 |
101 | @Override
102 | public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
103 | // Ignored, the Camera does all the work for us
104 | }
105 |
106 | @Override
107 | public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
108 | if (mCamera != null) {
109 | mCamera.stopPreview();
110 | mCamera.release();
111 | mCamera = null;
112 | }
113 | return true;
114 | }
115 |
116 | @Override
117 | public void onPause() {
118 | onSurfaceTextureDestroyed(null);
119 | super.onPause();
120 | }
121 |
122 | private long ts = 0;
123 | private long adts = 0;
124 | private long nts = 1;
125 |
126 | @Override
127 | public void onSurfaceTextureUpdated(SurfaceTexture surface) {
128 | // Log.i("ST", "onSurfaceTextureUpdated()");
129 | long newTs = surface.getTimestamp();
130 | if (ts != 0)
131 | {
132 | adts += newTs - ts;
133 | nts++;
134 | }
135 | ts = newTs;
136 |
137 | if (nts % 30 == 0)
138 | {
139 | Log.i("ST", "onSurfaceTextureUpdated(): average dts " + (adts*1.e-6/nts));
140 | adts = 0;
141 | nts = 0;
142 | }
143 | }
144 |
145 | @Override
146 | public void onClick(View arg0) {
147 | Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
148 | startActivityForResult(intent, CAMERA_PIC_REQUEST);
149 | }
150 |
151 | @Override
152 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
153 | if (requestCode == CAMERA_PIC_REQUEST) {
154 | Log.i("ST", "onActivityResult(" + resultCode + ")");
155 | }
156 | }
157 |
158 | }
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/app/app.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | generateDebugAndroidTestSources
19 | generateDebugSources
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/src/com/example/openglcamera/CameraPreview.java:
--------------------------------------------------------------------------------
1 | package com.example.openglcamera;
2 |
3 | import java.io.ByteArrayOutputStream;
4 | import java.io.File;
5 | import java.io.FileNotFoundException;
6 | import java.io.FileOutputStream;
7 | import java.io.IOException;
8 | import java.text.SimpleDateFormat;
9 | import java.util.ArrayList;
10 | import java.util.Date;
11 | import java.util.List;
12 |
13 | import android.annotation.TargetApi;
14 | import android.app.ProgressDialog;
15 | import android.content.res.Configuration;
16 | import android.graphics.Bitmap;
17 | import android.graphics.BitmapFactory;
18 | import android.graphics.Matrix;
19 | import android.graphics.Rect;
20 | import android.hardware.Camera;
21 | import android.hardware.Camera.AutoFocusCallback;
22 | import android.net.Uri;
23 | import android.os.Build;
24 | import android.os.Environment;
25 | import android.os.Handler;
26 | import android.os.HandlerThread;
27 | import android.text.method.Touch;
28 | import android.util.Log;
29 | import android.view.SurfaceHolder;
30 | import android.widget.Toast;
31 |
32 | //import com.nepalimutu.pujanpaudel.app.priceoverrrflow.FragmentsCorner.BaseImagesContainer;
33 | //import com.nepalimutu.pujanpaudel.app.priceoverrrflow.UltimateCamera.DialogHelper;
34 | //import com.soundcloud.android.crop.Crop;
35 |
36 | public class CameraPreview
37 | implements
38 | SurfaceHolder.Callback {
39 | public static CameraPreview reference;
40 | private int cameratype=Camera.CameraInfo.CAMERA_FACING_BACK;
41 | private Camera mCamera = null;
42 | public Camera.Parameters params;
43 | private SurfaceHolder sHolder;
44 | private String TAG="CameraPreview";
45 | public List supportedSizes;
46 |
47 | private boolean isCamOpen = false;
48 | private boolean isSurfaceReady = false;
49 | public boolean isSizeSupported = false;
50 | private int previewWidth, previewHeight;
51 | private List mSupportedFlashModes;
52 | private boolean flashon=false;
53 | private final static String MYTAG = "CameraPreview";
54 | private ProgressDialog loading;
55 | private CameraHandlerThread mThread;
56 | private String LOG_TAG="Camera_Preview";
57 |
58 | public CameraPreview(int width, int height) {
59 | Log.i("campreview", "Width = " + String.valueOf(width));
60 | Log.i("campreview", "Height = " + String.valueOf(height));
61 | previewWidth = width;
62 | previewHeight = height;
63 | reference=this;
64 | }
65 |
66 | private boolean oldOpenCamera() {
67 | if (isCamOpen) {
68 | releaseCamera();
69 | }
70 | try{
71 | mCamera = Camera.open(cameratype);
72 | isCamOpen = true;
73 | }catch (Exception e){
74 | e.printStackTrace();
75 | Toast.makeText(TouchActivity.reference.getActivity(),"Can't Open the Camera",Toast.LENGTH_LONG).show();
76 | }
77 | startPreviewIfReady();
78 | return isCamOpen;
79 | }
80 |
81 | public boolean isCamOpen() {
82 | return isCamOpen;
83 | }
84 |
85 | public void releaseCamera() {
86 | if (mCamera != null) {
87 | mCamera.stopPreview();
88 | mCamera.setPreviewCallback(null);
89 | mCamera.release();
90 | mCamera = null;
91 | }
92 | isCamOpen = false;
93 | }
94 |
95 | @Override
96 | public void surfaceCreated(SurfaceHolder holder) {
97 | sHolder = holder;
98 | newOpenCamera();
99 | }
100 |
101 | @Override
102 | public void surfaceChanged(SurfaceHolder holder, int format, int width,
103 | int height) {
104 | Log.d("Inside", "Surface Changed");
105 | isSurfaceReady = true;
106 | startPreviewIfReady();
107 | }
108 |
109 | private synchronized void startPreviewIfReady() {
110 | if (!isSurfaceReady || !isCamOpen) {
111 | return;
112 | }
113 | if (TouchActivity.reference.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
114 |
115 | mCamera.setDisplayOrientation(90);
116 |
117 | } else {
118 |
119 | mCamera.setDisplayOrientation(0);
120 |
121 | }
122 | try{
123 | mCamera.setPreviewDisplay(sHolder);
124 | mCamera.startPreview();
125 | }
126 | catch(Exception e){
127 | e.printStackTrace();
128 | }
129 |
130 | }
131 | @Override
132 | public void surfaceDestroyed(SurfaceHolder holder) {
133 |
134 | releaseCamera();
135 |
136 | }
137 |
138 | /**
139 | * Called from PreviewSurfaceView to set touch focus.
140 | *
141 | * @param - Rect - new area for auto focus
142 | */
143 | @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
144 | public void doTouchFocus(final Rect tfocusRect) {
145 | Log.i(TAG, "TouchFocus");
146 | try {
147 | final List focusList = new ArrayList();
148 | Camera.Area focusArea = new Camera.Area(tfocusRect, 1000);
149 | focusList.add(focusArea);
150 |
151 | Camera.Parameters para = mCamera.getParameters();
152 | para.setFocusAreas(focusList);
153 | para.setMeteringAreas(focusList);
154 | mCamera.setParameters(para);
155 |
156 | mCamera.autoFocus(myAutoFocusCallback);
157 | } catch (Exception e) {
158 | e.printStackTrace();
159 | Log.i(TAG, "Unable to autofocus");
160 | }
161 |
162 | }
163 |
164 | /**
165 | * AutoFocus callback
166 | */
167 | AutoFocusCallback myAutoFocusCallback = new AutoFocusCallback(){
168 |
169 | @Override
170 | public void onAutoFocus(boolean arg0, Camera arg1) {
171 | if (arg0){
172 | mCamera.cancelAutoFocus();
173 | }
174 | }
175 | };
176 |
177 |
178 |
179 |
180 | public void capturePicture(){
181 | mCamera.takePicture(null, null, mPicture);
182 |
183 |
184 | }
185 |
186 | private File getOutputMediaFile(){
187 |
188 | File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
189 | Environment.DIRECTORY_PICTURES), "UltimateCameraGuideApp");
190 |
191 | if (! mediaStorageDir.exists()){
192 | if (! mediaStorageDir.mkdirs()){
193 | Log.d("Camera Guide", "Required media storage does not exist");
194 | return null;
195 | }
196 | }
197 |
198 | // Create a media file name
199 | String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
200 | File mediaFile;
201 | mediaFile = new File(mediaStorageDir.getPath() + File.separator +
202 | "IMG_"+ timeStamp + ".jpg");
203 |
204 | //DialogHelper.showDialog("Success!", "Your picture has been saved!", TouchActivity.reference.getActivity());
205 |
206 | return mediaFile;
207 | }
208 |
209 | private Camera.PictureCallback mPicture = new Camera.PictureCallback() {
210 |
211 | @Override
212 | public void onPictureTaken(byte[] data, Camera camera) {
213 |
214 | //This One is Just for Getting a File Named after it
215 | loading=new ProgressDialog(TouchActivity.reference.getActivity()); // BaseImagesContainer.reference);
216 | loading.setMessage("Getting Image Ready");
217 | loading.show();
218 | File pictureFile =getOutputMediaFile();
219 | if (pictureFile == null){
220 | Toast.makeText(TouchActivity.reference.getActivity(), "Image retrieval failed.", Toast.LENGTH_SHORT)
221 | .show();
222 | return;
223 | }
224 | Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
225 | if(cameratype==Camera.CameraInfo.CAMERA_FACING_BACK){
226 | bmp=rotateImage(90,bmp);
227 | }else{
228 | bmp=rotateImage(270,bmp);
229 |
230 | }
231 | ByteArrayOutputStream stream = new ByteArrayOutputStream();
232 | bmp.compress(Bitmap.CompressFormat.PNG,1, stream);
233 | byte[] flippedImageByteArray = stream.toByteArray();
234 | try {
235 | FileOutputStream fos = new FileOutputStream(pictureFile);
236 | fos.write(flippedImageByteArray);
237 | fos.close();
238 | // Restart the camera preview.
239 | //safeCameraOpenInView(mCameraView);
240 | } catch (FileNotFoundException e) {
241 | e.printStackTrace();
242 | } catch (IOException e) {
243 | e.printStackTrace();
244 | }
245 |
246 | Uri destination = Uri.fromFile(new File(TouchActivity.reference.getActivity().getCacheDir(), "cropped"));
247 | Uri source = Uri.fromFile(new File(pictureFile.getPath()));
248 | // Crop.of(source, destination).withMaxSize(800,800).start(TouchActivity.reference.getActivity());
249 | }
250 | };
251 |
252 |
253 | public Bitmap rotateImage(int angle, Bitmap bitmapSrc) {
254 | Matrix matrix = new Matrix();
255 | matrix.postRotate(angle);
256 | return Bitmap.createBitmap(bitmapSrc, 0, 0,
257 | bitmapSrc.getWidth(), bitmapSrc.getHeight(), matrix, true);
258 | }
259 |
260 |
261 | public void switchCamera(){
262 | mCamera.stopPreview();
263 | //NB: if you don't release the current camera before switching, you app will crash
264 | mCamera.release();
265 |
266 | //swap the id of the camera to be used
267 | if(cameratype==Camera.CameraInfo.CAMERA_FACING_BACK){
268 | cameratype=Camera.CameraInfo.CAMERA_FACING_FRONT;
269 | }else{
270 | cameratype=Camera.CameraInfo.CAMERA_FACING_BACK;
271 | }
272 | try{
273 | mCamera = Camera.open(cameratype);
274 | }catch (Exception e){
275 | e.printStackTrace();
276 | Toast.makeText(TouchActivity.reference.getActivity(),"Can't Open the Camera",Toast.LENGTH_LONG).show();
277 | }
278 |
279 | if (TouchActivity.reference.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
280 |
281 | mCamera.setDisplayOrientation(90);
282 |
283 | } else {
284 |
285 | mCamera.setDisplayOrientation(0);
286 |
287 | }
288 |
289 | try{
290 | mCamera.setPreviewDisplay(sHolder);
291 | mCamera.startPreview();
292 | }
293 | catch(Exception e){
294 | e.printStackTrace();
295 | }
296 |
297 | }
298 |
299 | public void switchflash(){
300 | //Do the On Flash for now
301 | if(!flashon){
302 | mSupportedFlashModes = mCamera.getParameters().getSupportedFlashModes();
303 | if (mSupportedFlashModes != null && mSupportedFlashModes.contains(Camera.Parameters.FLASH_MODE_AUTO)){
304 | Camera.Parameters parameters = mCamera.getParameters();
305 | parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
306 | mCamera.setParameters(parameters);
307 | }
308 | }else{
309 | //flash on
310 | //do teh off now
311 | Camera.Parameters parameters = mCamera.getParameters();
312 | parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
313 | mCamera.setParameters(parameters);
314 | }
315 | flashon=!flashon;
316 |
317 | }
318 |
319 | public void stopLoading(){
320 | loading.dismiss();
321 | //DialogHelper.showDialog("Oops!", "Your crop had been cancelled !", TouchActivity.reference.getActivity());
322 |
323 | }
324 |
325 |
326 | private void newOpenCamera() {
327 | if (mThread == null) {
328 | mThread = new CameraHandlerThread();
329 | }
330 |
331 | synchronized (mThread) {
332 | mThread.openCamera();
333 | }
334 | }
335 | private class CameraHandlerThread extends HandlerThread {
336 | Handler mHandler = null;
337 |
338 | CameraHandlerThread() {
339 | super("CameraHandlerThread");
340 | start();
341 | mHandler = new Handler(getLooper());
342 | }
343 |
344 | synchronized void notifyCameraOpened() {
345 | //notify();
346 | if(mCamera==null){
347 | Log.d("Notify","Null Camera");
348 | }else {
349 | Log.d("Notify","Yess!! Camera");
350 | }
351 | }
352 |
353 | void openCamera() {
354 | mHandler.post(new Runnable() {
355 | @Override
356 | public void run() {
357 | oldOpenCamera();
358 | notifyCameraOpened();
359 | }
360 | });
361 | }
362 | }
363 | }
--------------------------------------------------------------------------------