gpt4 book ai didi

Android:从 Uri 获取位图方向

转载 作者:太空狗 更新时间:2023-10-29 14:55:40 25 4
gpt4 key购买 nike

使用以下方法打开图像选择器后:

Intent intent = new Intent(); 
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "choose image", 1);

从选定的 Uri 获取位图的推荐方法是使用以下代码:

InputStream input = cxt.getContentResolver().openInputStream(fileUri);
Bitmap bmp = BitmapFactory.decodeStream(input);

但是这种方法不会自动旋转用相机以人像模式拍摄的图像。

如何仅使用 Uri 获取位图方向? (考虑到 Uri 可能来自 Google Drive 或其他可能无法转化为磁盘上真实文件的位置)

最佳答案

我用这个类:src是选中图片的字符串,bitmap是从图片中提取出来的位图。

public class ExifUtils {
public static Bitmap rotateBitmap(String src, Bitmap bitmap) {
try {
int orientation = getExifOrientation(src);

if (orientation == 1) {
return bitmap;
}

Matrix matrix = new Matrix();
switch (orientation) {
case 2:
matrix.setScale(-1, 1);
break;
case 3:
matrix.setRotate(180);
break;
case 4:
matrix.setRotate(180);
matrix.postScale(-1, 1);
break;
case 5:
matrix.setRotate(90);
matrix.postScale(-1, 1);
break;
case 6:
matrix.setRotate(90);
break;
case 7:
matrix.setRotate(-90);
matrix.postScale(-1, 1);
break;
case 8:
matrix.setRotate(-90);
break;
default:
return bitmap;
}

try {
Bitmap oriented = Bitmap.createBitmap(bitmap, 0, 0,
bitmap.getWidth(), bitmap.getHeight(), matrix, true);
bitmap.recycle();
return oriented;
} catch (OutOfMemoryError e) {
e.printStackTrace();
return bitmap;
}
} catch (IOException e) {
e.printStackTrace();
}

return bitmap;
}

private static int getExifOrientation(String src) throws IOException {
int orientation = 1;

try {
/**
* if your are targeting only api level >= 5 ExifInterface exif =
* new ExifInterface(src); orientation =
* exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
*/
if (Build.VERSION.SDK_INT >= 5) {
Class<?> exifClass = Class
.forName("android.media.ExifInterface");
Constructor<?> exifConstructor = exifClass
.getConstructor(new Class[] { String.class });
Object exifInstance = exifConstructor
.newInstance(new Object[] { src });
Method getAttributeInt = exifClass.getMethod("getAttributeInt",
new Class[] { String.class, int.class });
java.lang.reflect.Field tagOrientationField = exifClass
.getField("TAG_ORIENTATION");
String tagOrientation = (String) tagOrientationField.get(null);
orientation = (Integer) getAttributeInt.invoke(exifInstance,
new Object[] { tagOrientation, 1 });
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}

return orientation;
}
}

在需要上传图片的部分。这是如何使用它:

ExifUtils.rotateBitmap(path, decodeSampledBitmap(file, 400, 400)));

decodeSampledBitmap 是:

    public Bitmap decodeSampledBitmap(File res, int reqWidth, int reqHeight) {
if (res != null) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
try {
FileInputStream stream2 = new FileInputStream(res);

BitmapFactory.decodeStream(stream2, null, options);

stream2.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// Calculate inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
o2.inJustDecodeBounds = false;
FileInputStream stream = null;
try {
stream = new FileInputStream(res);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Bitmap bitmap = BitmapFactory.decodeStream(stream, null, o2);
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
} else
return null;
}

public int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;

if (height > reqHeight || width > reqWidth) {

final int halfHeight = height / 2;
final int halfWidth = width / 2;

// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}

return inSampleSize;
}

如果您要上传位图,还有一种方法可以从位图中检索字节。此方法还压缩了位图大小:

    public byte[] getBytesFromBitmap(Bitmap bitmap) {
if (bitmap != null) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 75, stream);
return stream.toByteArray();
} else
return null;
}

关于Android:从 Uri 获取位图方向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31769438/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com