Android Front Facing Camera с перевернутыми фотографиями
У меня есть это приложение, которое работает в портретном режиме и как часть одного действия у меня есть объект камеры, работающий как фрагмент в нем.
У меня есть возможность переключаться с фронтальной камеры на обратную сторону и при съемке фотографий с задней камеры все в порядке и хорошо.
Когда я делаю фотографии с фронтальной камерой, они перевернуты на 180 градусов.
Теперь я знаю, что это, вероятно, связано с ориентацией в портретном режиме, но наличие в ландшафте просто убьет идею моего приложения.
В любом случае это может быть исправлено, так что сделанное изображение совпадает с тем, которое вы видите в предварительном просмотре?
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");
Проблема в том, что после того, как я попытаюсь сделать снимок, эта вещь падает. Кроме того, если он работает некоторое время только в режиме предварительного просмотра, он снова сработает. Я также должен добавить, что в другом методе я это делаю.
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;
}
}
Это называется, когда вы переключаетесь между камерами (обратная сторона обращена к передней стороне наоборот). Может ли это вмешаться в прослушиватель событий ориентации?
Кроме того, при сохранении сделанного снимка это то, что я называю. До того, как он просто взял данные в качестве параметра, но я попытался сделать его ориентацией экрана. Проблема в том, что ориентация экрана всегда равна 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;
}
Ответы
Ответ 1
Хорошо. Кажется, я позаботился об этом. Я использовал этот совет: Android, передняя и задняя камеры Ориентация, пейзаж
И изменил мою функцию 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;
}
Это похоже на работу и делает трюк. Хотя я не уверен, что это лучший способ, я доволен этим. Теперь все, что мне нужно сделать, это выяснить, почему он не принимает правильное соотношение сторон при использовании передней камеры.
Ответ 2
Попробуйте эти ссылки:
http://developer.android.com/reference/android/hardware/Camera.html#setDisplayOrientation(int)
http://developer.android.com/reference/android/hardware/Camera.Parameters.html#setRotation(int)
В частности, вот фрагмент формулировки из ссылки setRotation.
"Если приложения хотят повернуть изображение в соответствии с ориентацией того, что видят пользователи, приложения должны использовать OrientationEventListener и Camera.CameraInfo. Значение OrientationEventListener относительно естественной ориентации устройства. CameraInfo.orientation - это угол между ориентации камеры и ориентации на естественное устройство. Сумма двух из них - угол поворота задней камеры. Разница между ними - угол поворота для фронтальной камеры. Обратите внимание, что изображения JPEG с фронтальными камерами не отражаются как в режиме предварительного просмотра.
Я использовал этот код как есть, не изменял его вообще. Моя камера теперь лучше, но все-таки нужна какая-то ТЛК. Я также не имею переднюю функциональность.
Удачи!