インテント画像キャプチャを呼び出すときに特定の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;
}
}
};
そのため、カメラの向きに問題があります。
このリンクは、単純なカメラキャプチャアクティビティのサンプルアプリを示しています: 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);
}
写真が撮影された方向を確認するには、元のJPEGからメタデータを読み取る必要があります。
ExifInterface exif = new ExifInterface(SourceFileName);
String exifOrientation = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
出典: ExifInterfaceなしで画像の向きを決定する方法は?
編集:編集に答えて、コールバックで渡されたCameraオブジェクトで使用できるgetCameraInfo()メソッドを使用してみましたか?必要な情報はありますか?
出典: http://developer.Android.com/reference/Android/hardware/Camera.html
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();
}
}
setRequestedOrientation()
を削除すると、getWindowManager().getDefaultDisplay().getRotation()
が正しい回転を与えることができました。要求された方向を設定すると、構成が変更されたときにアクティビティがそれ自体を再描画するのを防ぐため、デバイスは変更された回転の種類を認識しません。私の唯一の問題は、0度の向きの横向きモードから横向きモードに切り替えても180度回転してもこれは発生しません。
@Override
public void onConfigurationChanged(Configuration newconfig)
{
super.onConfigurationChanged(newconfig);
}