Я пытаюсь использовать камеру в своем приложении, и я хочу использовать ее в ландшафтном и портретном режимах. Мне не сложно создавать картинки в ландшафтном режиме, но я не нашел хороший способ сохранить фотографии в портретном режиме.Android-камера Сохранение изображений в портретном режиме
Когда я хочу, чтобы сделать снимок в портретном режиме Мне нужно установить displayorientation к портрету первой, как это:
switch (windowManager.getDefaultDisplay().getRotation()) {
case android.view.Surface.ROTATION_0:
mCamera.setDisplayOrientation(90);
break;
case android.view.Surface.ROTATION_90:
mCamera.setDisplayOrientation(0);
break;
case android.view.Surface.ROTATION_180:
mCamera.setDisplayOrientation(270);
break;
case android.view.Surface.ROTATION_270:
mCamera.setDisplayOrientation(180);
break;
}
Но картина все еще сохраняется в ландшафтном режиме. Одно решение, которое я нашел в том, чтобы изменить параметр вращения камеры, как это:
public void onOrientationChanged(int orientation) {
if (orientation == ORIENTATION_UNKNOWN) return;
android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(cameraId, 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;
}
mParameters.setRotation(rotation);
}
Проблема такого подхода заключается в том, что он может просто установить ориентацию в заголовке EXIF и на самом деле не повернуть изображение (которое является с устройством, которое я использую).
Другой подход вращался фактические данные после того, как снимок сделан так:
Bitmap bitmap = BitmapFactory.decodeByteArray(data,0,data.length);
int w = bitmap.getWidth();
int h = bitmap.getHeight();
Matrix mtx = new Matrix();
mtx.postRotate(rotate);
bitmap= Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
currentData = stream.toByteArray();
Но этот подход занимает 10 секунд (что слишком долго), и в то время как я мог бы поставить этот код в AsyncTask, я нужны данные через несколько секунд, поэтому мне все равно придется ждать.
До сих пор я не нашел лучшего решения.
Напишите код NDK для выполнения поворота изображения. – CommonsWare
@CommonsWare Я никогда не использовал NDK, и, когда я его просматривал, было рекомендовано не использовать его, если вы не делаете действительно интенсивный материал, или если вы хорошо знакомы с C/C++ (я их никогда не использовал). И хотя моя проблема связана с производительностью, я чувствую, что должен быть другой (лучший) способ сделать это. Я также опасаюсь, что NDK может испортить некоторые из моих приложений. –
«вы делаете действительно интенсивный материал» - вращение мультимегапиксельного изображения, где вам «нужны данные сразу после», будет квалифицироваться как «действительно интенсивный материал». – CommonsWare