图像方向 - Android

Ric*_*ard 7 java android exif image bitmap

在过去一个月左右的时间里,我一直在努力解决这个问题.每当我认为我已经修复它似乎以某种形式回来.

这是旧的Android"图像旋转90度"的错误.我已经在这里阅读了无数的帖子(StackOverFlow)以及尝试了很多方法,但似乎无法修复它.

我仍然得到错误旋转的图像.

在我的应用程序中,用户选择他/她的个人资料图片,然后将其设置为ImageView.图像选自Phones Gallery

两天前,我实施了以下代码,这适用于我在手机上测试的所有图像.然而,当我的一位Beta测试者试用它时,他的图像再次被旋转.他把图像发给我测试,但他们在我的手机上显示正常.因此,为什么我越来越沮丧.

这是我用来获取图像方向的方法:

// Gets an Images Orientation
public static int getOrientationEXIF(Context context, Uri uri) {

    int orientation = 0;

    try {

        ExifInterface exif = new ExifInterface(uri.getPath());

        orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);

        switch (orientation) {

            case ExifInterface.ORIENTATION_ROTATE_90:
                orientation = 90;
                return orientation;

            case ExifInterface.ORIENTATION_ROTATE_180:
                orientation = 180;
                return orientation;

        }

    } catch (IOException e) {
        e.printStackTrace();
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

然后我使用此方法获得旋转的位图:

// Rotate a Bitmap
public static Bitmap rotate(float rotationValue, String filePath) {
    Bitmap original= BitmapFactory.decodeFile(filePath);

    int width = original.getWidth();

    int height = original.getHeight();

    Matrix matrix = new Matrix();

    matrix.postRotate(rotationValue);

    Bitmap rotated = Bitmap.createBitmap(original, 0, 0, width, height, matrix, true);

    return rotated;
}
Run Code Online (Sandbox Code Playgroud)

我不知道该怎么做了.

如果有人能帮助我解决这个问题,我真的很喜欢

先感谢您


UPDATE

我在实现建议的方法后,在我的日志中看到了以下代码行:

JHEAD can't open 'file:/external/images/media/3885'
Run Code Online (Sandbox Code Playgroud)

我不确定这意味着什么


更新#2

我想我可能已经修复了问题,我得到了文件的正确图像路径.

kan*_*idj 5

您需要考虑所有方向,而不仅仅是90或180。我正在使用

    File curFile = new File("path-to-file"); // ... This is an image file from my device.
    Bitmap rotatedBitmap;

            try {
                ExifInterface exif = new ExifInterface(curFile.getPath());
                int rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
                int rotationInDegrees = exifToDegrees(rotation);
                Matrix matrix = new Matrix();
                if (rotation != 0f) {matrix.preRotate(rotationInDegrees);}
                rotatedBitmap = Bitmap.createBitmap(bitmap,0,0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);


            }catch(IOException ex){
                Log.e(TAG, "Failed to get Exif data", ex);
            }
Run Code Online (Sandbox Code Playgroud)

和:

 /**
 * Gets the Amount of Degress of rotation using the exif integer to determine how much
 * we should rotate the image.
 * @param exifOrientation - the Exif data for Image Orientation
 * @return - how much to rotate in degress
 */
private static int exifToDegrees(int exifOrientation) {
    if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) { return 90; }
    else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) {  return 180; }
    else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) {  return 270; }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)


A.S*_*.SD 5

这个问题真糟糕!我注意到这是选择照片而不是拍摄照片时的问题。我发现该裁剪库的代码中隐藏了答案,它似乎在裁剪时始终正确显示 https://github.com/jdamcd/android-crop的内容(尽管此后有时返回错误方向的内容)。无论如何,首先以我在此答案中选择的方式选择照片作为开始: 从片段中选择图像总是在某些设备中返回resultcode 0

接下来,您需要这样做:

private void setRotationVariables(Uri uri)
{
   m_rotationInDegrees = ImageOrientationUtil.getExifRotation(ImageOrientationUtil
        .getFromMediaUri(
            this,
            getContentResolver(),
            uri));
}
Run Code Online (Sandbox Code Playgroud)

这是课程:

import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.provider.MediaStore;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import java.io.Closeable;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;


public class ImageOrientationUtil
{

private static final String SCHEME_FILE = "file";
private static final String SCHEME_CONTENT = "content";

public static void closeSilently(@Nullable Closeable c) {
    if (c == null) return;
    try {
        c.close();
    } catch (Throwable t) {
        // Do nothing
    }
}

public static int getExifRotation(File imageFile) {
    if (imageFile == null) return 0;
    try {
        ExifInterface exif = new ExifInterface(imageFile.getAbsolutePath());
        // We only recognize a subset of orientation tag values
        switch (exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED)) {
            case ExifInterface.ORIENTATION_ROTATE_90:
                return 90;
            case ExifInterface.ORIENTATION_ROTATE_180:
                return 180;
            case ExifInterface.ORIENTATION_ROTATE_270:
                return 270;
            default:
                return ExifInterface.ORIENTATION_UNDEFINED;
        }
    } catch (IOException e) {
      //  Log.e("Error getting Exif data", e);
        return 0;
    }
}

@Nullable
public static File getFromMediaUri(Context context, ContentResolver resolver, Uri uri) {
    if (uri == null) return null;

    if (SCHEME_FILE.equals(uri.getScheme())) {
        return new File(uri.getPath());
    } else if (SCHEME_CONTENT.equals(uri.getScheme())) {
        final String[] filePathColumn = { MediaStore.MediaColumns.DATA, MediaStore.MediaColumns.DISPLAY_NAME };
        Cursor cursor = null;
        try {
            cursor = resolver.query(uri, filePathColumn, null, null, null);
            if (cursor != null && cursor.moveToFirst()) {
                final int columnIndex = (uri.toString().startsWith("content://com.google.android.gallery3d")) ?
                    cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME) :
                    cursor.getColumnIndex(MediaStore.MediaColumns.DATA);
                // Picasa images on API 13+
                if (columnIndex != -1) {
                    String filePath = cursor.getString(columnIndex);
                    if (!TextUtils.isEmpty(filePath)) {
                        return new File(filePath);
                    }
                }
            }
        } catch (IllegalArgumentException e) {
            // Google Drive images
            return getFromMediaUriPfd(context, resolver, uri);
        } catch (SecurityException ignored) {
            // Nothing we can do
        } finally {
            if (cursor != null) cursor.close();
        }
    }
    return null;
}

private static String getTempFilename(Context context) throws IOException {
    File outputDir = context.getCacheDir();
    File outputFile = File.createTempFile("image", "tmp", outputDir);
    return outputFile.getAbsolutePath();
}

@Nullable
private static File getFromMediaUriPfd(Context context, ContentResolver resolver, Uri uri) {
    if (uri == null) return null;

    FileInputStream input = null;
    FileOutputStream output = null;
    try {
        ParcelFileDescriptor pfd = resolver.openFileDescriptor(uri, "r");
        FileDescriptor fd = pfd.getFileDescriptor();
        input = new FileInputStream(fd);

        String tempFilename = getTempFilename(context);
        output = new FileOutputStream(tempFilename);

        int read;
        byte[] bytes = new byte[4096];
        while ((read = input.read(bytes)) != -1) {
            output.write(bytes, 0, read);
        }
        return new File(tempFilename);
    } catch (IOException ignored) {
        // Nothing we can do
    } finally {
        closeSilently(input);
        closeSilently(output);
    }
    return null;
}
Run Code Online (Sandbox Code Playgroud)

}