Android解决SurfaceView预览Camera拉伸问题
16lz
2021-01-26
Android解决SurfaceView预览Camera拉伸问题
搜索了一遍国内的解决方案,基本上都是匹配Camera的支持分辨率,然后直接设置,这个只能解决一部分手机,很多机型仍然显示的时候会出现拉伸,因为Camera支持的分辨率没有刚好适合的当然屏幕尺寸,特别是没有隐藏状态栏,显示的View的尺寸和支持的分辨率不匹配,就出现了图像变形。
以下是我结合分辨率适配以及布局适配,来解决这个问题
在主界面直接在代码里new 一个CustomCameraSurface 对象并Add 进根视图,然后调用OnStart()
import android.app.Activity;import android.content.Context;import android.graphics.PixelFormat;import android.hardware.Camera;import android.util.AttributeSet;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.view.ViewGroup.LayoutParams;import android.widget.LinearLayout;import android.widget.RelativeLayout;/** * Created by Jackie on 2016/7/26. */public class CustomCameraSurface extends SurfaceView implements SurfaceHolder.Callback { static private CustomCameraSurface instance; private LinearLayout frame = null; private RelativeLayout innerFrame = null; private Camera camera; private SurfaceHolder previewHolder; private boolean inPreview = false; private boolean cameraConfigured = false; private Camera.Size size; static public CustomCameraSurface getInstance(Activity activity) { if (CustomCameraSurface.instance == null) { CustomCameraSurface.instance = new CustomCameraSurface(activity); } return CustomCameraSurface.instance; } public void onStart() { camera = Camera.open(1); if (size != null) { initPreview(size.width, size.height); } startPreview(); } public void onStop() { if (inPreview && camera != null) { camera.stopPreview(); } if (camera != null) camera.release(); camera = null; inPreview = false; setVisibility(GONE); } private CustomCameraSurface(Context context) { super(context); init(); } public CustomCameraSurface(Context context, AttributeSet attrs) { super(context, attrs); init(); } public CustomCameraSurface(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); }//初始化 void init() { previewHolder = getHolder(); previewHolder.addCallback(this); previewHolder.setFormat(PixelFormat.TRANSPARENT); innerFrame = new RelativeLayout(getContext()); innerFrame.addView(this); frame = new LinearLayout(getContext()); frame.addView(innerFrame); } public LinearLayout getFrame() { return frame; } public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // TODO Auto-generated method stub initPreview(width, height); startPreview(); } public void surfaceCreated(SurfaceHolder holder) { } public void surfaceDestroyed(SurfaceHolder holder) { // 记得销毁,释放相机 onStop(); } private Camera.Size getBestPreviewSize(int width, int height, Camera.Parameters parameters) { Camera.Size result = null; for (Camera.Size size : parameters.getSupportedPreviewSizes()) { if (size.width <= width && size.height <= height) { if (result == null) { result = size; } else { int resultArea = result.width * result.height; int newArea = size.width * size.height; if (newArea > resultArea) { result = size; } } } } this.size = result; return (result); } private void initPreview(int width, int height) { //利用布局,重设宽高来撑开界面,超出的部分直接撑出屏幕,至于为什么用这两个布局,自己去谷歌了! if (camera != null && previewHolder.getSurface() != null) { if (!cameraConfigured) { Camera.Parameters parameters = camera.getParameters(); Camera.Size size = getBestPreviewSize(width, height, parameters); if (size != null) { parameters.setPreviewSize(size.width, size.height); camera.setParameters(parameters); cameraConfigured = true; // Setting up correctly the view double ratio = size.height / (double) size.width; int Y = getResources().getDisplayMetrics().heightPixels; int X = getResources().getDisplayMetrics().widthPixels; LayoutParams params = innerFrame.getLayoutParams(); params.height = Y; params.width = (int) (Y * ratio); innerFrame.setLayoutParams(params); int deslocationX = (int) (params.width / 2.0 - X / 2.0); innerFrame.animate().translationX(-deslocationX); } } try { camera.setPreviewDisplay(previewHolder); camera.setDisplayOrientation(90); } catch (Throwable t) { //错误处理,自己做相应的逻辑 setVisibility(GONE); } } } private void startPreview() { if (cameraConfigured && camera != null) { camera.startPreview(); inPreview = true; } }}
更多相关文章
- 关于 Android(安卓)Fragment的官方说明文档
- Android界面布局编程
- 第27章、流动视图ScrollView(从零开始学Android)
- Android(安卓)改变窗口标题栏的布局
- (二)Unity 与 Android的布局管理
- .Net码农学Android---五分钟了解布局
- Android软件开发之盘点界面五大布局(十六)
- 关于Android的屏幕适配
- Android的UI组件 .