当前位置: 首页 > 知识库问答 >
问题:

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

公西兴业
2023-03-14

我正在开发一个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="html" target="_blank">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检查代码,但没有用。如前所述,方向总是零,所以我基于链接中的代码得到一个空位图。

共有1个答案

焦正德
2023-03-14

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

使用支持库的exifinterface版本从原始内容中读取EXIF标记。使用getContentResolver().OpenInputStream(imageUri)获取InputStream,并将其传递给exifInterface构造函数。

 类似资料:
  • 在我的应用程序中,图像是从相机捕获的,然后显示在 我已经成功地完成了此方法,但是当我的图像显示在中时,图像显示在旋转后 我想旋转图像,然后在中显示 当我单击前摄像头上的图像时,在下面代码的帮助下,图像显示正确 但当我从后摄像头点击时,图像将显示在前摄像头的对面。还有一件事,当我从不同角度单击“来自摄影机的图像”时,图像将以不同角度显示在中。

  • 我正在构建一个应用程序,它依赖于显示从相机拍摄的许多位图图像。我希望所有图像都以90度(纵向)的方向显示,我知道如何使用每个图像提供的EXIF信息来实现这一点。在拍摄图像后立即旋转图像的位图以满足我的需要,然后将其发送到我的服务器,这对我来说是一个更好的主意,还是应该在不旋转图像的情况下将图像发送到我的服务器,然后每当我下拉图像时,使用图像附带的EXIF旋转来旋转我正在显示的图像视图?我需要一个高

  • 在我们的应用程序中,用户多年来一直在使用以下代码上传数百万张图像: 最近,我们看到需要保存上传图像的数据。问题在于,压缩位图时图像Exif数据丢失。我考虑使用从原始文件中提取此数据: ..然后将其添加到InputStream 中,然后继续上传文件。问题是< code>ExifInterface无法将Exif数据保存到InputStream。 当Exif数据上传到服务器时,如何将它们保留在图像中?

  • 我认为我对保存的UIIimage的路径有一些问题,因为php告诉我该文件已经存在,我认为这是因为我以空白方式发送它

  • 问题内容: 我正在尝试创建一个Rotatable ImageView,我将向其指定特定角度和枢轴点,并查看其围绕该枢轴点旋转。我尝试过这样的事情: 但是postRotate方法的参数(第二个和第三个-枢轴点)完全没有变化。即使它们是0、0,也一样。 所以我想创建一个ImageView,在初始化时将旋转一定角度。在此示例中为45度。我试图设置范围和人员..没有帮助。 我怎么做?:/ 问题答案: 您可

  • 这可能会导致问题,特别是如果有问题的设备依赖于“方向”标签来正确地垂直显示图像。 不同的Android设备以不同的方式处理相机/图像旋转--我信任的旧Nexus One似乎总是在捕获后立即旋转图像,因此文件的原生内容在查看时总是“直立”。 然而,其他设备(尤其是我测试的三星手机)不会旋转图像文件的内容--相反,它们设置了Exif“方向”标签。每当稍后显示图像时,相关的图像代码应该检测到方向“标签”