Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android用户上传的图像在ImageView中旋转,带有假Exif数据_Android_Image_Sqlite_Exif_Image Rotation - Fatal编程技术网

Android用户上传的图像在ImageView中旋转,带有假Exif数据

Android用户上传的图像在ImageView中旋转,带有假Exif数据,android,image,sqlite,exif,image-rotation,Android,Image,Sqlite,Exif,Image Rotation,我正在开发一个Android应用程序,其中部分功能是用户可以从设备中选择一个图像,将其与列表中的特定项目关联,并在应用程序中使用它。我的意图是将图像本身存储在内部内存中,并将图像的路径与项目的其余存储信息一起存储在SQLite数据库中。 我已经能够让用户选择和图像,并上传它,但图像有时是旋转取决于如何拍摄的照片。我尝试查看Exif数据,但方向始终为零。我尝试使用光标来显示MediaStore.Images.Media.DATA信息,但也没有效果。有关守则的现况如下: @Override prot

我正在开发一个Android应用程序,其中部分功能是用户可以从设备中选择一个图像,将其与列表中的特定项目关联,并在应用程序中使用它。我的意图是将图像本身存储在内部内存中,并将图像的路径与项目的其余存储信息一起存储在SQLite数据库中。 我已经能够让用户选择和图像,并上传它,但图像有时是旋转取决于如何拍摄的照片。我尝试查看Exif数据,但方向始终为零。我尝试使用光标来显示MediaStore.Images.Media.DATA信息,但也没有效果。有关守则的现况如下:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_details);

    mDbHelper = new EntryDbHelper(this);

    Intent intent = getIntent();
    pId = intent.getIntExtra(PhrasesActivity.T_KEY, -1);

    mImageView = (ImageView) findViewById(R.id.details_img);
    mImageView.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
            //Making an intent to Pick an image, looking for an Internal URI
            Intent pickImageIntent = new Intent(Intent.ACTION_GET_CONTENT);
            //Setting the content to images
            pickImageIntent.setType("image/*");
            if(pickImageIntent.resolveActivity(getPackageManager()) != null) {
                startActivityForResult(pickImageIntent, REQUEST_IMAGE_GET);
            }

            return true;
        }
    });

    setText();
    setImage();
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if(requestCode == REQUEST_IMAGE_GET && resultCode == RESULT_OK) {
        Bitmap image = null;
        Uri imageUri = data.getData();

        try {
            image = MediaStore.Images.Media.getBitmap(getContentResolver(), imageUri);
        } catch(FileNotFoundException e) {
            e.printStackTrace();
        } catch(IOException e) {
            e.printStackTrace();
        }

        mImageView.setImageBitmap(image);

        String path = storeImage(image);

        SQLiteDatabase db = mDbHelper.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put(PhraseEntry.COLUMN_URI, path.toString());

        String selection = PhraseEntry._ID + " = ?";
        String[] selectionArgs = {Integer.toString(pId)};

        int count = db.update(PhraseEntry.TABLE_NAME, values, selection, selectionArgs);

        if(count == 1) {
            Toast.makeText(this, "Image Updated Successfully", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(this, "Image Updated UNSUCCESSFULLY", Toast.LENGTH_SHORT).show();
        }
    }
}

private void setImage() {
    SQLiteDatabase db = mDbHelper.getReadableDatabase();

    String[] projection = {
            PhraseEntry.COLUMN_URI
    };

    String selection = PhraseEntry._ID + " = ?";
    String[] selectionArgs = {Integer.toString(pId)};

    Cursor cursor = db.query(PhraseEntry.TABLE_NAME, projection, selection, selectionArgs,
            null, null, null);

    String imagePath = "";

    while(cursor.moveToNext()) {
        imagePath = cursor.getString(
                cursor.getColumnIndexOrThrow(PhraseEntry.COLUMN_URI)
        );
    }

    if(!imagePath.isEmpty()) {

        try {
            File f = new File(imagePath, "phrase_" + Integer.toString(pId));
            Bitmap b = BitmapFactory.decodeStream(new FileInputStream(f));
            mImageView.setImageBitmap(b);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

    }
    else {
        mImageView.setImageResource(R.drawable.sample);
    }
    cursor.close();
}
以下是相关的布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.bladefrisch.discoveringtalk.DetailsActivity">

    <ImageView
        android:id="@+id/details_img"
        style="@style/DetailImage"
        android:contentDescription="Sample"
        android:src="@drawable/sample" />

    <TextView
        android:id="@+id/details_text"
        style="@style/DetailText"
        tools:text="Hello, how are you?" />

</LinearLayout>
这允许用户选择图像,将其上载到图像视图,存储图像,并在关闭应用程序后检索图像。轮换是唯一的主要问题,我尝试过的修复没有反映在这里。我在这里引用了太多的答案,但它们分为三大类:检查Exif标记并使用矩阵旋转位图,使用光标获取图像信息并旋转,以及使用Glide。这三个都失败了,我不知道下一步该怎么办。有什么建议吗? 完整的代码可以找到

更新 按照要求,我已经检查了Exif代码,但没有结果。如前所述,方向始终为零,因此我根据链接中的代码得到一个空位图。

我不知道saveImage做什么。假设它接收位图并返回路径,我假设它正在将位图保存到文件中。如果是这样,那肯定不行,因为位图没有EXIF数据


用于从原始内容读入EXIF标记。使用getContentResolver.openInputStreamimageUri获取InputStream,并将其传递给ExiFinInterface构造函数。

有什么建议吗?-问一个问题,展示[你]尝试过的修复方法之一,并寻求帮助,提供不起作用的具体细节。我们无法帮助您处理无法看到的代码。这里的代码肯定不起作用,因为它不会旋转图像。FWIW演示了检查Exif标记和使用矩阵解决方案旋转位图,以及旋转ImageView。请参阅@Commonware,我添加了以前尝试过的代码,并根据santalu的链接进行了一些小改动。我已经用结果更新了我的问题。这在我的设备SDK 24+上运行得很好,因为在那里添加了接受InputStream的ExiFinInterface构造函数。saveImage实际上是一个自定义函数,它只将图像写入内部存储器并返回数据库的路径。我的主要问题似乎是访问低于24的设备的ExiFinInterface的原始内容。我可以用不同的API和URI来实现这一点,或者我需要采用不同的方法?最低级别的构造函数将文件名作为字符串,但我想我对它与URI的区别感到有点困惑。@BFrisch:这对于我的设备SDK 24+来说效果很好,因为在那里添加了接受InputStream的ExiFinInterface构造函数。-它也在我链接的支持库中,我现在明白了。我没有意识到我必须链接到Gradle文件中的支持库。当我了解到支持库是一个独立的东西时,我的博客文章很有帮助。非常感谢。