Android - 摄像头在某些设备的后置摄像头上提供颠倒的数据
Android - Camera provide upside down data on back camera in some devices
我在 GLSurfaceView
上渲染 camera preview
一切正常,但 camera preview
在某些设备上显示颠倒,特别是在 Nexus 5X 上。我已经检查了这个解决方案 Android - Camera preview is sideways
.这是我处理方向问题的代码
private void setCameraDisplayOrientation() {
Constants.debugLog(TAG_DEBUG, "setCameraDisplayOrientation");
Constants.debugLog(TAG, "setCameraDisplayOrientation ");
if (camera == null) {
Constants.debugLog(TAG + " Owncamera", "setCameraDisplayOrientation - camera null");
return;
}
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(currentCameraId, info);
WindowManager winManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
int rotation = winManager.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;
}
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
this.cameraOrientation = 2;
} else if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
this.cameraOrientation = 1;
}
Constants.debugLog(TAG_DEBUG, "result: " + result + " this.cameraOrientation == " + this.cameraOrientation);
Constants.debugLog(TAG, "result: " + result + " this.cameraOrientation == " + this.cameraOrientation);
//Log.e("camera_orient", "res: "+ result);
camera.setDisplayOrientation(result);
}
从 Camera.CameraInfo info
class,我可以得到 orientation
。对于最大设备,我在 portrait mode
上获得的值是“for front camera = 270, back camera = 90
”,但在 Nexus 5X
上它为两个前端提供 camera orientation
270,270 &后置摄像头。除了在其他设备上,我的相机在纵向模式下为前后摄像头提供 result
值 90,但对于 Nexus 5x
前置摄像头 90 后置摄像头 270。我也尝试通过设置值固定 90在 camera.setDisplayOrientation(90);
Nexus 5X 设备上但不工作
如何处理这个问题,以便所有设备相机的方向都相同,我不会得到任何旋转的图像??
尝试
1.首先,添加下面定义的方法(writeFile、processImage和getCorrectCameraOrientation)
2. 拍摄照片后计算相机方向并更新 onPictureTaken**
@Override
public void onPictureTaken (final byte[] data, final Camera camera) {
int rotationAngle = getCorrectCameraOrientation (this, info);
3. 创建文件并使用 rotationAngle 更新照片角度
File file = new File (folder, fileName);
try {
file.createNewFile ();
}
catch (IOException e) {
e.printStackTrace ();
}
writeFile (data, file);
processImage (file, rotationAngle, compressRatio);
writeFile
public static void writeFile (byte[] data, File file) throws IOException {
BufferedOutputStream bos = null;
try {
FileOutputStream fos = new FileOutputStream (file);
bos = new BufferedOutputStream (fos);
bos.write (data);
}
finally {
if (bos != null) {
try {
bos.flush ();
bos.close ();
}
catch (Exception e) {
}
}
}
}
processImage
public static void processImage (File file, int rotationAngle, int compressionRatio) {
BufferedOutputStream bos = null;
try {
Bitmap bmp = BitmapFactory.decodeFile (file.getPath ());
Matrix matrix = new Matrix ();
matrix.postRotate (rotationAngle);
bmp = Bitmap.createBitmap (bmp, 0, 0, bmp.getWidth (), bmp.getHeight (), matrix, true);
FileOutputStream fos = new FileOutputStream (file);
bmp.compress (Bitmap.CompressFormat.PNG, compressionRatio, fos);
}
catch (IOException e) {
e.printStackTrace ();
}
catch (OutOfMemoryError t) {
t.printStackTrace ();
}
catch (Throwable t) {
t.printStackTrace ();
}
finally {
if (bos != null) {
try {
bos.flush ();
bos.close ();
}
catch (Exception e) {
}
}
}
}
getCorrectCameraOrientation
public static int getCorrectCameraOrientation (Activity activity, Camera.CameraInfo info) {
int rotation = activity.getWindowManager ().getDefaultDisplay ().getRotation ();
int degrees = 0;
if (hasValidRotation (rotation)) {
degrees = rotation * 90;
}
int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360;
}
else {
result = (info.orientation - degrees + 360) % 360;
}
return result;
}
问题原因: 默认最大设备数 return 使用相机时默认方向为 90 度的图像 api 1. 我不确定这是在使用相机 api 2 的情况下。但是在 Nexus 5x 和一些稀有设备(使用相机 api 1)的情况下,它 return 默认旋转 270 度的图像是一个例外某些特定型号设备上的情况。所以你必须为 Nexus 5X 添加 180 度的附加旋转。请查看打印 Nexus 5X 图像方向的日志。
我在 GLSurfaceView
上渲染 camera preview
一切正常,但 camera preview
在某些设备上显示颠倒,特别是在 Nexus 5X 上。我已经检查了这个解决方案 Android - Camera preview is sideways
.这是我处理方向问题的代码
private void setCameraDisplayOrientation() {
Constants.debugLog(TAG_DEBUG, "setCameraDisplayOrientation");
Constants.debugLog(TAG, "setCameraDisplayOrientation ");
if (camera == null) {
Constants.debugLog(TAG + " Owncamera", "setCameraDisplayOrientation - camera null");
return;
}
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(currentCameraId, info);
WindowManager winManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
int rotation = winManager.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;
}
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
this.cameraOrientation = 2;
} else if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
this.cameraOrientation = 1;
}
Constants.debugLog(TAG_DEBUG, "result: " + result + " this.cameraOrientation == " + this.cameraOrientation);
Constants.debugLog(TAG, "result: " + result + " this.cameraOrientation == " + this.cameraOrientation);
//Log.e("camera_orient", "res: "+ result);
camera.setDisplayOrientation(result);
}
从 Camera.CameraInfo info
class,我可以得到 orientation
。对于最大设备,我在 portrait mode
上获得的值是“for front camera = 270, back camera = 90
”,但在 Nexus 5X
上它为两个前端提供 camera orientation
270,270 &后置摄像头。除了在其他设备上,我的相机在纵向模式下为前后摄像头提供 result
值 90,但对于 Nexus 5x
前置摄像头 90 后置摄像头 270。我也尝试通过设置值固定 90在 camera.setDisplayOrientation(90);
Nexus 5X 设备上但不工作
如何处理这个问题,以便所有设备相机的方向都相同,我不会得到任何旋转的图像??
尝试
1.首先,添加下面定义的方法(writeFile、processImage和getCorrectCameraOrientation)
2. 拍摄照片后计算相机方向并更新 onPictureTaken**
@Override
public void onPictureTaken (final byte[] data, final Camera camera) {
int rotationAngle = getCorrectCameraOrientation (this, info);
3. 创建文件并使用 rotationAngle 更新照片角度
File file = new File (folder, fileName);
try {
file.createNewFile ();
}
catch (IOException e) {
e.printStackTrace ();
}
writeFile (data, file);
processImage (file, rotationAngle, compressRatio);
writeFile
public static void writeFile (byte[] data, File file) throws IOException {
BufferedOutputStream bos = null;
try {
FileOutputStream fos = new FileOutputStream (file);
bos = new BufferedOutputStream (fos);
bos.write (data);
}
finally {
if (bos != null) {
try {
bos.flush ();
bos.close ();
}
catch (Exception e) {
}
}
}
}
processImage
public static void processImage (File file, int rotationAngle, int compressionRatio) {
BufferedOutputStream bos = null;
try {
Bitmap bmp = BitmapFactory.decodeFile (file.getPath ());
Matrix matrix = new Matrix ();
matrix.postRotate (rotationAngle);
bmp = Bitmap.createBitmap (bmp, 0, 0, bmp.getWidth (), bmp.getHeight (), matrix, true);
FileOutputStream fos = new FileOutputStream (file);
bmp.compress (Bitmap.CompressFormat.PNG, compressionRatio, fos);
}
catch (IOException e) {
e.printStackTrace ();
}
catch (OutOfMemoryError t) {
t.printStackTrace ();
}
catch (Throwable t) {
t.printStackTrace ();
}
finally {
if (bos != null) {
try {
bos.flush ();
bos.close ();
}
catch (Exception e) {
}
}
}
}
getCorrectCameraOrientation
public static int getCorrectCameraOrientation (Activity activity, Camera.CameraInfo info) {
int rotation = activity.getWindowManager ().getDefaultDisplay ().getRotation ();
int degrees = 0;
if (hasValidRotation (rotation)) {
degrees = rotation * 90;
}
int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360;
}
else {
result = (info.orientation - degrees + 360) % 360;
}
return result;
}
问题原因: 默认最大设备数 return 使用相机时默认方向为 90 度的图像 api 1. 我不确定这是在使用相机 api 2 的情况下。但是在 Nexus 5x 和一些稀有设备(使用相机 api 1)的情况下,它 return 默认旋转 270 度的图像是一个例外某些特定型号设备上的情况。所以你必须为 Nexus 5X 添加 180 度的附加旋转。请查看打印 Nexus 5X 图像方向的日志。