Проблема ориентации изображения на Android с пользовательской активностью камеры
Я написал пользовательскую активность камеры, чтобы обрабатывать некоторые проблемы, которые у меня были с некоторыми устройствами Android при вызове захвата изображения. Пользователь может либо выбрать сохранение изображения, либо просто использовать данные, возвращенные с OnPictureTakenCallback
.
Проблема, с которой я столкнулась, правильно отображает изображение относительно ориентации. Я заставляю действие отображаться в портрете, вызывая SetRequestedOrientation
.
Как узнать правильную ориентацию камеры, когда пользователь сделал снимок?
то есть пользователь может сделать снимок при вращении 90 (портрет).
Я попытался использовать getRotation()
на экране по умолчанию для оконного менеджера, но с установкой запрошенной ориентации на портрет, который возвращает только Surface.ROTATION_0
.
Обновление:
Чтобы прояснить мою другую проблему, как я мог определить ориентацию только из данных byte[]
в обратном обратном изображении, если пользователь не сохранил изображение?
Обновление: попробовав ответы ниже с этим кодом, все, что я получаю, это ExifInterface.ORIENTATION_NORMAL. Я также изменил свой код, чтобы просто сохранить файл, возвращенный с камеры, поскольку я не уверен, что есть простой способ определить ориентацию, имея только данные byte[]
.
private PictureCallback mPicture = new PictureCallback()
{
@Override
public void onPictureTaken(byte[] data, Camera camera)
{
File directory = new File(android.os.Environment.getExternalStoragePublicDirectory(android.os.Environment.DIRECTORY_PICTURES),
"MyApp");
if(!directory.exists())
{
if(!directory.mkdirs())
{
Log.d("CAMERA", "Unable to create directory to save photos.");
return;
}
}
File file = new File(directory.getPath() + file.separator + "IMG_" + SimpleDateFormat.getDateTimeInstance().toString() + ".jpg");
FileOutputStream fos = new FileOutputStream(file);
fos.write(data);
fos.close();
ExifInterface exif = new ExifInterface(file.getCanonicalPath());
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
int rotate = 0;
switch (orientation)
{
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
case default:
break;
}
}
};
Ответы
Ответ 1
SO, перед вами стоит проблема с ориентацией камеры.
В этой ссылке показано пример приложения простой активности захвата камеры:
http://labs.makemachine.net/2010/03/simple-android-photo-capture/
Возможно, вам стоит попробовать установить ориентацию, сделав что-то вроде этого:
ExifInterface exif = new ExifInterface(_path);
int exifOrientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
int rotate = 0;
switch (exifOrientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
}
if (rotate != 0) {
int w = bitmap.getWidth();
int h = bitmap.getHeight();
// Setting pre rotate
Matrix mtx = new Matrix();
mtx.preRotate(rotate);
// Rotating Bitmap & convert to ARGB_8888, required by tess
bitmap = Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, false);
bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
}
Ответ 2
Вам нужно будет прочитать метаданные из исходного JPEG, чтобы проверить ориентацию, в которой был сделан снимок.
ExifInterface exif = new ExifInterface(SourceFileName);
String exifOrientation = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
Источник: Как определить ориентацию изображения без ExifInterface?
Изменить. Отвечая на ваше редактирование, вы пытались использовать метод getCameraInfo(), который доступен с объектом Camera, переданным в обратном вызове? Имеет ли он информацию, которую вы требуете?
Источник: http://developer.android.com/reference/android/hardware/Camera.html
Ответ 3
Удаление setRequestedOrientation()
разрешено getWindowManager().getDefaultDisplay().getRotation()
для правильного вращения. Я предполагаю, что установка запрашиваемой ориентации предотвращает перерисовку активности при изменении конфигурации, поэтому устройство не знает, что какой-либо поворот изменился. Моя единственная проблема сейчас - переход из ландшафтного режима с ориентацией 0 градусов в альбомный режим. На 180 градусов вращение не срабатывает:
@Override
public void onConfigurationChanged(Configuration newconfig)
{
super.onConfigurationChanged(newconfig);
}
Ответ 4
public void surfaceCreated(SurfaceHolder holder) {
try {
mCamera.setPreviewDisplay(holder);
Camera.Parameters parameters = mCamera.getParameters();
if (this.getResources().getConfiguration().orientation !=
Configuration.ORIENTATION_LANDSCAPE)
{
parameters.set("orientation", "portrait"); <----THis gets the job done!!!
// For Android Version 2.2 and above
mCamera.setDisplayOrientation(90);
// For Android Version 2.0 and above
parameters.setRotation(90);
}
// End Effects for Android Version 2.0 and higher
mCamera.setParameters(parameters);
}
catch (IOException exception)
{
mCamera.release();
}
}