android预览画面拉伸,Android使用SurfaceView作为相机预览识图时,视图被拉伸的问题...

网上已经有很多人提到过,导致这种现象的原因是,传入的相机预览图像长宽比例,与SurfaceView本身大小长宽比例不一致。

那么解决方法也非常简单,只要获取一下设备本身支持的相机比例,然后选择其中一个与SurfaceView实际比例(经常就是设备的长宽)最相近的即可。

下面的代码是创建一个用于相机预览的SurfaceView的过程:

//继承SurfaceView并且实现SurfaceHolder.Callback接口

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback

{

private static final String TAG = "CameraPreview";

private final SurfaceHolder mHolder;

private Camera mCamera;

public CameraPreview(Context context, Camera camera) {

super(context);

mCamera = camera;

mHolder = getHolder();

mHolder.addCallback(this);

//下面一行适用于Android3.0之前的设备适配,一般可以省略

mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

}

@Override

public void surfaceCreated(SurfaceHolder holder) {

//制定相机图像的绘制区域为这个SurfaceView,并且启动相机的预览

try {

mCamera.setPreviewDisplay(holder);

mCamera.startPreview();

} catch (IOException e) {

e.printStackTrace();

}

}

@Override

public void surfaceDestroyed(SurfaceHolder holder) {

//摧毁时释放相机的资源,如果留空的话则需要在activity里释放camera

mCamera.release();

}

@Override

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {

//当SurfaceView尺寸变化时(包括设备横屏竖屏改变时时),需要重新设定相关参数

if (mHolder.getSurface() == null) {

//检查SurfaceView是否存在

return;

}

//改变设置前先关闭相机

try {

mCamera.stopPreview();

} catch (Exception e) {

e.printStackTrace();

}

//使用最佳比例配置重启相机

try {

mCamera.setPreviewDisplay(mHolder);

final Camera.Parameters parameters = mCamera.getParameters();

final Camera.Size size = getBestPreviewSize(w, h);

parameters.setPreviewSize(size.width, size.height);

mCamera.setParameters(parameters);

mCamera.startPreview();

} catch (Exception e) {

Log.d(TAG, "Error starting camera preview: " + e.getMessage());

}

}

private Camera.Size getBestPreviewSize(int width, int height) {

//在下面叙述

}

}

接下来是`getBestPreviewSize(int,int)的实现:

private Camera.Size getBestPreviewSize(int width, int height) {

Camera.Size result = null;

final Camera.Parameters p = mCamera.getParameters();

//特别注意此处需要规定rate的比是大的比小的,不然有可能出现rate = height/width,但是后面遍历的时候,current_rate = width/height,所以我们限定都为大的比小的。

float rate = (float) Math.max(width, height)/ (float)Math.min(width, height);

float tmp_diff;

float min_diff = -1f;

for (Camera.Size size : p.getSupportedPreviewSizes()) {

float current_rate = (float) Math.max(size.width, size.height)/ (float)Math.min(size.width, size.height);

tmp_diff = Math.abs(current_rate-rate);

if( min_diff < 0){

min_diff = tmp_diff ;

result = size;

}

if( tmp_diff < min_diff ){

min_diff = tmp_diff ;

result = size;

}

}

return result;

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android 中,可以通过设置 Camera.Parameters 中的 setPreviewSize 和 setPreviewFormat 方法来实现相机预览的翻转。 首先,需要获取当前设备支持的预览尺寸和格式。可以使用 Camera.Parameters 中的 getSupportedPreviewSizes 和 getSupportedPreviewFormats 方法来获取支持的预览尺寸和格式列表。 然后,可以通过 setPreviewSize 和 setPreviewFormat 方法来设置预览尺寸和格式。在设置预览尺寸,需要根据设备的旋转角度进行调整,以保证预览画面正常显示。可以使用 CameraInfo 中的 orientation 字段来获取设备的旋转角度。 最后,可以使用 SurfaceView 或 TextureView 来显示相机预览画面,并使用 Camera.setPreviewDisplay 方法将预览画面相机绑定起来。 下面是一个简单的示例代码,可以实现相机预览翻转: ``` public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { private Camera mCamera; private int mRotation; public CameraPreview(Context context) { super(context); getHolder().addCallback(this); } public void surfaceCreated(SurfaceHolder holder) { try { mCamera = Camera.open(); mCamera.setPreviewDisplay(holder); // 获取支持的预览尺寸和格式 Camera.Parameters params = mCamera.getParameters(); List<Camera.Size> sizes = params.getSupportedPreviewSizes(); int format = params.getPreviewFormat(); // 根据设备旋转角度调整预览尺寸 Camera.CameraInfo info = new Camera.CameraInfo(); Camera.getCameraInfo(0, info); int rotation = ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation(); int degrees = 0; switch (rotation) { case Surface.ROTATION_0: degrees = 0; break; case Surface.ROTATION_90: degrees = 90; break; case Surface.ROTATION_180: degrees = 180; break; case Surface.ROTATION_270: degrees = 270; break; } if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { mRotation = (info.orientation + degrees) % 360; mRotation = (360 - mRotation) % 360; } else { mRotation = (info.orientation - degrees + 360) % 360; } for (Camera.Size size : sizes) { if (size.width * 3 == size.height * 4) { params.setPreviewSize(size.width, size.height); break; } } // 设置预览格式和旋转角度 params.setPreviewFormat(format); mCamera.setDisplayOrientation(mRotation); mCamera.setParameters(params); // 开始预览 mCamera.startPreview(); } catch (IOException e) { e.printStackTrace(); } } public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // 暂不需要处理 } public void surfaceDestroyed(SurfaceHolder holder) { mCamera.stopPreview(); mCamera.release(); mCamera = null; } } ``` 这个示例代码可以实现在相机预览根据设备的旋转角度进行调整,保证预览画面正常显示。如果需要实现更复杂的功能,比如相机拍照、录制视频等,可以参考 Android 官方文档中的 Camera 相关章节。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值