カメラを使用して写真を撮るアプリケーションを構築しています。これを行うためのソースコードを次に示します。
_ File file = new File(Environment.getExternalStorageDirectory(),
imageFileName);
imageFilePath = file.getPath();
Intent intent = new Intent("Android.media.action.IMAGE_CAPTURE");
//Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
startActivityForResult(intent, ACTIVITY_NATIVE_CAMERA_AQUIRE);
_
onActivityResult()
メソッドでは、BitmapFactory.decodeStream()
を使用して画像をピックアップします。
Nexus 1でアプリケーションを実行すると、うまく動作します。しかし、Samsung Galaxy SまたはHTC Inspire 4Gで実行すると、画像の方向が正しくありません。
撮影後の画像プレビュー--------- SDカード上の実際の画像
撮影後の画像プレビュー--------- SDカード上の実際の画像
この周辺には、類似したトピックや問題がかなりあります。あなたはあなた自身のカメラを書いていないので、私はそれがこれに要約されると思う:
保存する前に画像を回転させるデバイスもあれば、写真のexifデータに方向タグを追加するだけのデバイスもあります。
写真のexifデータを確認して、特に
ExifInterface exif = new ExifInterface(SourceFileName); //Since API Level 5
String exifOrientation = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
写真がアプリで正しく表示されているため、問題の場所はわかりませんが、これで間違いなく正しい道に進むはずです!
私はちょうど同じ問題に遭遇し、これを使用して方向を修正しました:
public void fixOrientation() {
if (mBitmap.getWidth() > mBitmap.getHeight()) {
Matrix matrix = new Matrix();
matrix.postRotate(90);
mBitmap = Bitmap.createBitmap(mBitmap , 0, 0, mBitmap.getWidth(), mBitmap.getHeight(), matrix, true);
}
}
ビットマップの幅が高さよりも大きい場合、返される画像は横向きなので、90度回転します。
この問題が他の人に役立つことを願っています。
必要なものは2つあります。
カメラのプレビューは回転と同じである必要があります。 camera.setDisplayOrientation(result);
で設定します
カメラのプレビューとしてキャプチャした画像を保存します。これはCamera.Parameters
で行います。
int mRotation = getCameraDisplayOrientation();
Camera.Parameters parameters = camera.getParameters();
parameters.setRotation(mRotation); //set rotation to save the picture
camera.setDisplayOrientation(result); //set the rotation for preview camera
camera.setParameters(parameters);
お役に立てば幸いです。
int rotate = 0;
try {
File imageFile = new File(sourcepath);
ExifInterface exif = new ExifInterface(
imageFile.getAbsolutePath());
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
}
} catch (Exception e) {
e.printStackTrace();
}
Matrix matrix = new Matrix();
matrix.postRotate(rotate);
bitmap = Bitmap.createBitmap(bitmap , 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
別のオプションは、結果画面のビットマップを次のように回転させることです。
ImageView img=(ImageView)findViewById(R.id.ImageView01);
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.refresh);
// Getting width & height of the given image.
int w = bmp.getWidth();
int h = bmp.getHeight();
// Setting post rotate to 90
Matrix mtx = new Matrix();
mtx.postRotate(90);
// Rotating Bitmap
Bitmap rotatedBMP = Bitmap.createBitmap(bmp, 0, 0, w, h, mtx, true);
BitmapDrawable bmd = new BitmapDrawable(rotatedBMP);
img.setImageDrawable(bmd);
一部のデバイスでもこのタイプの同じ問題があります。
private void rotateImage(final String path) {
Bitmap scaledBitmap = Bitmap.createScaledBitmap(Conasants.bm1, 1000,
700, true);
Bitmap rotatedBitmap = null;
try {
ExifInterface ei = new ExifInterface(path);
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
Matrix matrix = new Matrix();
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
matrix.postRotate(90);
rotatedBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,
scaledBitmap.getWidth(), scaledBitmap.getHeight(),
matrix, true);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
matrix.postRotate(180);
rotatedBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,
scaledBitmap.getWidth(), scaledBitmap.getHeight(),
matrix, true);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
matrix.postRotate(270);
rotatedBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,
scaledBitmap.getWidth(), scaledBitmap.getHeight(),
matrix, true);
break;
default:
rotatedBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,
scaledBitmap.getWidth(), scaledBitmap.getHeight(),
matrix, true);
break;
}
} catch (Throwable e) {
e.printStackTrace();
}
cropImage.setImageBitmap(rotatedBitmap);
rotatedBitmap = null;
Conasants.bm1 = null;
}
写真のexifデータをチェックする必要はもうありません。 Glideで簡単に進みます。
Googleは、Googleが推奨するライブラリとして、Android bumptechが開発したGlideという画像ローダーライブラリを紹介しました。これまで、Google I/O 2014の公式アプリケーションなど、多くのGoogleオープンソースプロジェクトで使用されてきました。
例:Glide.with(context).load(uri).into(imageview);
この方法を試してください:static Uri image_uri; static Bitmap taken_image = null;
image_uri=fileUri; // file where image has been saved
taken_image=BitmapFactory.decodeFile(image_uri.getPath());
try
{
ExifInterface exif = new ExifInterface(image_uri.getPath());
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch(orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
taken_image=decodeScaledBitmapFromSdCard(image_uri.getPath(), 200, 200);
RotateBitmap(taken_image, 90);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
taken_image=decodeScaledBitmapFromSdCard(image_uri.getPath(), 200, 200);
RotateBitmap(taken_image, 180);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
taken_image=decodeScaledBitmapFromSdCard(image_uri.getPath(), 200, 200);
RotateBitmap(taken_image, 270);
break;
case ExifInterface.ORIENTATION_NORMAL:
taken_image=decodeScaledBitmapFromSdCard(image_uri.getPath(), 200, 200);
RotateBitmap(taken_image, 0);
break;
}
}
catch (OutOfMemoryError e)
{
Toast.makeText(getActivity(),e+"\"memory exception occured\"",Toast.LENGTH_LONG).show();
}
public Bitmap RotateBitmap(Bitmap source, float angle) {
Matrix matrix = new Matrix();
matrix.postRotate(angle);
round_Image = source;
round_Image = Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
}
public void setCameraPicOrientation(){
int rotate = 0;
try {
File imageFile = new File(mCurrentPhotoPath);
ExifInterface exif = new ExifInterface(
imageFile.getAbsolutePath());
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
}
} catch (Exception e) {
e.printStackTrace();
}
Matrix matrix = new Matrix();
matrix.postRotate(rotate);
int targetW = 640;
int targetH = 640;
/* Get the size of the image */
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
/* Figure out which way needs to be reduced less */
int scaleFactor = 1;
if ((targetW > 0) || (targetH > 0)) {
scaleFactor = Math.min(photoW/targetW, photoH/targetH);
}
/* Set bitmap options to scale the image decode target */
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
/* Decode the JPEG file into a Bitmap */
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
bitmap= Bitmap.createBitmap(bitmap , 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
/* Associate the Bitmap to the ImageView */
imageView.setImageBitmap(bitmap);
}
これが役立つことを願っています!!ありがとう
ピカソとグライドライブラリを使用した2つの1行ソリューション
画像の回転の問題に対する多くの解決策に多くの時間を費やした後、ようやく2つの簡単な解決策を見つけました。追加の作業を行う必要はありません。 PicassoとGlideは、アプリに含まれる画像を処理するための非常に強力なライブラリです。画像のEXIFデータを読み取り、画像を自動回転します。
グライドライブラリの使用https://github.com/bumptech/glide
Glide.with(this).load("http url or sdcard url").into(imgageView);
Picassoライブラリを使用するhttps://github.com/square/picasso
Picasso.with(context).load("http url or sdcard url").into(imageView);
public static int mOrientation = 1;
OrientationEventListener myOrientationEventListener;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.takephoto);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
myOrientationEventListener
= new OrientationEventListener(getApplicationContext()) {
@Override
public void onOrientationChanged(int o) {
// TODO Auto-generated method stub
if(!isTablet(getApplicationContext()))
{
if(o<=285 && o>=80)
mOrientation = 2;
else
mOrientation = 1;
}
else
{
if(o<=285 && o>=80)
mOrientation = 1;
else
mOrientation = 2;
}
}
};
myOrientationEventListener.enable();
}
public static boolean isTablet(Context context) {
return (context.getResources().getConfiguration().screenLayout
& Configuration.SCREENLAYOUT_SIZE_MASK)
>= Configuration.SCREENLAYOUT_SIZE_LARGE;
}
}
これがお役に立てば幸いです!
SurfaceChangedコールバックでこれを試してください:
Camera.Parameters parameters=mCamera.getParameters();
if(this.getResources().getConfiguration().orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT){
parameters.setRotation(90);
}else{
parameters.setRotation(0);
}
mCamera.setParameters(parameters);
ここで同じ問題が発生するだけで、以下のコードスニペットが機能します。
private static final String[] CONTENT_ORIENTATION = new String[] {
MediaStore.Images.ImageColumns.ORIENTATION
};
static int getExifOrientation(ContentResolver contentResolver, Uri uri) {
Cursor cursor = null;
try {
cursor = contentResolver.query(uri, CONTENT_ORIENTATION, null, null, null);
if (cursor == null || !cursor.moveToFirst()) {
return 0;
}
return cursor.getInt(0);
} catch (RuntimeException ignored) {
// If the orientation column doesn't exist, assume no rotation.
return 0;
} finally {
if (cursor != null) {
cursor.close();
}
}
}
これが役立つことを願って:)