Android摄像头图像失真-SurfaceHolder-
我的相机表面有个奇怪的问题 我想在活动中显示摄像头的图像。 这一切在我的GalaxyS1(CyanogenMod-Android 4.4)上都非常有效 另一方面,在我的S3(也是CyanogenMod-Android4.4)上,它看起来很奇怪 没有标题栏的横向图像是正常的,但当我显示标题栏或将其转换为纵向模式时,它看起来扭曲了: ---编辑--- 谢谢亚历克斯·科恩的帮助。看来你是对的。portraid模式的预览现在运行良好。但从景观上看,它仍然是扭曲的。我检查了预览比例,看起来还可以。就我所知,我也正确设置了预览大小。那么它有什么问题呢 以下是当前代码:Android摄像头图像失真-SurfaceHolder-,android,camera,surfaceholder,Android,Camera,Surfaceholder,我的相机表面有个奇怪的问题 我想在活动中显示摄像头的图像。 这一切在我的GalaxyS1(CyanogenMod-Android 4.4)上都非常有效 另一方面,在我的S3(也是CyanogenMod-Android4.4)上,它看起来很奇怪 没有标题栏的横向图像是正常的,但当我显示标题栏或将其转换为纵向模式时,它看起来扭曲了: ---编辑--- 谢谢亚历克斯·科恩的帮助。看来你是对的。portraid模式的预览现在运行良好。但从景观上看,它仍然是扭曲的。我检查了预览比例,看起来还可以。就我所
private static final String TAG = CameraView.class.getSimpleName();
private SurfaceHolder surfaceHolder;
private Camera camera;
private List<Size> mSupportedPreviewSizes;
private Size mPreviewSize;
public CameraView(Activity activity) {
super(activity);
surfaceHolder = getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
camera = Camera.open();
mSupportedPreviewSizes = camera.getParameters()
.getSupportedPreviewSizes();
setCameraDisplayOrientation(activity, 0, camera);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Camera.Parameters parameters = camera.getParameters();
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
camera.setParameters(parameters);
camera.startPreview();
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
camera.setPreviewDisplay(holder);
} catch (IOException exception) {
camera.release();
camera = null;
}
}
@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
camera.stopPreview();
camera.release();
camera = null;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(width, height);
if (mSupportedPreviewSizes != null) {
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
}
}
private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w,
int h) {...}
public static void setCameraDisplayOrientation(Activity activity,
int cameraId, Camera camera) {...}
private static final String TAG=CameraView.class.getSimpleName();
私人地勤人员地勤人员;
私人摄像机;
私有列表msupportedpreviews;
私人规模的mPreviewSize;
公共摄像师(活动){
超级(活动);
surfaceHolder=getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(surfaceHolder.SURFACE\u TYPE\u PUSH\u缓冲区);
camera=camera.open();
mSupportedPreviewSizes=camera.getParameters()
.getSupportedPreviewSizes();
设置摄像机方向(活动,0,摄像机);
}
@凌驾
公共无效表面更改(表面持有人,整数格式,整数w,整数h){
Camera.Parameters=Camera.getParameters();
parameters.setPreviewSize(mPreviewSize.width、mPreviewSize.height);
设置参数(参数);
camera.startPreview();
}
@凌驾
已创建的公共空白表面(表面持有人){
试一试{
摄像头。设置预览显示(支架);
}捕获(IOException异常){
相机。释放();
摄像机=零;
}
}
@凌驾
公共空间表面已覆盖(表面层arg0){
camera.stopPreview();
相机。释放();
摄像机=零;
}
@凌驾
测量时的保护空隙(内部宽度测量等级、内部高度测量等级){
最终整数宽度=resolveSize(getSuggestedMinimumWidth(),widthMeasureSpec);
最终整数高度=resolveSize(getSuggestedMinimumHeight(),heightMeasureSpec);
设置测量尺寸(宽度、高度);
if(mSupportedPreviewSizes!=null){
mPreviewSize=getOptimalPreviewSize(MSSupportedPreviewSize、宽度、高度);
}
}
私人相机。大小GetOptimizePreviewSize(列表大小,整数w,
int h){…}
公共静态无效设置和播放方向(活动,
int cameraId,摄像机){…}
---编辑---
我记录了onMeasure和surface change的值。他们似乎还行:
肖像:
表面变化:Witdh:720高度:1134
测量:宽度:720高度:1134
景观:
表面更改:Witdh:1280高度:590
测量:宽度:1280高度:590
预览大小:宽度:704高度:576
我得到了以下可能的预览尺寸
数组中有8个元素:
960x720,
1280x720,
1184 x 666,
960x640,
704 x 576,
640x480,
352 x 288,
320 x 240
希望任何人都能帮忙
谢谢,
Tobias问题的根源如下:
parameters.setPreviewSize(w, h);
在surfaceChanged()
方法中。在Android中,不能将预览大小设置为任意值。只能使用返回的(w,h)对。否则,你就会陷入困境。实际上,许多设备只会在camera.setParameters(parameters)
上引发一个运行时异常
不要求预览大小与用于显示它的曲面相同,例如,在640x480曲面上使用320x240预览是可以的。但是,如果预览和曲面具有不同的纵横比,则图像看起来会拉伸(请参见)。轻微的失真可能是可以容忍的,比如在800x400像素的屏幕上使用1280x720预览,但超过某个阈值时,您别无选择,只能使用部分屏幕,在预览上下留下边距
你可以找到开发者社区的想法:(这只是一个例子)。哇,这似乎很有帮助。肖像模式就是这样工作的。不过,我还是遇到了一些问题(参见代码)。也许你知道为什么?谢谢你!请打印以记录您选择的大小以及
surfaceChanged()
和onMeasure()回调中的w,h
参数。我记录了这些值。他们看起来还不错,但也许你发现了什么。我猜它与标题栏有关,因为它似乎可以在全屏中找到。那么,您为1280x590选择的预览大小是多少?预览大小是:宽度:704高度:576-用于OnMeasure()中的函数;此外:如果我自动将预览设置为,比如说,320 x 240,它就可以按计划正常工作(只是拉伸)!