gpt4 book ai didi

Android 相机预览看起来很奇怪

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:26:38 26 4
gpt4 key购买 nike

我正在实现一个相机应用程序,当我查看预览时(尤其是使用前置摄像头时),图像非常胖。看起来图像被水平拉伸(stretch)了。我按照 sdk 示例使用优化的相机尺寸,但它没有帮助。如何调整我的相机设置,使其像其他相机应用程序一样预览?

谢谢。

我的代码如下。

public class CameraActivity extends Activity implements SurfaceHolder.Callback, Camera.ShutterCallback, Camera.PictureCallback {

Camera m_camera;
SurfaceView m_surfaceView;
int m_numOfCamera;
int m_defaultCameraId;
int m_currentCamera;
int m_surfaceWidth;
int m_surfaceHeight;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
getActionBar().setDisplayHomeAsUpEnabled(true);


m_surfaceView = (SurfaceView)findViewById(R.id.cameraPreview);
m_surfaceView.getHolder().addCallback(this);

m_camera = Camera.open();

m_numOfCamera = Camera.getNumberOfCameras();

CameraInfo cameraInfo = new CameraInfo();
for (int i = 0; i < m_numOfCamera; ++i) {
Camera.getCameraInfo(i, cameraInfo);
if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
m_defaultCameraId = i;
m_currentCamera = m_defaultCameraId;
}
}

if (m_numOfCamera < 1) {
MenuItem switchCam = (MenuItem)findViewById(R.id.menu_switch_camera);
switchCam.setVisible(false);
}
}

@Override
public void onPause() {
super.onPause();
m_camera.stopPreview();
}

@Override
public void onDestroy() {
super.onDestroy();
m_camera.release();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_camera, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(final MenuItem item)
{
if (item.getItemId() == android.R.id.home)
{
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

return true;
}
else if (item.getItemId() == R.id.menu_switch_camera)
{
if (m_camera != null) {
m_camera.stopPreview();
m_camera.release();
m_camera = null;
}

m_camera = Camera.open((m_currentCamera + 1) % m_numOfCamera);
m_currentCamera = (m_currentCamera + 1) % m_numOfCamera;

Camera.Parameters params = m_camera.getParameters();
List<Camera.Size> sizes = params.getSupportedPreviewSizes();
Camera.Size size = getOptimalPreviewSize(sizes, m_surfaceWidth, m_surfaceHeight);

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

m_camera.setParameters(params);
setCameraDisplayOrientation(this, m_currentCamera, m_camera);
m_camera.startPreview();
try {
m_camera.setPreviewDisplay(m_surfaceView.getHolder());
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
return true;
}

public void onPictureTaken(byte[] arg0, Camera arg1) {
// TODO Auto-generated method stub

}

public void onShutter() {
// TODO Auto-generated method stub

}

public void surfaceChanged(SurfaceHolder arg0, int format, int w, int h) {
m_surfaceWidth = w;
m_surfaceHeight = h;
Camera.Parameters params = m_camera.getParameters();
List<Camera.Size> sizes = params.getSupportedPreviewSizes();
Camera.Size selected = getOptimalPreviewSize(sizes, w, h);

params.setPreviewSize(selected.width, selected.height);


m_camera.setParameters(params);
setCameraDisplayOrientation(this, m_currentCamera, m_camera);
m_camera.startPreview();
}

private static void setCameraDisplayOrientation(Activity activity,
int cameraId, android.hardware.Camera camera) {
android.hardware.Camera.CameraInfo info =
new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(cameraId, info);
int rotation = activity.getWindowManager().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;
}

int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else { // back-facing
result = (info.orientation - degrees + 360) % 360;
}
camera.setDisplayOrientation(result);
}


public void surfaceCreated(SurfaceHolder arg0) {
try {
m_camera.setPreviewDisplay(m_surfaceView.getHolder());
} catch (Exception e) {
e.printStackTrace();
}
}

public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub

}

private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {


final double ASPECT_TOLERANCE = 0.1;
double targetRatio = (double) w / h;
if (sizes == null)
return null;

Size optimalSize = null;
double minDiff = Double.MAX_VALUE;

int targetHeight = h;

// Try to find an size match aspect ratio and size
for (Size size : sizes) {
double ratio = (double) size.width / size.height;
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
continue;
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}

// Cannot find the one match the aspect ratio, ignore the requirement
if (optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}

return optimalSize;
}

}

最佳答案

相机预览总是填满显示它的 SurfaceView。如果 m_surfaceView 的纵横比与相机的纵横比不匹配,预览将被拉伸(stretch)。

您需要创建匹配宽高比的 m_surfaceView。这意味着,您需要从代码而不是布局 XML 文件创建它。

您可以在 android 示例项目中找到一个示例项目 APIDemos。在项目中有一个名为 CameraPreview 的东西。这对在 SurfaceView 中设置相机预览有很好的演示。它有一个 extends ViewGroup 的类,并从代码中添加 SurfaceView 作为其子级。 onMeasure() 方法已被覆盖以确定 SurfaceView 的高度和宽度,因此纵横比得以保留。看看这个项目,我希望它会很清楚。

[抱歉,我无法在此处发布链接 - this应该是链接,但我发现它坏了。但是如果你已经安装了带有 Android SDK 的示例项目,你可以在示例中找到该项目。打开一个新的 Android 示例项目,选择 APIDemos,然后查找名为 CameraPreview 的类。据我所知,它应该在 com.example.android.apis.graphics 包中。]

关于Android 相机预览看起来很奇怪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12751016/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com