Today, I found that the preview interface will be deformed when I customize the camera on the handheld terminal
First look for the problem:
When I adjust the direction of the preview interface, I find that 90 ° rotation can change this problem, but the preview interface as a whole will also cross over. It will be difficult for page customization development, and it is not the final solution, just around it
solve the problem:
Then I found a lot of relevant information from the Internet, and the final result is that the preview angle and camera width and height of the device are not compatible with the device, resulting in
So I started from this aspect, and finally I succeeded, not much code
resolvent:
First of all, I want to initialize SurfaceView
//Initialize SurfaceView public void initSurfaceView() { //There are some attributes that can change the direction of the camera, but I don't want to fix the problem here // setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); mSurfaceHolder = mSurfaceView.getHolder(); mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//Surface view does not maintain its own buffer, waiting for the screen rendering engine to push the content to the user mSurfaceHolder.addCallback(this); }
Listening events are also relatively simple without complicated logic
//After creation @Override public void surfaceCreated(SurfaceHolder holder) { //Open Camera mPresenter.openCamera(mContext); } //After the change @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { mSurfaceHolder = holder; } //After destruction @Override public void surfaceDestroyed(SurfaceHolder holder) { //Free memory mPresenter.releaseCamera(); }
Notice that this is the point
//Open Camera @Override public void openCamera(Context context, SurfaceHolder mSurfaceHolder, SurfaceView mSurfaceView) { mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK); try { mCamera.setPreviewDisplay(mSurfaceHolder); } catch (IOException e) { e.printStackTrace(); } // In order to adapt to the problem of setparams failure of some mobile phones, if it fails, it will not be set try { Camera.Parameters parameters = mCamera.getParameters(); Point bestPreviewSizeValue1 = findBestPreviewSizeValue(parameters.getSupportedPreviewSizes()); parameters.setPreviewSize(bestPreviewSizeValue1.x, bestPreviewSizeValue1.y); mCamera.setParameters(parameters); } catch (Exception e) { Log.d("wangc", "set parameters fail"); } //Make horizontal and vertical screen judgment and then correct the image //If it's a vertical screen if (context.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) { mCamera.setDisplayOrientation(90); } else {//If it's a horizontal screen mCamera.setDisplayOrientation(0); } //Open Preview mCamera.startPreview(); //If you want to achieve continuous autofocus, you must add mCamera.cancelAutoFocus(); }
Get the corresponding size
/** * The size closest to the aspect ratio can be obtained by comparison (if there is the same size, it is preferred) * @return Get the size closest to the original width to height ratio */ private static Point findBestPreviewSizeValue(List<Camera.Size> sizeList){ int bestX = 0; int bestY = 0; int size = 0; for (Camera.Size nowSize : sizeList){ int newX = nowSize.width; int newY = nowSize.height; int newSize = Math.abs(newX * newX) + Math.abs(newY * newY); float ratio = (float) (newY * 1.0 / newX); if(newSize >= size && ratio != 0.75){//Make sure the picture is 16:9 bestX = newX; bestY = newY; size = newSize; }else if(newSize < size){ continue; } } if(bestX > 0 && bestY > 0){ return new Point(bestX,bestY); } return null; }
Next, let's have a pleasant development
//Photograph @Override public void takePic() { mCamera.takePicture(null, null, new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { } }); }