├── .gitignore ├── Library ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── io │ │ └── values │ │ └── camera │ │ └── widget │ │ ├── CameraView.java │ │ ├── FocusView.java │ │ └── ShakeListener.java │ └── res │ ├── drawable-hdpi │ └── ic_launcher.png │ ├── drawable-mdpi │ └── ic_launcher.png │ ├── drawable-xhdpi │ └── ic_launcher.png │ ├── drawable-xxhdpi │ └── ic_launcher.png │ └── values │ └── strings.xml ├── README.md ├── build.gradle ├── example ├── .gitignore ├── build.gradle ├── manifest-merger-release-report.txt ├── proguard-rules.pro ├── resocamera.jks └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── io │ │ └── values │ │ └── camera │ │ └── resocamera │ │ └── CameraActivity.java │ └── res │ ├── drawable-hdpi │ └── ic_launcher.png │ ├── drawable-mdpi │ └── ic_launcher.png │ ├── drawable-xhdpi │ ├── camera_change_normal.png │ ├── camera_change_press.png │ ├── camera_close_normal.png │ ├── camera_close_press.png │ ├── camera_flash_auto.png │ ├── camera_flash_off.png │ ├── camera_flash_on.png │ ├── camera_grid_normal.png │ ├── camera_grid_press.png │ ├── camera_take_picture_normal.png │ ├── camera_take_picture_press.png │ ├── grid.png │ └── ic_launcher.png │ ├── drawable-xxhdpi │ └── ic_launcher.png │ ├── drawable │ ├── camera_change.xml │ ├── camera_close.xml │ └── camera_take_picture.xml │ ├── layout-hdpi │ └── activity_camera.xml │ ├── layout-xhdpi │ └── activity_camera.xml │ ├── layout │ └── activity_camera.xml │ ├── values-v11 │ └── styles.xml │ └── values │ ├── attrs.xml │ ├── colors.xml │ ├── strings.xml │ └── styles.xml ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── images └── screenshot_camera.jpg └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | #built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # files for the dex VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # generated files 12 | bin/ 13 | gen/ 14 | 15 | # Local configuration file (sdk path, etc) 16 | local.properties 17 | 18 | # Windows thumbnail db 19 | Thumbs.db 20 | 21 | # OSX files 22 | .DS_Store 23 | 24 | # Eclipse project files 25 | .classpath 26 | .project 27 | 28 | # Android Studio 29 | .idea 30 | #.idea/workspace.xml - remove # and delete .idea if it better suit your needs. 31 | .gradle 32 | build/ 33 | 34 | /*/out 35 | /*/build 36 | /*/*/build 37 | /*/*/production 38 | *.iws 39 | *.ipr 40 | *~ 41 | *.swp 42 | *.iml 43 | # gradle.properties 44 | app/mapping.txt 45 | proguard/lib/proguard.jar 46 | -------------------------------------------------------------------------------- /Library/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /Library/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | android { 3 | compileSdkVersion 19 4 | buildToolsVersion "20.0.0" 5 | 6 | defaultConfig { 7 | minSdkVersion 14 8 | targetSdkVersion 14 9 | versionCode 1 10 | versionName "1.1.0" 11 | } 12 | buildTypes { 13 | release { 14 | minifyEnabled false 15 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 16 | } 17 | } 18 | } 19 | 20 | dependencies { 21 | compile fileTree(dir: 'libs', include: ['*.jar']) 22 | } -------------------------------------------------------------------------------- /Library/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Applications/Android Studio.app/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /Library/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Library/src/main/java/io/values/camera/widget/CameraView.java: -------------------------------------------------------------------------------- 1 | package io.values.camera.widget; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import android.graphics.BitmapFactory; 6 | import android.graphics.ImageFormat; 7 | import android.graphics.Matrix; 8 | import android.graphics.Rect; 9 | import android.hardware.Camera; 10 | import android.media.ExifInterface; 11 | import android.os.Environment; 12 | import android.util.DisplayMetrics; 13 | import android.util.FloatMath; 14 | import android.util.Log; 15 | import android.view.MotionEvent; 16 | import android.view.SurfaceHolder; 17 | import android.view.SurfaceView; 18 | import android.view.View; 19 | import android.view.ViewGroup; 20 | 21 | import java.io.BufferedOutputStream; 22 | import java.io.File; 23 | import java.io.FileNotFoundException; 24 | import java.io.FileOutputStream; 25 | import java.util.ArrayList; 26 | import java.util.Collections; 27 | import java.util.Comparator; 28 | import java.util.List; 29 | 30 | /** 31 | * Created by valuesfeng on 14-8-8. 32 | */ 33 | public class CameraView implements SurfaceHolder.Callback, Camera.PictureCallback, 34 | Camera.AutoFocusCallback, View.OnTouchListener, ShakeListener.OnShakeListener { 35 | 36 | public final static String TAG = CameraView.class.getSimpleName(); 37 | 38 | /** 39 | * camera flash mode 40 | */ 41 | public final static int FLASH_AUTO = 2; 42 | public final static int FLASH_OFF = 0; 43 | public final static int FLASH_ON = 1; 44 | 45 | /** 46 | * camera prewView size 47 | */ 48 | public static final int MODE4T3 = 43; 49 | public static final int MODE16T9 = 169; 50 | 51 | private int currentMODE = MODE4T3; 52 | 53 | private SurfaceHolder mHolder; 54 | private Camera mCamera; 55 | private CameraSizeComparator sizeComparator = new CameraSizeComparator(); 56 | private FocusView focusView; 57 | 58 | private int flash_type = FLASH_AUTO; // 0 close , 1 open , 2 auto 59 | private static int camera_position = Camera.CameraInfo.CAMERA_FACING_BACK;// 0 back camera , 1 front camera 60 | private int takePhotoOrientation = 90; 61 | 62 | /** 63 | * if you need square picture , you can set true while you take a picture; 64 | * see {@link #takePicture(boolean)} 65 | */ 66 | private boolean isSquare; 67 | 68 | private int topDistance; 69 | private int zoomFlag = 0; 70 | 71 | private SurfaceView surfaceView; 72 | private String PATH_DIR = Environment.getExternalStorageDirectory().getAbsolutePath() + "/ResoCamera/"; 73 | private String PATH_FILE; 74 | 75 | private String dirPath; 76 | private int screenDpi; 77 | /** 78 | * touch focus area size 79 | */ 80 | private float focusAreaSize = 300; 81 | private OnCameraSelectListener onCameraSelectListener; 82 | 83 | private int picQuality = 80; 84 | 85 | public void setPicQuality(int picQuality) { 86 | if (picQuality > 0 && picQuality < 101) 87 | this.picQuality = picQuality; 88 | } 89 | 90 | public void setOnCameraSelectListener(OnCameraSelectListener onCameraSelectListener) { 91 | this.onCameraSelectListener = onCameraSelectListener; 92 | } 93 | 94 | public void setFocusAreaSize(float focusAreaSize) { 95 | this.focusAreaSize = focusAreaSize; 96 | } 97 | 98 | public void setDirPath(String dirPath) { 99 | this.dirPath = dirPath; 100 | } 101 | 102 | private Context context; 103 | 104 | public CameraView(Context context) { 105 | this.context = context; 106 | } 107 | 108 | public void setCameraView(SurfaceView surfaceView) throws NullPointerException, ClassCastException { 109 | this.setCameraView(surfaceView, MODE4T3); 110 | } 111 | 112 | /** 113 | * @param surfaceView the camera view you should give it 114 | * @param cameraMode set the camera preview proportion ,default is MODE4T3; {@link #MODE4T3} 115 | * @throws Exception 116 | */ 117 | public void setCameraView(SurfaceView surfaceView, int cameraMode) throws NullPointerException, ClassCastException { 118 | this.surfaceView = surfaceView; 119 | this.currentMODE = cameraMode; 120 | int screenWidth = context.getResources().getDisplayMetrics().widthPixels; 121 | if (currentMODE == MODE4T3) { 122 | ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) this.surfaceView.getLayoutParams(); 123 | layoutParams.width = screenWidth; 124 | layoutParams.height = screenWidth * 4 / 3; 125 | this.surfaceView.setLayoutParams(layoutParams); 126 | } else if (currentMODE == MODE16T9) { 127 | ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) this.surfaceView.getLayoutParams(); 128 | layoutParams.width = screenWidth; 129 | layoutParams.height = screenWidth * 16 / 9; 130 | this.surfaceView.setLayoutParams(layoutParams); 131 | } 132 | ShakeListener.newInstance().setOnShakeListener(this); 133 | screenDpi = context.getResources().getDisplayMetrics().densityDpi; 134 | mHolder = surfaceView.getHolder(); 135 | surfaceView.setOnTouchListener(this); 136 | mHolder.addCallback(this); 137 | mHolder.setKeepScreenOn(true); 138 | mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 139 | } 140 | 141 | /** 142 | * set camera top distance 143 | * 144 | * @param topDistance 145 | */ 146 | public void setTopDistance(int topDistance) { 147 | this.topDistance = topDistance; 148 | } 149 | 150 | public void setFocusView(FocusView focusView) { 151 | this.focusView = focusView; 152 | } 153 | 154 | @Override 155 | public void surfaceCreated(SurfaceHolder holder) { 156 | if (screenDpi == DisplayMetrics.DENSITY_HIGH) { 157 | zoomFlag = 10; 158 | } 159 | } 160 | 161 | @Override 162 | public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 163 | mHolder = holder; 164 | mHolder.setKeepScreenOn(true); 165 | } 166 | 167 | @Override 168 | public void surfaceDestroyed(SurfaceHolder holder) { 169 | closeCamera(); 170 | } 171 | 172 | private void openCamera() { 173 | try { 174 | closeCamera(); 175 | mCamera = Camera.open(camera_position); 176 | mCamera.setDisplayOrientation(90); 177 | mCamera.setPreviewDisplay(mHolder); 178 | setCameraPictureSize(); 179 | setCameraPreviewSize(); 180 | changeFlash(flash_type); 181 | mCamera.startPreview(); 182 | } catch (Exception e) { 183 | e.printStackTrace(); 184 | } 185 | } 186 | 187 | private void closeCamera() { 188 | if (mCamera != null) { 189 | mCamera.stopPreview(); 190 | mCamera.release(); 191 | } 192 | flash_type = FLASH_AUTO; 193 | mCamera = null; 194 | } 195 | 196 | private void resetCamera() { 197 | if (onCameraSelectListener != null) { 198 | onCameraSelectListener.onChangeCameraPosition(camera_position); 199 | } 200 | Log.i(TAG, "camera-camera-position:" + camera_position); 201 | closeCamera(); 202 | openCamera(); 203 | } 204 | 205 | private void setCameraPreviewSize() { 206 | Camera.Parameters params = mCamera.getParameters(); 207 | List sizes = params.getSupportedPreviewSizes(); 208 | Collections.sort(sizes, sizeComparator); 209 | for (Camera.Size size : sizes) { 210 | params.setPreviewSize(size.width, size.height); 211 | if (size.width * 1.0 / size.height * 1.0 == 4.0 / 3.0 && currentMODE == MODE4T3) { 212 | break; 213 | } else if (size.width * 1.0 / size.height * 1.0 == 16.0 / 9.0 && currentMODE == MODE16T9) { 214 | break; 215 | } 216 | } 217 | mCamera.setParameters(params); 218 | } 219 | 220 | private void setCameraPictureSize() { 221 | Camera.Parameters params = mCamera.getParameters(); 222 | List sizes = params.getSupportedPictureSizes(); 223 | Collections.sort(sizes, sizeComparator); 224 | for (Camera.Size size : sizes) { 225 | params.setPictureSize(size.width, size.height); 226 | if (size.width * 1.0 / size.height * 1.0 == 4.0 / 3.0 227 | && currentMODE == MODE4T3 && size.height < 2000) { 228 | break; 229 | } else if (size.width * 1.0 / size.height * 1.0 == 16.0 / 9.0 230 | && currentMODE == MODE16T9 && size.height < 2000) { 231 | break; 232 | } 233 | } 234 | params.setJpegQuality(picQuality); 235 | params.setPictureFormat(ImageFormat.JPEG); 236 | mCamera.setParameters(params); 237 | } 238 | 239 | /** 240 | * use with activity or fragment life circle 241 | */ 242 | public final void onResume() { 243 | Log.i(TAG, "camera-resume"); 244 | if (surfaceView == null) 245 | throw new NullPointerException("not init surfaceView for camera view"); 246 | openCamera(); 247 | ShakeListener.newInstance().start(context); 248 | } 249 | 250 | /** 251 | * seem to onResume 252 | * {@link #onResume()} 253 | */ 254 | public final void onPause() { 255 | Log.i(TAG, "camera-pause"); 256 | closeCamera(); 257 | ShakeListener.newInstance().stop(); 258 | } 259 | 260 | public final int changeFlash(int flash_type) { 261 | this.flash_type = flash_type; 262 | return changeFlash(); 263 | } 264 | 265 | /** 266 | * change camera flash mode 267 | */ 268 | public final int changeFlash() { 269 | if (mCamera == null) { 270 | return -1; 271 | } 272 | Camera.Parameters parameters = mCamera.getParameters(); 273 | List flashModes = parameters.getSupportedFlashModes(); 274 | if (flashModes == null || flashModes.size() <= 1) { 275 | return 0; 276 | } 277 | if (onCameraSelectListener != null) { 278 | onCameraSelectListener.onChangeFlashMode((flash_type) % 3); 279 | } 280 | Log.i(TAG, "camera-flash-type:" + flash_type); 281 | switch (flash_type % 3) { 282 | case FLASH_ON: 283 | if (flashModes.contains(Camera.Parameters.FLASH_MODE_ON)) { 284 | parameters.setFlashMode(Camera.Parameters.FLASH_MODE_ON); 285 | flash_type++; 286 | mCamera.setParameters(parameters); 287 | } 288 | break; 289 | case FLASH_OFF: 290 | if (flashModes.contains(Camera.Parameters.FLASH_MODE_OFF)) { 291 | parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); 292 | flash_type++; 293 | mCamera.setParameters(parameters); 294 | } 295 | break; 296 | case FLASH_AUTO: 297 | if (flashModes.contains(Camera.Parameters.FLASH_MODE_AUTO)) { 298 | parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO); 299 | flash_type++; 300 | mCamera.setParameters(parameters); 301 | } 302 | break; 303 | default: 304 | if (flashModes.contains(Camera.Parameters.FLASH_MODE_OFF)) { 305 | parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); 306 | flash_type++; 307 | mCamera.setParameters(parameters); 308 | } 309 | break; 310 | } 311 | return flash_type; 312 | } 313 | 314 | /** 315 | * change camera facing 316 | */ 317 | public final int changeCamera() { 318 | Camera.CameraInfo cameraInfo = new Camera.CameraInfo(); 319 | int cameraCount = Camera.getNumberOfCameras(); 320 | for (int i = 0; i < cameraCount; i++) { 321 | Camera.getCameraInfo(i, cameraInfo); 322 | if (camera_position == Camera.CameraInfo.CAMERA_FACING_BACK) { 323 | camera_position = Camera.CameraInfo.CAMERA_FACING_FRONT; 324 | resetCamera(); 325 | return camera_position; 326 | } else if (camera_position == Camera.CameraInfo.CAMERA_FACING_FRONT) { 327 | camera_position = Camera.CameraInfo.CAMERA_FACING_BACK; 328 | resetCamera(); 329 | return camera_position; 330 | } 331 | } 332 | return camera_position; 333 | } 334 | 335 | public final void takePicture(boolean isSquare) { 336 | if (mCamera != null) { 337 | this.isSquare = isSquare; 338 | mCamera.takePicture(null, null, this); 339 | } 340 | } 341 | 342 | @Override 343 | public void onPictureTaken(final byte[] data, final Camera camera) { 344 | try { 345 | if (dirPath != null && !dirPath.equals("")) { 346 | PATH_DIR = dirPath; 347 | } 348 | PATH_FILE = PATH_DIR + "IMG_" + System.currentTimeMillis() + ".jpg"; 349 | createFolder(PATH_DIR); 350 | createFile(PATH_FILE); 351 | new Thread(new Runnable() { 352 | @Override 353 | public void run() { 354 | Bitmap bitmap = null; 355 | try { 356 | bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); 357 | FileOutputStream fos; 358 | ExifInterface exifInterface = new ExifInterface(PATH_FILE); 359 | switch (takePhotoOrientation) { 360 | case 0: 361 | exifInterface.setAttribute(ExifInterface.TAG_ORIENTATION, String.valueOf(ExifInterface.ORIENTATION_NORMAL)); 362 | break; 363 | case 90: 364 | exifInterface.setAttribute(ExifInterface.TAG_ORIENTATION, String.valueOf(ExifInterface.ORIENTATION_ROTATE_90)); 365 | break; 366 | case 180: 367 | exifInterface.setAttribute(ExifInterface.TAG_ORIENTATION, String.valueOf(ExifInterface.ORIENTATION_ROTATE_180)); 368 | break; 369 | case 270: 370 | exifInterface.setAttribute(ExifInterface.TAG_ORIENTATION, String.valueOf(ExifInterface.ORIENTATION_ROTATE_270)); 371 | break; 372 | } 373 | if (camera_position == Camera.CameraInfo.CAMERA_FACING_FRONT) { 374 | Matrix matrix = new Matrix(); 375 | matrix.postScale(-1, 1); 376 | bitmap = Bitmap.createBitmap(bitmap, 0, 0, 377 | bitmap.getWidth(), bitmap.getHeight(), matrix, 378 | true); 379 | } 380 | if (isSquare) { 381 | bitmap = Bitmap.createBitmap(bitmap, 0, 0, 382 | bitmap.getHeight(), bitmap.getHeight(), null, 383 | true); 384 | } 385 | System.gc(); 386 | fos = new FileOutputStream(PATH_FILE); 387 | BufferedOutputStream bos = new BufferedOutputStream(fos); 388 | bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos); 389 | bos.flush(); 390 | bos.close(); 391 | exifInterface.saveAttributes(); 392 | bitmap.recycle(); 393 | if (onCameraSelectListener != null) { 394 | onCameraSelectListener.onTakePicture(true, PATH_FILE); 395 | } 396 | openCamera(); 397 | } catch (Exception e) { 398 | if (bitmap != null) 399 | bitmap.recycle(); 400 | e.printStackTrace(); 401 | if (onCameraSelectListener != null) { 402 | onCameraSelectListener.onTakePicture(false, "相机出错啦!"); 403 | } 404 | } 405 | System.gc(); 406 | takePhotoOrientation = 0; 407 | } 408 | }).start(); 409 | closeCamera(); 410 | } catch (Exception e) { 411 | e.printStackTrace(); 412 | } 413 | } 414 | 415 | @Override 416 | public void onAutoFocus(boolean success, Camera camera) { 417 | if (focusView != null) { 418 | focusView.clearDraw(); 419 | } 420 | } 421 | 422 | /** 423 | * Convert touch position x:y in (-1000~1000) 424 | */ 425 | private Rect calculateTapArea(float x, float y, float coefficient) { 426 | int areaSize = Float.valueOf(focusAreaSize * coefficient).intValue(); 427 | x = x / surfaceView.getWidth(); 428 | y = y / surfaceView.getHeight(); 429 | 430 | float cameraX = y; 431 | float cameraY = 1 - x; 432 | 433 | int centerX = (int) (cameraX * 2000 - 1000); 434 | int centerY = (int) (cameraY * 2000 - 1000); 435 | int left = clamp(centerX - areaSize / 2, -1000, 1000); 436 | int top = clamp(centerY - areaSize / 2, -1000, 1000); 437 | int right = clamp(left + areaSize, -1000, 1000); 438 | int bottom = clamp(top + areaSize, -1000, 1000); 439 | 440 | return new Rect(left, top, right, bottom); 441 | } 442 | 443 | private int clamp(int x, int min, int max) { 444 | if (x > max) { 445 | return max; 446 | } 447 | if (x < min) { 448 | return min; 449 | } 450 | return x; 451 | } 452 | 453 | private float mDist; 454 | 455 | @Override 456 | public boolean onTouch(View view, MotionEvent event) { 457 | if (mCamera == null) { 458 | return false; 459 | } 460 | Camera.Parameters params = mCamera.getParameters(); 461 | int action = event.getAction(); 462 | 463 | if (event.getPointerCount() > 1) { 464 | if (action == MotionEvent.ACTION_POINTER_DOWN) { 465 | mDist = getFingerSpacing(event); 466 | } else if (action == MotionEvent.ACTION_MOVE && params.isZoomSupported()) { 467 | mCamera.cancelAutoFocus(); 468 | handleZoom(event, params); 469 | } 470 | if (focusView != null) { 471 | focusView.clearDraw(); 472 | } 473 | } else { 474 | if (action == MotionEvent.ACTION_DOWN) { 475 | if (focusView != null) { 476 | focusView.clearDraw(); 477 | focusView.drawLine(event.getRawX(), event.getRawY() - topDistance); 478 | } 479 | } 480 | if (action == MotionEvent.ACTION_UP) { 481 | handleFocus(event); 482 | } 483 | } 484 | return true; 485 | } 486 | 487 | private void handleZoom(MotionEvent event, Camera.Parameters params) { 488 | int maxZoom = params.getMaxZoom(); 489 | int zoom = params.getZoom(); 490 | float newDist = getFingerSpacing(event); 491 | if (newDist > mDist && newDist - mDist > zoomFlag) { 492 | if (zoom < maxZoom) 493 | zoom++; 494 | } else if (newDist < mDist && mDist - newDist > zoomFlag) { 495 | if (zoom > 0) 496 | zoom--; 497 | } 498 | mDist = newDist; 499 | params.setZoom(zoom); 500 | mCamera.setParameters(params); 501 | } 502 | 503 | public void handleFocus(MotionEvent event) { 504 | if (mCamera != null) { 505 | mCamera.cancelAutoFocus(); 506 | 507 | Rect focusRect = calculateTapArea(event.getRawX(), event.getRawY() - topDistance, 1f); 508 | Rect meteringRect = calculateTapArea(event.getRawX(), event.getRawY() - topDistance, 2f); 509 | 510 | Camera.Parameters parameters = mCamera.getParameters(); 511 | if (parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_AUTO)) 512 | parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); 513 | 514 | if (parameters.getMaxNumFocusAreas() > 0) { 515 | List areaList = new ArrayList(); 516 | areaList.add(new Camera.Area(focusRect, 1000)); 517 | parameters.setFocusAreas(areaList); 518 | } 519 | 520 | if (parameters.getMaxNumMeteringAreas() > 0) { 521 | List meteringList = new ArrayList(); 522 | meteringList.add(new Camera.Area(meteringRect, 1000)); 523 | parameters.setMeteringAreas(meteringList); 524 | } 525 | 526 | mCamera.setParameters(parameters); 527 | mCamera.autoFocus(this); 528 | } 529 | } 530 | 531 | private float getFingerSpacing(MotionEvent event) { 532 | float x = event.getX(0) - event.getX(1); 533 | float y = event.getY(0) - event.getY(1); 534 | return FloatMath.sqrt(x * x + y * y); 535 | } 536 | 537 | private void createParentFolder(File file) throws Exception { 538 | if (!file.getParentFile().exists()) { 539 | if (!file.getParentFile().mkdirs()) { 540 | throw new Exception("create parent directory failure!"); 541 | } 542 | } 543 | } 544 | 545 | private void createFolder(String path) throws Exception { 546 | path = separatorReplace(path); 547 | File folder = new File(path); 548 | if (folder.isDirectory()) { 549 | return; 550 | } else if (folder.isFile()) { 551 | deleteFile(path); 552 | } 553 | folder.mkdirs(); 554 | } 555 | 556 | private File createFile(String path) throws Exception { 557 | path = separatorReplace(path); 558 | File file = new File(path); 559 | if (file.isFile()) { 560 | return file; 561 | } else if (file.isDirectory()) { 562 | deleteFolder(path); 563 | } 564 | return createFile(file); 565 | } 566 | 567 | private File createFile(File file) throws Exception { 568 | createParentFolder(file); 569 | if (!file.createNewFile()) { 570 | throw new Exception("create file failure!"); 571 | } 572 | return file; 573 | } 574 | 575 | private void deleteFolder(String path) throws Exception { 576 | path = separatorReplace(path); 577 | File folder = getFolder(path); 578 | File[] files = folder.listFiles(); 579 | for (File file : files) { 580 | if (file.isDirectory()) { 581 | deleteFolder(file.getAbsolutePath()); 582 | } else if (file.isFile()) { 583 | deleteFile(file.getAbsolutePath()); 584 | } 585 | } 586 | folder.delete(); 587 | } 588 | 589 | private File getFolder(String path) throws FileNotFoundException { 590 | path = separatorReplace(path); 591 | File folder = new File(path); 592 | if (!folder.isDirectory()) { 593 | throw new FileNotFoundException("folder not found!"); 594 | } 595 | return folder; 596 | } 597 | 598 | private String separatorReplace(String path) { 599 | return path.replace("\\", "/"); 600 | } 601 | 602 | private void deleteFile(String path) throws Exception { 603 | path = separatorReplace(path); 604 | File file = getFile(path); 605 | if (!file.delete()) { 606 | throw new Exception("delete file failure"); 607 | } 608 | } 609 | 610 | private File getFile(String path) throws FileNotFoundException { 611 | path = separatorReplace(path); 612 | File file = new File(path); 613 | if (!file.isFile()) { 614 | throw new FileNotFoundException("file not found!"); 615 | } 616 | return file; 617 | } 618 | 619 | @Override 620 | public void onShake(int orientation) { 621 | if (onCameraSelectListener != null) { 622 | onCameraSelectListener.onShake(orientation); 623 | } 624 | this.takePhotoOrientation = orientation; 625 | } 626 | 627 | public interface OnCameraSelectListener { 628 | public void onTakePicture(boolean success, String filePath); 629 | 630 | public void onChangeFlashMode(int flashMode); 631 | 632 | public void onChangeCameraPosition(int camera_position); 633 | 634 | public void onShake(int orientation); 635 | } 636 | 637 | public static class CameraSizeComparator implements Comparator { 638 | public int compare(Camera.Size lhs, Camera.Size rhs) { 639 | if (lhs.width == rhs.width) { 640 | return 0; 641 | } else if (lhs.width < rhs.width) { 642 | return 1; 643 | } else { 644 | return -1; 645 | } 646 | } 647 | } 648 | } -------------------------------------------------------------------------------- /Library/src/main/java/io/values/camera/widget/FocusView.java: -------------------------------------------------------------------------------- 1 | package io.values.camera.widget; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import android.graphics.BitmapFactory; 6 | import android.graphics.Canvas; 7 | import android.graphics.Color; 8 | import android.graphics.Paint; 9 | import android.graphics.PixelFormat; 10 | import android.graphics.PorterDuff; 11 | import android.graphics.PorterDuffXfermode; 12 | import android.util.AttributeSet; 13 | import android.view.SurfaceHolder; 14 | import android.view.SurfaceView; 15 | 16 | /** 17 | * Created by ${valuesFeng} on ${2014.9.1}. 18 | */ 19 | public class FocusView extends SurfaceView implements SurfaceHolder.Callback { 20 | 21 | private Context context; 22 | protected SurfaceHolder sh; 23 | private Bitmap bitmap; 24 | 25 | private Paint paint = new Paint(); 26 | 27 | private float rectWidth; 28 | 29 | public void setRectWidth(int rectDpiWidth) { 30 | float scale = context.getResources().getDisplayMetrics().density; 31 | rectWidth = (int) (rectDpiWidth * scale + 0.5f); 32 | } 33 | 34 | public FocusView(Context context) { 35 | super(context); 36 | } 37 | 38 | public FocusView(Context context, AttributeSet attrs) { 39 | super(context, attrs); 40 | this.context = context; 41 | float scale = context.getResources().getDisplayMetrics().density; 42 | rectWidth = (int) (25 * scale + 0.5f); 43 | sh = getHolder(); 44 | sh.addCallback(this); 45 | sh.setFormat(PixelFormat.TRANSPARENT); 46 | setZOrderOnTop(true); 47 | paint.setColor(Color.TRANSPARENT); 48 | } 49 | 50 | public void setBitmap(Bitmap bitmap) { 51 | this.bitmap = bitmap; 52 | } 53 | 54 | public void setBitmap(int res) { 55 | bitmap = BitmapFactory.decodeResource(context.getResources(), res); 56 | } 57 | 58 | public void surfaceChanged(SurfaceHolder arg0, int arg1, int w, int h) { 59 | } 60 | 61 | public void surfaceCreated(SurfaceHolder arg0) { 62 | 63 | } 64 | 65 | public void surfaceDestroyed(SurfaceHolder arg0) { 66 | 67 | } 68 | 69 | synchronized void clearDraw() { 70 | Canvas canvas = sh.lockCanvas(); 71 | Paint paint = new Paint(); 72 | paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); 73 | canvas.drawPaint(paint); 74 | paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC)); 75 | canvas.drawColor(Color.TRANSPARENT); 76 | sh.unlockCanvasAndPost(canvas); 77 | } 78 | 79 | public synchronized void drawLine(float x, float y) { 80 | Canvas canvas = sh.lockCanvas(); 81 | canvas.drawColor(Color.TRANSPARENT); 82 | Paint paint = new Paint(); 83 | paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); 84 | canvas.drawPaint(paint); 85 | if (bitmap != null) { 86 | paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC)); 87 | canvas.drawBitmap(bitmap, x - bitmap.getWidth() / 2, y - bitmap.getHeight() / 2, paint); 88 | } else { 89 | Paint paints = new Paint(); 90 | paints.setStrokeWidth(1.5f); 91 | paints.setStyle(Paint.Style.STROKE); 92 | paints.setColor(Color.GREEN); 93 | paints.clearShadowLayer(); 94 | paint.setAntiAlias(true); 95 | canvas.drawCircle(x, y, rectWidth, paints); 96 | } 97 | sh.unlockCanvasAndPost(canvas); 98 | } 99 | } -------------------------------------------------------------------------------- /Library/src/main/java/io/values/camera/widget/ShakeListener.java: -------------------------------------------------------------------------------- 1 | package io.values.camera.widget; 2 | 3 | import android.content.Context; 4 | import android.hardware.Sensor; 5 | import android.hardware.SensorEvent; 6 | import android.hardware.SensorEventListener; 7 | import android.hardware.SensorManager; 8 | 9 | /** 10 | * Created by valuesfeng on 14-7-30. 11 | */ 12 | public class ShakeListener implements SensorEventListener { 13 | 14 | public static final int LandscapeLeft = 0; 15 | public static final int LandscapeRight = 180; 16 | public static final int Portrait = 90; 17 | private SensorManager sensorManager; 18 | private static ShakeListener sensor1; 19 | private Sensor sensor; 20 | private OnShakeListener onShakeListener; 21 | 22 | public static ShakeListener newInstance() { 23 | if (sensor1 == null) { 24 | sensor1 = new ShakeListener(); 25 | } 26 | return sensor1; 27 | } 28 | 29 | public void start(Context context) { 30 | if (sensorManager == null) { 31 | sensorManager = (SensorManager) context 32 | .getSystemService(Context.SENSOR_SERVICE); 33 | } 34 | if (sensorManager != null && sensor == null) { 35 | sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 36 | } 37 | if (sensor != null) { 38 | try { 39 | sensorManager.registerListener(this, sensor, 40 | SensorManager.SENSOR_DELAY_NORMAL); 41 | } catch (NullPointerException e) { 42 | e.printStackTrace(); 43 | } 44 | } 45 | } 46 | 47 | public void stop() { 48 | if (sensorManager != null) 49 | sensorManager.unregisterListener(this); 50 | } 51 | 52 | public interface OnShakeListener { 53 | public void onShake(int orientation); 54 | } 55 | 56 | public void setOnShakeListener(OnShakeListener listener) { 57 | onShakeListener = listener; 58 | } 59 | 60 | @Override 61 | public void onSensorChanged(SensorEvent event) { 62 | float x = event.values[0]; 63 | float y = event.values[1]; 64 | float z = event.values[2]; 65 | 66 | float g = 9.8f; 67 | float ghysteresis = g / 5; 68 | float ghalf = g * (float) Math.sqrt(2) / 2; 69 | if (Math.abs(z) > ghalf) { 70 | return; 71 | } 72 | 73 | if (x <= -ghalf - ghysteresis / 2) { 74 | onShakeListener.onShake(LandscapeRight); 75 | } else if (y >= ghalf + ghysteresis / 2) { 76 | onShakeListener.onShake(Portrait); 77 | } else if (x >= ghalf + ghysteresis / 2) { 78 | onShakeListener.onShake(LandscapeLeft); 79 | } 80 | 81 | } 82 | 83 | public void onAccuracyChanged(Sensor sensor, int accuracy) { 84 | 85 | } 86 | } -------------------------------------------------------------------------------- /Library/src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValuesFeng/ResoCamera/a7e54cebbdf74a3b601687d77e1b2e53940c3ae0/Library/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /Library/src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValuesFeng/ResoCamera/a7e54cebbdf74a3b601687d77e1b2e53940c3ae0/Library/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /Library/src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValuesFeng/ResoCamera/a7e54cebbdf74a3b601687d77e1b2e53940c3ae0/Library/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Library/src/main/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValuesFeng/ResoCamera/a7e54cebbdf74a3b601687d77e1b2e53940c3ae0/Library/src/main/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Library/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Library 3 | 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ResoCamera 2 | ========== 3 | 4 | ![Screenshot](https://github.com/ValuesFeng/ResoCamera/blob/master/images/screenshot_camera.jpg) 5 | #### Download 6 | [resoCamera.apk](http://1.values.sinaapp.com/download/resoCamera.apk) 7 | Function: 8 | ========== 9 | * you can set preview size 16:9 or 4:3 10 | * Flash Control 11 | * Touch Focus 12 | * Front and rear camera toggle 13 | * Two-finger zoom control camera preview 14 | * After taking a picture of the filter(Based on GPUImage) 15 | 16 | 17 | ## Simple 18 | * Flash Mode : FLASH_AUTO (`default`),FLASH_OPEN,FLASH_CLOSE; 19 | * Camera Preview Proportion : MODE4T3(`default`),MODE16T9; 20 | 21 | #### you can use: 22 | mCamera.changeFlash(); 23 | mCamera.changeCamera(); 24 | mCamera.takePicture(); 25 | 26 | ````java 27 | public interface OnCameraSelectListener { 28 | public void onTakePicture(boolean success, String filePath); 29 | public void onChangeFlashMode(int flashMode); 30 | public void onChangeCameraPosition(int camera_position); 31 | } 32 | ```` 33 | 34 | ## Update 35 | * Enhance the speed camera 36 | * you can set picture quality now (1-100) 37 | * fix bug - take picture orientation 38 | 39 | 40 | ## Usage 41 | ```gradle 42 | repositories { 43 | // ... 44 | maven { url "https://jitpack.io" } 45 | } 46 | 47 | 48 | dependencies { 49 | compile 'com.github.ValuesFeng:ResoCamera:0.1' 50 | } 51 | ``` 52 | ## Quick Setup 53 | #### 1. Android Manifest 54 | ``` xml 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | ``` 63 | #### 2. Activity Class 64 | ````xml 65 | 66 | ```` 67 | 68 | 69 | ````java 70 | 71 | @Override 72 | protected void onCreate(Bundle savedInstanceState) { 73 | super.onCreate(savedInstanceState); 74 | setContentView(R.layout.activity_camera); 75 | try { 76 | cameraView = new CameraView(this); 77 | cameraView.setFocusView((FocusView) findViewById(R.id.sf_focus)); 78 | /** 79 | * setCameraView(SurfaceView surfaceView, int screenWidth, int cameraMode) 80 | */ 81 | // cameraView.setCameraView((SurfaceView) findViewById(R.id.sf_camera)); 82 | cameraView.setCameraView((SurfaceView) findViewById(R.id.sf_camera),CameraView.MODE4T3); 83 | } catch (Exception e) { 84 | e.printStackTrace(); 85 | } 86 | } 87 | 88 | @Override 89 | public void onWindowFocusChanged(boolean hasFocus) { 90 | super.onWindowFocusChanged(hasFocus); 91 | if (hasFocus) { 92 | cameraView.onResume();//must 93 | }else{ 94 | cameraView.onPause(); 95 | } 96 | } 97 | 98 | //@Override 99 | //protected void onPause() { 100 | // super.onPause(); 101 | // if (cameraView != null) 102 | // cameraView.onPause(); //must 103 | //} 104 | ```` 105 | 106 | ## License 107 | Copyright 2011-2014 valuesFeng 108 | 109 | Licensed under the Apache License, Version 2.0 (the "License"); 110 | you may not use this file except in compliance with the License. 111 | You may obtain a copy of the License at 112 | 113 | http://www.apache.org/licenses/LICENSE-2.0 114 | 115 | Unless required by applicable law or agreed to in writing, software 116 | distributed under the License is distributed on an "AS IS" BASIS, 117 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 118 | See the License for the specific language governing permissions and 119 | limitations under the License. 120 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:1.0.0' 9 | 10 | // NOTE: Do not place your application dependencies here; they belong 11 | // in the individual module build.gradle files 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | jcenter() 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /example/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 20 5 | buildToolsVersion "20.0.0" 6 | 7 | defaultConfig { 8 | applicationId "io.values.camera.resocamera" 9 | minSdkVersion 14 10 | targetSdkVersion 20 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | buildscript { 23 | repositories { 24 | mavenCentral() 25 | } 26 | dependencies { 27 | classpath 'com.android.tools.build:gradle:1.0.+' 28 | } 29 | } 30 | 31 | 32 | allprojects { 33 | repositories { 34 | mavenCentral() 35 | } 36 | } 37 | 38 | dependencies { 39 | compile fileTree(dir: 'libs', include: ['*.jar']) 40 | compile 'com.android.support:support-v4:20.0.0' 41 | compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.3' 42 | compile project(':Library') 43 | } 44 | 45 | -------------------------------------------------------------------------------- /example/manifest-merger-release-report.txt: -------------------------------------------------------------------------------- 1 | -- Merging decision tree log --- 2 | manifest 3 | ADDED from AndroidManifest.xml:2:1 4 | package 5 | ADDED from AndroidManifest.xml:3:5 6 | INJECTED from AndroidManifest.xml:0:0 7 | INJECTED from AndroidManifest.xml:0:0 8 | android:versionName 9 | INJECTED from AndroidManifest.xml:0:0 10 | INJECTED from AndroidManifest.xml:0:0 11 | xmlns:android 12 | ADDED from AndroidManifest.xml:2:11 13 | android:versionCode 14 | INJECTED from AndroidManifest.xml:0:0 15 | INJECTED from AndroidManifest.xml:0:0 16 | uses-permission#android.permission.CAMERA 17 | ADDED from AndroidManifest.xml:5:5 18 | android:name 19 | ADDED from AndroidManifest.xml:5:22 20 | uses-feature#android.hardware.camera 21 | ADDED from AndroidManifest.xml:7:5 22 | android:name 23 | ADDED from AndroidManifest.xml:7:19 24 | uses-feature#android.hardware.camera.autofocus 25 | ADDED from AndroidManifest.xml:8:5 26 | android:name 27 | ADDED from AndroidManifest.xml:8:19 28 | uses-permission#android.permission.WRITE_EXTERNAL_STORAGE 29 | ADDED from AndroidManifest.xml:10:5 30 | android:name 31 | ADDED from AndroidManifest.xml:10:22 32 | uses-permission#android.permission.READ_EXTERNAL_STORAGE 33 | ADDED from AndroidManifest.xml:11:5 34 | android:name 35 | ADDED from AndroidManifest.xml:11:22 36 | application 37 | ADDED from AndroidManifest.xml:13:5 38 | MERGED from com.android.support:support-v4:20.0.0:17:5 39 | MERGED from ResoCamera:Library:unspecified:11:5 40 | android:label 41 | ADDED from AndroidManifest.xml:16:9 42 | android:allowBackup 43 | ADDED from AndroidManifest.xml:14:9 44 | android:icon 45 | ADDED from AndroidManifest.xml:15:9 46 | android:theme 47 | ADDED from AndroidManifest.xml:17:9 48 | activity#io.values.camera.resocamera.CameraActivity 49 | ADDED from AndroidManifest.xml:18:9 50 | android:screenOrientation 51 | ADDED from AndroidManifest.xml:21:13 52 | android:label 53 | ADDED from AndroidManifest.xml:22:13 54 | android:configChanges 55 | ADDED from AndroidManifest.xml:20:13 56 | android:name 57 | ADDED from AndroidManifest.xml:19:13 58 | intent-filter#android.intent.action.MAIN+android.intent.category.LAUNCHER 59 | ADDED from AndroidManifest.xml:23:13 60 | action#android.intent.action.MAIN 61 | ADDED from AndroidManifest.xml:24:17 62 | android:name 63 | ADDED from AndroidManifest.xml:24:25 64 | category#android.intent.category.LAUNCHER 65 | ADDED from AndroidManifest.xml:26:17 66 | android:name 67 | ADDED from AndroidManifest.xml:26:27 68 | uses-sdk 69 | INJECTED from AndroidManifest.xml:0:0 reason: use-sdk injection requested 70 | MERGED from com.android.support:support-v4:20.0.0:16:5 71 | MERGED from ResoCamera:Library:unspecified:7:5 72 | android:targetSdkVersion 73 | INJECTED from AndroidManifest.xml:0:0 74 | INJECTED from AndroidManifest.xml:0:0 75 | android:minSdkVersion 76 | INJECTED from AndroidManifest.xml:0:0 77 | INJECTED from AndroidManifest.xml:0:0 78 | -------------------------------------------------------------------------------- /example/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Applications/Android Studio.app/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /example/resocamera.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValuesFeng/ResoCamera/a7e54cebbdf74a3b601687d77e1b2e53940c3ae0/example/resocamera.jks -------------------------------------------------------------------------------- /example/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 18 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /example/src/main/java/io/values/camera/resocamera/CameraActivity.java: -------------------------------------------------------------------------------- 1 | package io.values.camera.resocamera; 2 | 3 | import android.app.Activity; 4 | import android.database.Cursor; 5 | import android.graphics.Bitmap; 6 | import android.os.Bundle; 7 | import android.provider.MediaStore; 8 | import android.util.DisplayMetrics; 9 | import android.util.Log; 10 | import android.view.SurfaceView; 11 | import android.view.View; 12 | import android.widget.ImageButton; 13 | import android.widget.ImageView; 14 | import android.widget.RelativeLayout; 15 | import android.widget.Toast; 16 | 17 | import com.nostra13.universalimageloader.cache.memory.impl.LRULimitedMemoryCache; 18 | import com.nostra13.universalimageloader.core.DisplayImageOptions; 19 | import com.nostra13.universalimageloader.core.ImageLoader; 20 | import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; 21 | import com.nostra13.universalimageloader.core.assist.ImageScaleType; 22 | import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer; 23 | 24 | import io.values.camera.widget.CameraView; 25 | import io.values.camera.widget.FocusView; 26 | 27 | 28 | public class CameraActivity extends Activity implements CameraView.OnCameraSelectListener, 29 | View.OnClickListener { 30 | 31 | private CameraView cameraView; 32 | 33 | DisplayImageOptions options = new DisplayImageOptions.Builder().bitmapConfig(Bitmap.Config.ARGB_8888) 34 | .imageScaleType(ImageScaleType.EXACTLY).considerExifParams(true) 35 | .cacheInMemory(false).cacheOnDisk(false).displayer(new FadeInBitmapDisplayer(0)).build(); 36 | 37 | private RelativeLayout rlTop; 38 | 39 | private ImageButton ib_camera_change; 40 | private ImageButton ib_camera_flash; 41 | private ImageButton ib_camera_grid; 42 | 43 | private ImageButton ibTakePicture; 44 | private ImageView ibCameraPhotos; 45 | 46 | private ImageView imgGrid; 47 | 48 | @Override 49 | protected void onCreate(Bundle savedInstanceState) { 50 | super.onCreate(savedInstanceState); 51 | initImaLoader(); 52 | setContentView(R.layout.activity_camera); 53 | try { 54 | cameraView = new CameraView(this); 55 | cameraView.setOnCameraSelectListener(this); 56 | cameraView.setFocusView((FocusView) findViewById(R.id.sf_focus)); 57 | // cameraView.setCameraView((SurfaceView) findViewById(R.id.sf_camera)); //default 58 | cameraView.setCameraView((SurfaceView) findViewById(R.id.sf_camera), CameraView.MODE4T3); 59 | cameraView.setPicQuality(50); 60 | } catch (Exception e) { 61 | e.printStackTrace(); 62 | } 63 | initViews(); 64 | showDCIM(); 65 | } 66 | 67 | private void initViews() { 68 | rlTop = $(R.id.rl_top); 69 | ib_camera_change = $(R.id.ib_camera_change); 70 | ib_camera_flash = $(R.id.ib_camera_flash); 71 | ib_camera_grid = $(R.id.ib_camera_grid); 72 | ibTakePicture = $(R.id.ib_camera_take_picture); 73 | ibCameraPhotos = $(R.id.ib_camera_photos); 74 | imgGrid = $(R.id.img_grid); 75 | } 76 | 77 | private T $(int resId) { 78 | return (T) super.findViewById(resId); 79 | } 80 | 81 | private void initImaLoader() { 82 | ImageLoaderConfiguration config = 83 | new ImageLoaderConfiguration 84 | .Builder(getApplicationContext()) 85 | .diskCacheFileCount(50) 86 | .threadPoolSize(Thread.NORM_PRIORITY - 2) 87 | .denyCacheImageMultipleSizesInMemory() 88 | .memoryCacheSize(30) 89 | .memoryCache(new LRULimitedMemoryCache(30)) 90 | .build(); 91 | ImageLoader.getInstance().init(config); 92 | } 93 | 94 | /** 95 | * get first picture DCIM 96 | */ 97 | private void showDCIM() { 98 | String columns[] = new String[]{ 99 | MediaStore.Images.Media.DATA, MediaStore.Images.Media._ID, MediaStore.Images.Media.TITLE, MediaStore.Images.Media.DISPLAY_NAME 100 | }; 101 | Cursor cursor = this.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns, null, null, null); 102 | boolean isOK = false; 103 | if (cursor != null) { 104 | cursor.moveToLast(); 105 | String path = ""; 106 | try { 107 | while (!isOK) { 108 | int photoIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); 109 | path = cursor.getString(photoIndex); 110 | isOK = !(path.indexOf("DCIM/Camera") == -1); //Is thie photo from DCIM folder ? 111 | cursor.moveToPrevious(); //Add this so we don't get an infinite loop if the first image from 112 | //the cursor is not from DCIM 113 | } 114 | } catch (Exception e) { 115 | e.printStackTrace(); 116 | } finally { 117 | cursor.close(); 118 | } 119 | ImageLoader.getInstance().displayImage("file://" + path, ibCameraPhotos, options); 120 | } 121 | } 122 | 123 | @Override 124 | protected void onStart() { 125 | super.onStart(); 126 | ib_camera_change.setOnClickListener(this); 127 | ib_camera_flash.setOnClickListener(this); 128 | ib_camera_grid.setOnClickListener(this); 129 | ibTakePicture.setOnClickListener(this); 130 | } 131 | 132 | @Override 133 | public void onWindowFocusChanged(boolean hasFocus) { 134 | super.onWindowFocusChanged(hasFocus); 135 | if (hasFocus) { 136 | cameraView.onResume(); 137 | cameraView.setTopDistance(rlTop.getHeight()); 138 | } 139 | } 140 | 141 | @Override 142 | protected void onPause() { 143 | super.onPause(); 144 | if (cameraView != null) 145 | cameraView.onPause(); 146 | } 147 | 148 | @Override 149 | public void onClick(View v) { 150 | switch (v.getId()) { 151 | case R.id.ib_camera_change: 152 | cameraView.changeCamera(); 153 | break; 154 | case R.id.ib_camera_flash: 155 | cameraView.changeFlash(); 156 | break; 157 | case R.id.ib_camera_grid: 158 | if (imgGrid.getVisibility() == View.VISIBLE) { 159 | imgGrid.setVisibility(View.GONE); 160 | ib_camera_grid.setBackgroundResource(R.drawable.camera_grid_normal); 161 | break; 162 | } 163 | ib_camera_grid.setBackgroundResource(R.drawable.camera_grid_press); 164 | imgGrid.setVisibility(View.VISIBLE); 165 | break; 166 | case R.id.ib_camera_take_picture: 167 | cameraView.takePicture(false); 168 | break; 169 | } 170 | } 171 | 172 | @Override 173 | public void onShake(int orientation) { 174 | // you can rotate views here 175 | } 176 | 177 | @Override 178 | public void onTakePicture(final boolean success, String filePath) { 179 | //sd/ResoCamera/(file) 180 | runOnUiThread(new Runnable() { 181 | @Override 182 | public void run() { 183 | if (success){ 184 | Toast.makeText(CameraActivity.this,"seccess!",Toast.LENGTH_SHORT).show(); 185 | } 186 | } 187 | }); 188 | } 189 | 190 | @Override 191 | public void onChangeFlashMode(int flashMode) { 192 | switch (flashMode) { 193 | case CameraView.FLASH_AUTO: 194 | ib_camera_flash.setBackgroundResource(R.drawable.camera_flash_auto); 195 | break; 196 | case CameraView.FLASH_OFF: 197 | ib_camera_flash.setBackgroundResource(R.drawable.camera_flash_off); 198 | break; 199 | case CameraView.FLASH_ON: 200 | ib_camera_flash.setBackgroundResource(R.drawable.camera_flash_on); 201 | break; 202 | } 203 | } 204 | 205 | @Override 206 | public void onChangeCameraPosition(int camera_position) { 207 | 208 | } 209 | } 210 | -------------------------------------------------------------------------------- /example/src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValuesFeng/ResoCamera/a7e54cebbdf74a3b601687d77e1b2e53940c3ae0/example/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValuesFeng/ResoCamera/a7e54cebbdf74a3b601687d77e1b2e53940c3ae0/example/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/src/main/res/drawable-xhdpi/camera_change_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValuesFeng/ResoCamera/a7e54cebbdf74a3b601687d77e1b2e53940c3ae0/example/src/main/res/drawable-xhdpi/camera_change_normal.png -------------------------------------------------------------------------------- /example/src/main/res/drawable-xhdpi/camera_change_press.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValuesFeng/ResoCamera/a7e54cebbdf74a3b601687d77e1b2e53940c3ae0/example/src/main/res/drawable-xhdpi/camera_change_press.png -------------------------------------------------------------------------------- /example/src/main/res/drawable-xhdpi/camera_close_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValuesFeng/ResoCamera/a7e54cebbdf74a3b601687d77e1b2e53940c3ae0/example/src/main/res/drawable-xhdpi/camera_close_normal.png -------------------------------------------------------------------------------- /example/src/main/res/drawable-xhdpi/camera_close_press.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValuesFeng/ResoCamera/a7e54cebbdf74a3b601687d77e1b2e53940c3ae0/example/src/main/res/drawable-xhdpi/camera_close_press.png -------------------------------------------------------------------------------- /example/src/main/res/drawable-xhdpi/camera_flash_auto.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValuesFeng/ResoCamera/a7e54cebbdf74a3b601687d77e1b2e53940c3ae0/example/src/main/res/drawable-xhdpi/camera_flash_auto.png -------------------------------------------------------------------------------- /example/src/main/res/drawable-xhdpi/camera_flash_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValuesFeng/ResoCamera/a7e54cebbdf74a3b601687d77e1b2e53940c3ae0/example/src/main/res/drawable-xhdpi/camera_flash_off.png -------------------------------------------------------------------------------- /example/src/main/res/drawable-xhdpi/camera_flash_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValuesFeng/ResoCamera/a7e54cebbdf74a3b601687d77e1b2e53940c3ae0/example/src/main/res/drawable-xhdpi/camera_flash_on.png -------------------------------------------------------------------------------- /example/src/main/res/drawable-xhdpi/camera_grid_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValuesFeng/ResoCamera/a7e54cebbdf74a3b601687d77e1b2e53940c3ae0/example/src/main/res/drawable-xhdpi/camera_grid_normal.png -------------------------------------------------------------------------------- /example/src/main/res/drawable-xhdpi/camera_grid_press.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValuesFeng/ResoCamera/a7e54cebbdf74a3b601687d77e1b2e53940c3ae0/example/src/main/res/drawable-xhdpi/camera_grid_press.png -------------------------------------------------------------------------------- /example/src/main/res/drawable-xhdpi/camera_take_picture_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValuesFeng/ResoCamera/a7e54cebbdf74a3b601687d77e1b2e53940c3ae0/example/src/main/res/drawable-xhdpi/camera_take_picture_normal.png -------------------------------------------------------------------------------- /example/src/main/res/drawable-xhdpi/camera_take_picture_press.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValuesFeng/ResoCamera/a7e54cebbdf74a3b601687d77e1b2e53940c3ae0/example/src/main/res/drawable-xhdpi/camera_take_picture_press.png -------------------------------------------------------------------------------- /example/src/main/res/drawable-xhdpi/grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValuesFeng/ResoCamera/a7e54cebbdf74a3b601687d77e1b2e53940c3ae0/example/src/main/res/drawable-xhdpi/grid.png -------------------------------------------------------------------------------- /example/src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValuesFeng/ResoCamera/a7e54cebbdf74a3b601687d77e1b2e53940c3ae0/example/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/src/main/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ValuesFeng/ResoCamera/a7e54cebbdf74a3b601687d77e1b2e53940c3ae0/example/src/main/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/src/main/res/drawable/camera_change.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/src/main/res/drawable/camera_close.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/src/main/res/drawable/camera_take_picture.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/src/main/res/layout-hdpi/activity_camera.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 8 | 9 | 14 | 15 | 23 | 24 | 32 | 33 | 41 | 42 | 43 | 48 | 49 | 57 | 58 | 69 | 70 | 76 | 77 | 83 | 84 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /example/src/main/res/layout-xhdpi/activity_camera.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 8 | 9 | 14 | 15 | 23 | 24 | 32 | 33 | 41 | 42 | 43 | 48 | 49 | 57 | 58 | 69 | 70 | 76 | 77 | 83 | 84 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /example/src/main/res/layout/activity_camera.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 8 | 9 | 14 | 15 | 23 | 24 | 32 | 33 | 41 | 42 | 43 | 48 | 49 | 57 | 58 | 69 | 70 | 76 | 77 | 83 | 84 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /example/src/main/res/values-v11/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | 11 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /example/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /example/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #66000000 4 | 5 | 6 | -------------------------------------------------------------------------------- /example/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ResoCamera 5 | Dummy Button 6 | DUMMY\nCONTENT 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 15 | 16 | 23 | 24 |