我的Camera-SurfaceHolder有一个奇怪的问题。
我想在我的活动中显示相机的图像。 这一切都在我的GalaxyS1上有很大的作用(CyanogenMod - Android 4.4) 另一方面,在我的S3(也是CyanogenMod - Android 4.4)上看起来很奇怪。
没有标题栏的风景图片没问题,但是当我显示标题栏或将其转换为肖像模式时,它看起来很扭曲:
---编辑---
谢谢Alex Cohn的帮助。看起来你是对的。 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) {...}
---编辑---
我记录了onMeasure和surface Changed的值。他们似乎没问题:
肖像:
表面变化:Witdh:720身高:1134
onMeasure:宽度:720高度:1134
风景:
表面变化:Witdh:1280身高:590
onMeasure:宽度:1280高度:590
预览尺寸:宽度:704高度:576
我得到以下可能的预览尺寸。
数组中有8个元素:
960 x 720, 1280 x 720, 1184 x 666, 960 x 640, 704 x 576 , 640 x 480, 352 x 288, 320 x 240
希望任何人都可以提供帮助!
谢谢, 托拜厄斯
答案 0 :(得分:2)
您的问题来源如下:
parameters.setPreviewSize(w, h);
surfaceChanged()
方法中的。您无法在Android中将预览大小设置为任意值。您应该只使用 Parameters.getSupportedPreviewSizes() 返回的(w,h)对。否则,您会遇到 appearing to succeed is a valid form of undefined behavior 情况。实际上,许多设备只会在camera.setParameters(parameters)
上引发 RuntimeException ,但您的开发平台选择表现不同。
不要求预览尺寸与用于显示它的表面相同,例如在640x480表面上使用320x240预览是可以的。但是,如果您的预览和曲面具有不同的宽高比,则图像看起来会拉伸(请参阅http://i.stack.imgur.com/VFwes.jpg)。轻微失真可能是可以忍受的,例如在800x400像素场景上使用1280x720预览,但是超过特定阈值,您别无选择,只能使用部分屏幕,在预览的上方和下方留下边距。
您可以找到开发者社区提出的建议:use getOptimalPreviewSize()
for given width, hight(这只是一个例子)。