Android 用户上传的图像在 ImageView 中旋转,带有错误的 Exif 数据
Android user-uploaded image rotated in ImageView with false Exif data
我正在开发一个 Android 应用程序,其中部分功能是用户可以 select 来自他们设备的图像,将其与列表中的特定项目相关联,然后使用它在应用程序中。我的意图是将图像本身存储在内部存储器中,并将图像的路径与项目的其余存储信息一起存储在 SQLite 数据库中。
我已经能够让用户访问 select 并对其进行成像并上传,但有时会根据照片的拍摄方式旋转图像。我试过查看 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>
这允许用户 select 图像,将其上传到图像视图(有时旋转),存储图像,并在关闭应用程序后检索图像。轮换是唯一的主要问题,我尝试过的修复没有在这里体现。我在这里引用了太多答案,但它们分为三大类:检查 Exif 标签和使用矩阵旋转 Bitmap,使用光标获取图像信息并旋转,以及使用 Glide。这三个都失败了,我不知道下一步该怎么做。有什么建议吗?
完整代码可见here.
更新
按照要求,我 added Exif 检查代码无济于事。如前所述,方向始终为零,因此我根据 link.
中的代码得到了一个空位图
我不知道 saveImage()
是做什么的。鉴于它接受一个 Bitmap
和 returns 一个 "path",我假设它将 Bitmap
保存到一个文件中。如果是这样,那肯定行不通,因为 Bitmap
没有 EXIF 数据。
使用the support library's edition of ExifInterface
从原始内容中读取EXIF标签。使用 getContentResolver().openInputStream(imageUri)
获取 InputStream
,将其传递给 ExifInterface
构造函数。
我正在开发一个 Android 应用程序,其中部分功能是用户可以 select 来自他们设备的图像,将其与列表中的特定项目相关联,然后使用它在应用程序中。我的意图是将图像本身存储在内部存储器中,并将图像的路径与项目的其余存储信息一起存储在 SQLite 数据库中。
我已经能够让用户访问 select 并对其进行成像并上传,但有时会根据照片的拍摄方式旋转图像。我试过查看 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>
这允许用户 select 图像,将其上传到图像视图(有时旋转),存储图像,并在关闭应用程序后检索图像。轮换是唯一的主要问题,我尝试过的修复没有在这里体现。我在这里引用了太多答案,但它们分为三大类:检查 Exif 标签和使用矩阵旋转 Bitmap,使用光标获取图像信息并旋转,以及使用 Glide。这三个都失败了,我不知道下一步该怎么做。有什么建议吗?
完整代码可见here.
更新
按照要求,我 added Exif 检查代码无济于事。如前所述,方向始终为零,因此我根据 link.
我不知道 saveImage()
是做什么的。鉴于它接受一个 Bitmap
和 returns 一个 "path",我假设它将 Bitmap
保存到一个文件中。如果是这样,那肯定行不通,因为 Bitmap
没有 EXIF 数据。
使用the support library's edition of ExifInterface
从原始内容中读取EXIF标签。使用 getContentResolver().openInputStream(imageUri)
获取 InputStream
,将其传递给 ExifInterface
构造函数。