【发布时间】:2021-01-20 06:59:12
【问题描述】:
我正在为我的 AR View 应用使用自定义相机。相机预览在全屏纵向模式下被拉伸。
我在 stackoverflow 上尝试了许多解决方案,但它不适用于我的代码。 谁能告诉我如何解决这个问题?
我在下面添加了我的相机工作代码和一个屏幕截图,预览被拉伸了。
这是我的自定义相机类:
public class ARCamera extends ViewGroup implements SurfaceHolder.Callback {
private final static float Z_NEAR = 0.5f;
private final static float Z_FAR = 2000;
private final String TAG = ARCamera.class.getSimpleName();
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
Camera camera;
Activity activity;
float[] projectionMatrix = new float[16];
int cameraWidth;
int cameraHeight;
int screenWidth, screenHeight;
int rotation;
public ARCamera(Context context, SurfaceView surfaceView) {
super(context);
this.surfaceView = surfaceView;
this.activity = (Activity) context;
surfaceHolder = this.surfaceView.getHolder();
surfaceHolder.addCallback(this);
DisplayMetrics displayMetrics = new DisplayMetrics();
WindowManager windowManager = (WindowManager) context
.getSystemService(Context.WINDOW_SERVICE);
windowManager.getDefaultDisplay().getMetrics(displayMetrics);
rotation = windowManager.getDefaultDisplay()
.getRotation();
this.screenWidth = displayMetrics.widthPixels;
this.screenHeight = displayMetrics.heightPixels;
}
public void setCamera(Camera camera) {
this.camera = camera;
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
}
public void surfaceCreated(SurfaceHolder holder) {
try {
if (camera != null) {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(Camera.CameraInfo.CAMERA_FACING_BACK, info);
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;
}
camera.setDisplayOrientation((info.orientation - degrees + 360) % 360);
camera.setPreviewDisplay(holder);
}
} catch (IOException exception) {
Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
if (camera != null) {
camera.setPreviewCallback(null);
camera.stopPreview();
camera.release();
camera = null;
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (camera != null) {
this.cameraWidth = width;
this.cameraHeight = height;
Camera.Parameters parameters = camera.getParameters();
try {
List<Camera.Size> supportedSizes = camera.getParameters().getSupportedPreviewSizes();
for (Camera.Size element : supportedSizes) {
element.width -= cameraWidth;
element.height -= cameraHeight;
}
Collections.sort(supportedSizes, new ResolutionOrders());
parameters.setPreviewSize(width + supportedSizes.get(supportedSizes.size() - 1).width, height + supportedSizes.get(supportedSizes.size() - 1).height);
} catch (Exception ex) {
parameters.setPreviewSize(screenWidth, screenHeight);
}
this.camera.setParameters(parameters);
this.camera.startPreview();
generateProjectionMatrix();
}
}
private void generateProjectionMatrix() {
float ratio = (float) this.screenWidth / this.screenHeight;
final int OFFSET = 0;
final float LEFT = -ratio;
final float RIGHT = ratio;
final float BOTTOM = -1;
final float TOP = 1;
Matrix.frustumM(projectionMatrix, OFFSET, LEFT, RIGHT, BOTTOM, TOP, Z_NEAR, Z_FAR);
}
public float[] getProjectionMatrix() {
return projectionMatrix;
}
class ResolutionOrders implements java.util.Comparator<Camera.Size> {
public int compare(Camera.Size left, Camera.Size right) {
return Float.compare(left.width + left.height, right.width + right.height);
}
}
}
【问题讨论】:
标签: java android android-camera surfaceview aspect-ratio