Android 前置摄像头拍摄倒置照片
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10283467/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android Front Facing Camera Taking Inverted Photos
提问by Valentin
I have this app that is running in portrait mode and as a part of one activity I have a camera object running as a fragment in it.
我有一个以纵向模式运行的应用程序,作为一项活动的一部分,我有一个相机对象作为片段在其中运行。
I have the option to switch from front to back-facing camera and when taking photos with the back camera all is fine and well.
我可以选择从前置摄像头切换到后置摄像头,使用后置摄像头拍照时一切正常。
When I take photos with the front-facing camera though, they get inverted 180 degrees. Now I know that this is probably something to do with the orientation being in portrait mode, but having it in landscape would just kill the idea of my application.
但是,当我使用前置摄像头拍照时,它们会倒转 180 度。现在我知道这可能与纵向模式下的方向有关,但横向模式只会扼杀我的应用程序的想法。
Is there anyway this can be fixed so the picture taken is the same as the one you see in the preview?
无论如何,这是否可以修复,以便拍摄的照片与您在预览中看到的照片相同?
listener = new OrientationEventListener(this.getActivity(),SensorManager.SENSOR_DELAY_NORMAL){
@Override
public void onOrientationChanged(int orientation) {
// TODO Auto-generated method stub
if (orientation == ORIENTATION_UNKNOWN) return;
android.hardware.Camera.CameraInfo info =
new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(mCurrentCamera, info);
orientation = (orientation + 45) / 90 * 90;
int rotation = 0;
if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
rotation = (info.orientation - orientation + 360) % 360;
} else { // back-facing camera
rotation = (info.orientation + orientation) % 360;
}
if (mCamera.getParameters() != null){
Camera.Parameters mParameters = mCamera.getParameters();
mParameters.setRotation(rotation);
mCamera.setParameters(mParameters);
}
}
};
listener.enable();
if (listener.canDetectOrientation())
Log.d("Orientation Possible", "Orientation Possible");
The problem is, after I try an take a picture this thing crashes. Also, if it runs for a while just in preview mode it crashes again. I also should probably add, that in another method I am doing this.
问题是,在我尝试拍照后,这件事崩溃了。此外,如果它只是在预览模式下运行一段时间,它会再次崩溃。我还应该补充一点,我正在以另一种方法执行此操作。
public void switchCamera(Camera camera) {
setCamera(camera);
try {
camera.setPreviewDisplay(mHolder);
} catch (IOException exception) {
Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
}
Camera.Parameters parameters = camera.getParameters();
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
requestLayout();
try{
camera.setParameters(parameters);
}
catch (RuntimeException ex){
Log.d("Preview", "Failure to set proper parameters");
//need to improve this method
if (mSupportedPreviewSizes != null) {
Camera.Size cs = mSupportedPreviewSizes.get(0);
parameters.setPreviewSize(cs.width, cs.height);
camera.setParameters(parameters);
requestLayout();
//int tempheight = mPreviewSize.height;
//mPreviewSize.height = mPreviewSize.width;
//mPreviewSize.width = tempheight;
}
}
This is called when you switch between cameras(back facing to front facing vice-versa). Could this be interfering with the orientation event listener?
当您在相机之间切换时会调用此方法(从背面到正面,反之亦然)。这会干扰方向事件侦听器吗?
Also, when saving the picture taken, this is what I call. Before it was just taking in data as a parameter, but I tried to make it take screen orientation as well. The problem is the screen orientation is always 90, no matter what. So the bitmap will always be rotated by 90 degrees(which is great for taking photos with the back camera) but inverts it when taking it with the front camera. Could a fix be implemented in this function?
另外,在保存拍摄的照片时,这就是我所说的。在它只是将数据作为参数接收之前,但我试图让它也采用屏幕方向。问题是屏幕方向总是 90,无论如何。因此位图将始终旋转 90 度(这对于使用后置摄像头拍摄照片非常有用),但在使用前置摄像头拍摄时会反转。可以在此功能中实施修复吗?
public static Bitmap MakeSquare(byte[] data, int orientation) {
int width;
int height;
// Rotate photo
Matrix matrix = new Matrix();
matrix.postRotate(orientation);
// Convert ByteArray to Bitmap
Bitmap bitPic = BitmapFactory.decodeByteArray(data, 0, data.length);
width = bitPic.getWidth();
height = bitPic.getHeight();
// Create new Bitmap out of the old one
Bitmap bitPicFinal = Bitmap.createBitmap(bitPic, 0, 0, width, height,matrix, true);
bitPic.recycle();
int desWidth;
int desHeight;
desWidth = bitPicFinal.getWidth();
desHeight = desWidth;
Bitmap croppedBitmap = Bitmap.createBitmap(bitPicFinal, 0,bitPicFinal.getHeight() / 2 - bitPicFinal.getWidth() / 2,desWidth, desHeight);
croppedBitmap = Bitmap.createScaledBitmap(croppedBitmap, 528, 528, true);
return croppedBitmap;
}
回答by Valentin
Well well. It seems I have kind of taken care of it. I used the advice from this: Android, front and back camera Orientation , Landscape
好吧。看来我有点照顾它了。我使用了这个建议:Android, front and back camera Orientation , Landscape
And changed my MakeSquare function to this:
并将我的 MakeSquare 函数更改为:
public static Bitmap MakeSquare(byte[] data, int cameraID) {
int width;
int height;
Matrix matrix = new Matrix();
Camera.CameraInfo info = new Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(cameraID, info);
// Convert ByteArray to Bitmap
Bitmap bitPic = BitmapFactory.decodeByteArray(data, 0, data.length);
width = bitPic.getWidth();
height = bitPic.getHeight();
// Perform matrix rotations/mirrors depending on camera that took the photo
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT)
{
float[] mirrorY = { -1, 0, 0, 0, 1, 0, 0, 0, 1};
Matrix matrixMirrorY = new Matrix();
matrixMirrorY.setValues(mirrorY);
matrix.postConcat(matrixMirrorY);
}
matrix.postRotate(90);
// Create new Bitmap out of the old one
Bitmap bitPicFinal = Bitmap.createBitmap(bitPic, 0, 0, width, height,matrix, true);
bitPic.recycle();
int desWidth;
int desHeight;
desWidth = bitPicFinal.getWidth();
desHeight = desWidth;
Bitmap croppedBitmap = Bitmap.createBitmap(bitPicFinal, 0,bitPicFinal.getHeight() / 2 - bitPicFinal.getWidth() / 2,desWidth, desHeight);
croppedBitmap = Bitmap.createScaledBitmap(croppedBitmap, 528, 528, true);
return croppedBitmap;
}
This seems to work and do the trick. Although I am not sure this was the best way, I am content with it. Now all I have to do is figure out why its not taking in the proper aspect ratio when using the front camera.
这似乎有效并且可以解决问题。虽然我不确定这是最好的方法,但我很满意。现在我所要做的就是弄清楚为什么在使用前置摄像头时它没有采用正确的纵横比。
回答by JustSomeGuy
Give these links a try:
试试这些链接:
http://developer.android.com/reference/android/hardware/Camera.html#setDisplayOrientation(int)
http://developer.android.com/reference/android/hardware/Camera.html#setDisplayOrientation(int)
http://developer.android.com/reference/android/hardware/Camera.Parameters.html#setRotation(int)
http://developer.android.com/reference/android/hardware/Camera.Parameters.html#setRotation(int)
Specifically, here is a chunk of verbiage from the setRotation link.
具体来说,这里是 setRotation 链接中的一段话。
"If applications want to rotate the picture to match the orientation of what users see, apps should use OrientationEventListener and Camera.CameraInfo. The value from OrientationEventListener is relative to the natural orientation of the device. CameraInfo.orientation is the angle between camera orientation and natural device orientation. The sum of the two is the rotation angle for back-facing camera. The difference of the two is the rotation angle for front-facing camera. Note that the JPEG pictures of front-facing cameras are not mirrored as in preview display."
“如果应用程序想要旋转图片以匹配用户看到的方向,应用程序应该使用 OrientationEventListener 和 Camera.CameraInfo。来自 OrientationEventListener 的值是相对于设备的自然方向。CameraInfo.orientation 是相机方向和相机方向之间的角度自然设备方向,两者之和为后置摄像头旋转角度,两者之差为前置摄像头旋转角度。注意前置摄像头的JPEG图片并没有像预览中那样镜像展示。”
I used this code as-is, didn't modify it at all. My camera is better now, still needs some TLC though. I also don't have front-facing functionality yet.
我按原样使用此代码,根本没有修改它。我的相机现在更好了,但仍然需要一些 TLC。我还没有前置功能。
Good luck!
祝你好运!