Guest User

Untitled

a guest
Dec 23rd, 2016
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 11.87 KB | None | 0 0
  1. package com.example.arturs.cameraappzoom;
  2.  
  3. import android.Manifest;
  4. import android.content.Context;
  5. import android.content.pm.PackageManager;
  6. import android.content.res.TypedArray;
  7. import android.hardware.Camera;
  8. import android.support.annotation.NonNull;
  9. import android.support.v4.content.ContextCompat;
  10. import android.util.AttributeSet;
  11. import android.util.Log;
  12. import android.view.MotionEvent;
  13. import android.view.ScaleGestureDetector;
  14. import android.view.Surface;
  15. import android.view.SurfaceHolder;
  16. import android.view.SurfaceView;
  17. import android.view.WindowManager;
  18.  
  19. import com.example.arturs.cameraappzoom.constant.ZoomSupportIssues;
  20.  
  21. import java.util.ArrayList;
  22. import java.util.List;
  23.  
  24.  
  25. public class CameraView extends SurfaceView implements SurfaceHolder.Callback {
  26.  
  27.     private static final String TAG = CameraView.class.getSimpleName();
  28.  
  29.  
  30.     /*@IntDef({CameraType.BACK_CAMERA, CameraType.FRONT_CAMERA})
  31.     //@Retention(RetentionPolicy.SOURCE)*/
  32.     public @interface Cam {
  33.     }
  34.  
  35.     private static final int INCREMENT_ZOOM_STEP = 2;
  36.     private static final int DECREMENT_ZOOM_STEP = -2;
  37.     private static final int ZOOM_GESTURE_MULTIPLIER = 50;
  38.  
  39.     private Camera.Size mPreviewSize;
  40.  
  41.     private int mCameraId;
  42.  
  43.     private com.example.arturs.cameraappzoom.listener.ZoomListener mTestResultListener;
  44.  
  45.     private Camera mCamera;
  46.     private SurfaceHolder previewHolder;
  47.  
  48.     private ScaleGestureDetector mScaleGestureDetector;
  49.     private final ScaleGestureDetector.OnScaleGestureListener mScaleGestureListener
  50.             = new ScaleGestureDetector.SimpleOnScaleGestureListener() {
  51.         @Override
  52.         public boolean onScale(ScaleGestureDetector scaleGestureDetector) {
  53.             changeZoom(Math.log(scaleGestureDetector.getScaleFactor()) * ZOOM_GESTURE_MULTIPLIER);
  54.             return true;
  55.         }
  56.     };
  57.  
  58.     public CameraView(Context context) {
  59.         super(context);
  60.         initView(null);
  61.         initCamera();
  62.     }
  63.  
  64.     public CameraView(Context context, AttributeSet attrs) {
  65.         super(context, attrs);
  66.         initView(attrs);
  67.         initCamera();
  68.     }
  69.  
  70.     public CameraView(Context context, AttributeSet attrs, int defStyleAttr) {
  71.         super(context, attrs, defStyleAttr);
  72.         initView(attrs);
  73.     }
  74.  
  75.  
  76.     private void initView(AttributeSet attrs) {
  77.         TypedArray attributes = getContext().getTheme().obtainStyledAttributes(attrs, R.styleable.CameraType, 0, 0);
  78.         try {
  79.             setCameraId(attributes.getInt(R.styleable.CameraType_camera_type, Camera.CameraInfo.CAMERA_FACING_FRONT));
  80.             initCamera();
  81.         } finally {
  82.             attributes.recycle();
  83.         }
  84.     }
  85.  
  86.     public void zoomIn() {
  87.         changeZoom(INCREMENT_ZOOM_STEP);
  88.     }
  89.  
  90.     public void zoomOut() {
  91.         changeZoom(DECREMENT_ZOOM_STEP);
  92.     }
  93.  
  94.     public void setTestResultListener(/*@Nullable*/ final com.example.arturs.cameraappzoom.listener.ZoomListener testResultListener) {
  95.         mTestResultListener = testResultListener;
  96.         initCamera();
  97.     }
  98.  
  99.     public void setCameraId(int cameraId) {
  100.         mCameraId = cameraId;
  101.     }
  102.  
  103.     public void setCameraType(@Cam final int cameraType) {
  104.         setCameraId(cameraType);
  105.         initCamera();
  106.     }
  107.  
  108.     public void initCamera() {
  109.         if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
  110.             logMessage("CAMERA permission isn't granted");
  111.             notifyTestFailure(ZoomSupportIssues.NO_PERMISSION);
  112.         } else if (!checkCamHardware(getContext())) {
  113.             logMessage("This device doesn't have mCamera");
  114.             notifyTestFailure(ZoomSupportIssues.NO_CAMERA);
  115.         } else {
  116.             mScaleGestureDetector = new ScaleGestureDetector(getContext(), mScaleGestureListener);
  117.             previewHolder = this.getHolder();
  118.             previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
  119.             previewHolder.addCallback(this);
  120.             openCamera(mCameraId);
  121.             requestLayout();
  122.             mCamera.startPreview();
  123.         }
  124.     }
  125.  
  126.     @Override
  127.     public boolean onTouchEvent(MotionEvent event) {
  128.         if (mScaleGestureDetector != null) {
  129.             mScaleGestureDetector.onTouchEvent(event);
  130.         }
  131.         return true;
  132.     }
  133.  
  134.     private boolean checkCamHardware(/*@NonNull*/ final Context context) {
  135.         return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);
  136.     }
  137.  
  138.     private void changeZoom(double extraZoom) {
  139.         if (mCamera != null) {
  140.             Camera.Parameters params = mCamera.getParameters();
  141.             if (params.isZoomSupported()) {
  142.                 int maxZoom = params.getMaxZoom();
  143.                 int currentZoom = params.getZoom();
  144.                 if (currentZoom + (int) extraZoom < maxZoom) {
  145.                     params.setZoom(currentZoom + (int) extraZoom);
  146.                 } else if (currentZoom + (int) extraZoom < 0) {
  147.                     params.setZoom(0);
  148.                 } else {
  149.                     params.setZoom(maxZoom);
  150.                 }
  151.                 try {
  152.                     mCamera.setParameters(params);
  153.                 } catch (RuntimeException e) {
  154.                     Log.d(TAG, "unable set mCamera params: " + e.getLocalizedMessage());
  155.                 }
  156.                 if (currentZoom != mCamera.getParameters().getZoom()) {
  157.                     mTestResultListener.onZoomSupported();
  158.  
  159.                 }
  160.             } else {
  161.                 logMessage("Zoom is not supported");
  162.                 notifyTestFailure(ZoomSupportIssues.NOT_SUPPORTED);
  163.             }
  164.         }
  165.     }
  166.  
  167.  
  168.     private void openCamera(int cameraId) {
  169.         releaseCameraAndPreview();
  170.         try {
  171.             mCamera = Camera.open(getCameraType(cameraId));
  172.             mCamera.setPreviewDisplay(previewHolder);
  173.         } catch (Exception e) {
  174.             e.printStackTrace();
  175.         }
  176.     }
  177.  
  178.     private void releaseCameraAndPreview() {
  179.         if (mCamera != null) {
  180.             mCamera.release();
  181.             mCamera = null;
  182.         }
  183.     }
  184.  
  185.     @Override
  186.     public void surfaceCreated(SurfaceHolder surfaceHolder) {
  187.         openCamera(mCameraId);
  188.     }
  189.  
  190.     @Override
  191.     public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
  192.         if (mCamera != null) {
  193.             mCamera.stopPreview();
  194.             setCameraDisplayOrientation(getCameraType(mCameraId));
  195.             setCameraPreviewSize(mPreviewSize);
  196.  
  197.  
  198.             try {
  199.                 mCamera.startPreview();
  200.             } catch (Exception e) {
  201.                 e.printStackTrace();
  202.             }
  203.         }
  204.     }
  205.  
  206.  
  207.  
  208.     @Override
  209.     public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
  210.         if (mCamera != null) {
  211.             mCamera.stopPreview();
  212.             mCamera.release();
  213.         }
  214.     }
  215.  
  216.     private int getDisplayOrientation() {
  217.         WindowManager windowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
  218.         return windowManager.getDefaultDisplay().getRotation();
  219.     }
  220.  
  221.  
  222.     private void setCameraDisplayOrientation(final int cameraId) {
  223.         int degrees = 0;
  224.         switch (getDisplayOrientation()) {
  225.             case Surface.ROTATION_0:
  226.                 degrees = 0;
  227.                 break;
  228.             case Surface.ROTATION_90:
  229.                 degrees = 90;
  230.                 break;
  231.             case Surface.ROTATION_180:
  232.                 degrees = 180;
  233.                 break;
  234.             case Surface.ROTATION_270:
  235.                 degrees = 270;
  236.                 break;
  237.         }
  238.  
  239.         int result = 0;
  240.  
  241.         Camera.CameraInfo info = new Camera.CameraInfo();
  242.         Camera.getCameraInfo(cameraId, info);
  243.  
  244.         //back mCamera
  245.         if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
  246.             result = ((360 - degrees) + info.orientation);
  247.         } else if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {  //face mCamera
  248.             result = ((360 - degrees) - info.orientation);
  249.             result += 360;
  250.         }
  251.         result = result % 360;
  252.         mCamera.setDisplayOrientation(result);
  253.     }
  254.  
  255.     private void setCameraPreviewSize(final Camera.Size size) {
  256.         if(mCamera != null && size != null) {
  257.             Camera.Parameters parameters = mCamera.getParameters();
  258.             parameters.setPreviewSize(size.width, size.height);
  259.             parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); //dodany autofokus
  260.             Log.i(TAG, "camera preview size: width: " + size.width + " height: " + size.height);
  261.             mCamera.setParameters(parameters);
  262.         }
  263.     }
  264.  
  265.  
  266.  
  267.     private void notifyTestFailure(@NonNull final ZoomSupportIssues reason) {
  268.         if (mTestResultListener != null) {
  269.             mTestResultListener.onZoomNotSupported(reason);
  270.         }
  271.     }
  272.  
  273.     private int getCameraType(final int cameraId) {
  274.         if (cameraId != Camera.CameraInfo.CAMERA_FACING_BACK && cameraId != Camera.CameraInfo.CAMERA_FACING_FRONT) {
  275.             //return back camera as default
  276.             //return Camera.CameraInfo.CAMERA_FACING_BACK; //tylna domyślna
  277.             return Camera.CameraInfo.CAMERA_FACING_FRONT;
  278.         } else {
  279.             return cameraId;
  280.         }
  281.     }
  282.  
  283.     @Override
  284.     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  285.         final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
  286.         final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
  287.  
  288.         if (!getCameraPreviewSizes().isEmpty()) {
  289.             mPreviewSize = getOptimalPreviewSize(getCameraPreviewSizes(), width, height);
  290.  
  291.             float ratio = mPreviewSize.height >= mPreviewSize.width
  292.                     ? (float) mPreviewSize.height / (float) mPreviewSize.width
  293.                     : (float) mPreviewSize.width / (float) mPreviewSize.height;
  294.  
  295.  
  296.             float camHeight = (int) (width * ratio);
  297.             float newHeightRatio;
  298.  
  299.             if (camHeight < height) {
  300.                 newHeightRatio = (float) height / (float) mPreviewSize.height;
  301.                 setMeasuredDimension((int) (width * newHeightRatio), (int) (newHeightRatio * camHeight));
  302.             } else {
  303.                 setMeasuredDimension(width, (int) camHeight);
  304.             }
  305.         } else {
  306.             setMeasuredDimension(width, height);
  307.         }
  308.     }
  309.  
  310.     private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
  311.         final double TOLERANCE_ASP = 0.1;
  312.         double targetRatio = (double) h / w;
  313.  
  314.         if (sizes == null) {
  315.             return null;
  316.         }
  317.  
  318.         Camera.Size optimalSize = null;
  319.         double minDiff = Double.MAX_VALUE;
  320.  
  321.         int targetHeight = h;
  322.  
  323.         for (Camera.Size size : sizes) {
  324.             double ratio = (double) size.height / size.width;
  325.             if (Math.abs(ratio - targetRatio) > TOLERANCE_ASP) {
  326.                 continue;
  327.             }
  328.             if (Math.abs(size.height - targetHeight) < minDiff) {
  329.                 optimalSize = size;
  330.                 minDiff = Math.abs(size.height - targetHeight);
  331.             }
  332.         }
  333.  
  334.         if (optimalSize == null) {
  335.             minDiff = Double.MAX_VALUE;
  336.             for (Camera.Size size : sizes) {
  337.                 if (Math.abs(size.height - targetHeight) < minDiff) {
  338.                     optimalSize = size;
  339.                     minDiff = Math.abs(size.height - targetHeight);
  340.                 }
  341.             }
  342.         }
  343.         return optimalSize;
  344.     }
  345.  
  346.  
  347.  
  348.     private List<Camera.Size> getCameraPreviewSizes() {
  349.         if (mCamera != null) {
  350.             return mCamera.getParameters().getSupportedPreviewSizes();
  351.         } else {
  352.             return new ArrayList<>();
  353.         }
  354.     }
  355.  
  356.  
  357.  
  358.     private void logMessage(final String message) {
  359.         Log.i(TAG, message);
  360.     }
  361.  
  362.  
  363.  
  364.  
  365. }
Add Comment
Please, Sign In to add comment