Android custom Camera

Keywords: github SurfaceView Mobile


Address: https://github.com/danfengfirst/Camera
Demo Description:
1. Demo contains a custom rectangular View. Generally, a picture can be placed in this rectangle. Because of the special requirement of aspect ratio, we hope to keep the same aspect ratio in different screens, so we have customized it here. The custom part can be replaced by a picture. In addition, this demo doesn't just capture rectangular areas.
2. In Demo, Camera is placed directly in the custom SurfaceView.

3. Touch focus

  //Set touch event monitoring
            setOnTouchListener(new OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    if (event.getAction() == MotionEvent.ACTION_DOWN) {
                        Point point = new Point();
                        point.x = (int) event.getX();
                        point.y = (int) event.getY();
                        onFocus(point, mCameraAutoFocusCallBack);
                    }
                    return true;
                }
            });

//Touch focus
    protected boolean onFocus(Point point, Camera.AutoFocusCallback callback) {
        if (mCamera == null) {
            return false;
        }
        Camera.Parameters parameters = null;
        try {
            parameters = mCamera.getParameters();
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        //Setting custom focus is not supported. Use auto focus to return to

        if(Build.VERSION.SDK_INT >= 14) {

            if (parameters.getMaxNumFocusAreas() <= 0) {
                return focus(callback);
            }

            Log.i(TAG, "onCameraFocus:" + point.x + "," + point.y);

            //Fixed point focus
            List<Camera.Area> areas = new ArrayList<Camera.Area>();
            int left = point.x - 300;
            int top = point.y - 300;
            int right = point.x + 300;
            int bottom = point.y + 300;
            left = left < -1000 ? -1000 : left;
            top = top < -1000 ? -1000 : top;
            right = right > 1000 ? 1000 : right;
            bottom = bottom > 1000 ? 1000 : bottom;
            areas.add(new Camera.Area(new Rect(left, top, right, bottom), 100));
            parameters.setFocusAreas(areas);
            try {
                //When setting the focus area, the Xiaomi mobile phone often goes wrong. Looking at the log, it is found that there is an error when the string of the frame layer is converted to int,
                //The visual inspection shows that Xiaomi has modified the frame layer code, so it will try to drop it here, which has no effect on the actual focusing effect
                mCamera.setParameters(parameters);
            } catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
                return false;
            }
        }


        return focus(callback);
    }

    private boolean focus(Camera.AutoFocusCallback callback) {
        try {
            mCamera.autoFocus(callback);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

4. Best resolution

 /**
     * Get the best resolution
     * @param sizes
     * @param w
     * @param h
     * @return
     */
    private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
        final double ASPECT_TOLERANCE = 0.1;
        double targetRatio = (double) h / w;
        if (sizes == null)
            return null;
        Camera.Size optimalSize = null;
        double minDiff = Double.MAX_VALUE;
        int targetHeight = h;
        for (Camera.Size size : sizes) {
            double ratio = (double) size.height / size.width;
            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
                continue;
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }
        if (optimalSize == null) {
            minDiff = Double.MAX_VALUE;
            for (Camera.Size size : sizes) {
                if (Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }
        }

        return optimalSize;
    }

5. Problems such as too small image size can be solved by rebuilding bitmap

There are many articles about customizing camera on the Internet, so there is not much introduction

ps: just remember the display mode of github image, I'm afraid I'll forget it next time

 ![image](https://github.com/danfengfirst/Camera/raw/master/Screenshot_2018-02-03-11-53-57.png)

Posted by Ajdija on Mon, 20 Apr 2020 10:33:22 -0700