百度人脸识别横屏竖屏的实现

作者: i小灰 | 来源:发表于2021-08-02 17:00 被阅读0次

    前言

    新的项目用了百度的人脸识别,然后开开心心的集成了百度的人脸识别sdk,非常perfect,so easy.然而项目的应用场景需要横屏使用,但是百度这个坑爹的货,只给了一个竖屏demo,去百度提工单,然而说你们自己适配,我去你大爷的。骂归骂,可咱也得解决不是,好在我们的平板是固定的,只需要适配一个就行,下面我来放大招了。先看效果图,

    image.png image.png

    正文

    其实呢,想适配横屏也非常简单,只需要修改一下几个方向参数即可,这几个方向含义,我也不细说了,主要就是1,相机的预览方向,Camera.DisplayOrientation,2 图像的预览方向,Camera.getParameters.setRotation, 3,相机的传感器方向,这个咱不能修改,因为这是固件安装固定的,前面两个,我们可以自由修改,只要能跟相机传感器方向匹配,就能获得完美的效果,我修改的地方,我做了注释,看代码吧

    //1,修改这个类的这个方法
    CameraImageSource.java
    
     //TODO--输入源
        public CameraImageSource(Context context) {
            this.context = context;
    //        Log.e("camera","orientation:="+context.getResources().getConfiguration().orientation);
            cameraControl = new Camera1Control(getContext());
            cameraControl.setCameraFacing(cameraFaceType);
            //TODO---横屏90,竖屏0
            cameraControl.setDisplayOrientation((context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) ? CameraView.ORIENTATION_HORIZONTAL : CameraView.ORIENTATION_PORTRAIT);
            cameraControl.setOnFrameListener(new ICameraControl.OnFrameListener<byte[]>() {
                @Override
                public void onPreviewFrame(byte[] data, int rotation, int width, int height) {
    
                    Log.e("camera", "setOnFrameListener onPreviewFrame: rotation:" + rotation + ",width:" + width + ",height:" + height);
    
                    int[] argb = argbPool.acquire(width, height);
    
                    if (argb == null || argb.length != width * height) {
                        argb = new int[width * height];
                    }
    
                    rotation = rotation < 0 ? 360 + rotation : rotation;
                    FaceDetector.yuvToARGB(data, width, height, argb, rotation, 0);
    
                    // liujinhui modify
    
                    // TODO--旋转了90或270度。高宽需要替换
                    if (rotation % 180 == 90) {
                        int temp = width;
                        width = height;
                        height = temp;
                    }
    
                    ImageFrame frame = new ImageFrame();
                    frame.setArgb(argb);
                    frame.setWidth(width);
                    frame.setHeight(height);
                    frame.setPool(argbPool);
                    ArrayList<OnFrameAvailableListener> listeners = getListeners();
                    for (OnFrameAvailableListener listener : listeners) {
                        listener.onFrameAvailable(frame);
                    }
                }
            });
        }
    
    // TODO---2,修改这个类
    /**
     * 5.0以下相机API的封装。
     */
    @SuppressWarnings("deprecation")
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    public class Camera1Control implements ICameraControl {
    
        private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
        private static final int MAX_PREVIEW_SIZE = 2048;
    
        static {
            ORIENTATIONS.append(Surface.ROTATION_0, 90);
            ORIENTATIONS.append(Surface.ROTATION_90, 0);
            ORIENTATIONS.append(Surface.ROTATION_180, 270);
            ORIENTATIONS.append(Surface.ROTATION_270, 180);
        }
    
    
        private int displayOrientation = CameraView.ORIENTATION_HORIZONTAL;//TODO--这里修改为90,原来是0
        private int cameraId = 0;
        private int flashMode;
        private AtomicBoolean takingPicture = new AtomicBoolean(false);
    
        private Context context;
        private Camera camera;
    
        private Camera.Parameters parameters;
        private PermissionCallback permissionCallback;
        private Rect previewFrame = new Rect();
    
        private int preferredWidth = 1280;
        private int preferredHeight = 720;
    
        @ICameraControl.CameraFacing
        private int cameraFacing = CAMERA_FACING_FRONT;
    
        private boolean usbCamera = false;
    
        @Override
        public void setDisplayOrientation(int displayOrientation) {
            this.displayOrientation = displayOrientation;
            Log.e("camera","setDisplayOrientation:"+displayOrientation);
        }
    
        /**
         * {@inheritDoc}
         */
        @Override
        public void refreshPermission() {
            startPreview(true);
        }
    
        /**
         * {@inheritDoc}
         */
        @Override
        public void setFlashMode(@FlashMode int flashMode) {
            if (this.flashMode == flashMode) {
                return;
            }
            this.flashMode = flashMode;
            updateFlashMode(flashMode);
        }
    
        @Override
        public int getFlashMode() {
            return flashMode;
        }
    
        @Override
        public void setCameraFacing(@CameraFacing int cameraFacing) {
            this.cameraFacing = cameraFacing;
        }
    
        @Override
        public void setUsbCamera(boolean usbCamera) {
            this.usbCamera = usbCamera;
        }
    
        @Override
        public void start() {
            startCamera();
        }
    
        public void isUsbCamera() {
    
        }
    
        private SurfaceTexture surfaceTexture;
    
        private void startCamera() {
            if (ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA)
                    != PackageManager.PERMISSION_GRANTED) {
                if (permissionCallback != null) {
                    permissionCallback.onRequestPermission();
                }
                return;
            }
            if (camera == null) {
                Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
                for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
                    Camera.getCameraInfo(i, cameraInfo);
                    if (cameraInfo.facing == cameraFacing) {
                        cameraId = i;
                    }
                }
                camera = Camera.open(cameraId);
            }
            if (parameters == null) {
                parameters = camera.getParameters();
                parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
            }
    
            surfaceTexture = new SurfaceTexture(11);
            parameters.setRotation((displayOrientation == CameraView.ORIENTATION_HORIZONTAL) ? 0 : 90); // TODO--图片的预览方向,原来是90,我设置为0
            int rotation = ORIENTATIONS.get(displayOrientation);
            Log.e("camera", "camera rotation:" + rotation+",displayOrientation:"+displayOrientation);
            camera.setDisplayOrientation(rotation);//TODO---相机的预览反向
            //TODO---设备方向,
    
            try {
                camera.setPreviewCallback(new Camera.PreviewCallback() {
                    @Override
                    public void onPreviewFrame(byte[] data, Camera camera) {//TODO--相机预览回调
    //                    Log.e("onPreviewFrame", "onPreviewFrame");
                        Camera.Size size = camera.getParameters().getPreviewSize();
                        Log.e("camera", "camera.getParameters().getPreviewSize() :height:" + size.height + ",width:" + size.width);
                        int rotation = getSurfaceOrientation();//TODO--这里原来是{# getSurfaceOrientation()},改成0
    
                        Log.e("camera", "getSurfaceOrientation :" + rotation + ",displayorientation:" + displayOrientation);
    
                        if (cameraFacing == ICameraControl.CAMERA_FACING_FRONT) {
                            //TODO--镜像--180旋转 android自带的摄像头和接usb摄像头,图片有180旋转,用usb摄像头注释下面的代码,
                            if (!usbCamera) {
                                if (rotation == 90 || rotation == 270) {
                                    rotation = (rotation + 180) % 360;
                                }
                            }
                        }
    
                        Log.e("camera", "getSurfaceOrientation :" + rotation + ",rotation % 180 == 90:" + (rotation % 180 == 90));
    
                        if (rotation % 180 == 90) {
                            previewView.setPreviewSize(size.height, size.width);//,TODO--这里回调的是旋转的图片
                        } else {
                            previewView.setPreviewSize(size.width, size.height);
                        }
    
                        onFrameListener.onPreviewFrame(data, rotation, size.width, size.height);
                    }
                });
                camera.setPreviewTexture(surfaceTexture);
                if (textureView != null) {
                    surfaceTexture.detachFromGLContext();
                    textureView.setSurfaceTexture(surfaceTexture);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            opPreviewSize(preferredWidth, preferredHeight);
        }
    
        private TextureView textureView;
    
        @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
        public void setTextureView(TextureView textureView) {
            this.textureView = textureView;
            if (surfaceTexture != null) {
                surfaceTexture.detachFromGLContext();
                textureView.setSurfaceTexture(surfaceTexture);
            }
        }
    
        @Override
        public void stop() {
            if (camera != null) {
                camera.stopPreview();
                camera.setPreviewCallback(null);
                camera.release();
                camera = null;
            }
        }
    
        @Override
        public void pause() {
            if (camera != null) {
                camera.stopPreview();
            }
            setFlashMode(FLASH_MODE_OFF);
        }
    
        @Override
        public void resume() {
            takingPicture.set(false);
            if (camera == null) {
                startCamera();
            }
        }
    
        private OnFrameListener onFrameListener;
    
        @Override
        public void setOnFrameListener(OnFrameListener listener) {
            this.onFrameListener = listener;
        }
    
        @Override
        public void setPreferredPreviewSize(int width, int height) {
            this.preferredWidth = Math.max(width, height);
            this.preferredHeight = Math.min(width, height);
        }
    
        @Override
        public View getDisplayView() {
            return null;
        }
    
    
        private PreviewView previewView;
    
        @Override
        public void setPreviewView(PreviewView previewView) {
            this.previewView = previewView;
            setTextureView(previewView.getTextureView());
        }
    
        @Override
        public PreviewView getPreviewView() {
            return previewView;
        }
    
        @Override
        public void takePicture(final OnTakePictureCallback onTakePictureCallback) {
            if (takingPicture.get()) {
                return;
            }
    
            switch (displayOrientation) {
                case CameraView.ORIENTATION_PORTRAIT:
                    parameters.setRotation(90);
                    break;
                case CameraView.ORIENTATION_HORIZONTAL:
                    parameters.setRotation(0);
                    break;
                case CameraView.ORIENTATION_INVERT:
                    parameters.setRotation(180);
                    break;
                default:
                    parameters.setRotation(90);
                    break;
            }
            Camera.Size picSize =
                    getOptimalSize(preferredWidth, preferredHeight, camera.getParameters().getSupportedPictureSizes());
            parameters.setPictureSize(picSize.width, picSize.height);
            camera.setParameters(parameters);
            takingPicture.set(true);
            camera.autoFocus(new Camera.AutoFocusCallback() {
                @Override
                public void onAutoFocus(boolean success, Camera camera) {
                    camera.cancelAutoFocus();
                    try {
                        camera.takePicture(null, null, new Camera.PictureCallback() {
                            @Override
                            public void onPictureTaken(byte[] data, Camera camera) {
                                camera.startPreview();
                                takingPicture.set(false);
                                if (onTakePictureCallback != null) {
                                    onTakePictureCallback.onPictureTaken(data);
                                }
                            }
                        });
                    } catch (RuntimeException e) {
                        e.printStackTrace();
                        camera.startPreview();
                        takingPicture.set(false);
                    }
                }
            });
        }
    
        @Override
        public void setPermissionCallback(PermissionCallback callback) {
            this.permissionCallback = callback;
        }
    
        public Camera1Control(Context context) {
            this.context = context;
            Log.e("camera", "Camera1Control------------");
        }
    
        // 开启预览
        private void startPreview(boolean checkPermission) {
            if (ActivityCompat.checkSelfPermission(context, Manifest.permission.CAMERA)
                    != PackageManager.PERMISSION_GRANTED) {
                if (checkPermission && permissionCallback != null) {
                    permissionCallback.onRequestPermission();
                }
                return;
            }
            camera.startPreview();
        }
    
        private void opPreviewSize(int width, @SuppressWarnings("unused") int height) {
            Camera.Size optSize;
            if (parameters != null && camera != null && width > 0) {
                optSize = getOptimalSize(width, height, camera.getParameters().getSupportedPreviewSizes());
    
                Log.e("camera", "getOptimalSize:width:" + optSize.width + ",height:" + optSize.height);//TODO--设置最佳预览尺寸
    
                parameters.setPreviewSize(optSize.width, optSize.height);
    
    //            camera.setDisplayOrientation(getSurfaceOrientation());
                //            camera.stopPreview();
                try {
                    camera.setParameters(parameters);
                } catch (RuntimeException e) {
                    e.printStackTrace();
    
                }
                camera.startPreview();
            }
        }
    
        private Camera.Size getOptimalSize(int width, int height, List<Camera.Size> sizes) {
    
            Camera.Size pictureSize = sizes.get(0);
    
            List<Camera.Size> candidates = new ArrayList<>();
    
            for (Camera.Size size : sizes) {
                if (size.width >= width && size.height >= height && size.width * height == size.height * width) {
                    // 比例相同
                    candidates.add(size);
                } else if (size.height >= width && size.width >= height && size.width * width == size.height * height) {
                    // 反比例
                    candidates.add(size);
                }
            }
            if (!candidates.isEmpty()) {
                return Collections.min(candidates, sizeComparator);
            }
    
            for (Camera.Size size : sizes) {
                if (size.width > width && size.height > height) {
                    return size;
                }
            }
    
            return pictureSize;
        }
    
        private Comparator<Camera.Size> sizeComparator = new Comparator<Camera.Size>() {
            @Override
            public int compare(Camera.Size lhs, Camera.Size rhs) {
                return Long.signum((long) lhs.width * lhs.height - (long) rhs.width * rhs.height);
            }
        };
    
        private void updateFlashMode(int flashMode) {
            switch (flashMode) {
                case FLASH_MODE_TORCH:
                    parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
                    break;
                case FLASH_MODE_OFF:
                    parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
                    break;
                case ICameraControl.FLASH_MODE_AUTO:
                    parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
                    break;
                default:
                    parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
                    break;
            }
            camera.setParameters(parameters);
        }
    
        protected int getSurfaceOrientation() {
    
            switch (displayOrientation) {
                case CameraView.ORIENTATION_HORIZONTAL:
                    return 0;
                case CameraView.ORIENTATION_INVERT:
                    return 180;
                default:
                    return 90;
            }
        }
    
        @Override
        public Rect getPreviewFrame() {
            return previewFrame;
        }
    }
    

    结尾

    好了,很简单就能改好了,为了方便大家测试,我把我申请的测试 FaceLogin-Sample-Android-demo上传上来,给大家用,不用谢我。让人无语的百度,连个人工客服都没有,差评

    相关文章

      网友评论

        本文标题:百度人脸识别横屏竖屏的实现

        本文链接:https://www.haomeiwen.com/subject/ecdjvltx.html