gpt4 book ai didi

java - 从图片回调中读取 android jpeg EXIF 元数据

转载 作者:IT老高 更新时间:2023-10-28 21:00:26 27 4
gpt4 key购买 nike

背景:我正在为信使程序编写相机应用程序。我无法随时将捕获的图像保存到永久磁盘。相机必须支持所有方向。我的实现是熟悉的 Surfaceview 示例。我使用 Display 类来检测方向并相应地旋转相机。在 takePicture jpeg 回调中,我从 byte[] 构造了一个位图,以解决我遇到的一些纵横比问题:Camera API: Cross device issues

问题描述:在某些设备上,在 ROTATION_270(设备顺时针旋转 90 度)拍摄的构造位图颠倒了。到目前为止,它似乎是三星。我只能假设相机可能是以其他方式焊接的,或者有什么影响,但这既不存在也不存在。虽然我可以检查位图是否横向,但我无法从逻辑上检查它是否按维度倒置,因此我需要访问 EXIF 数据。

Android 为这个 http://developer.android.com/reference/android/media/ExifInterface.html 提供了一个解析器。但不幸的是,它有一个接受文件的构造函数......我没有也不想要。直观地说,我可以为字节数组编写一个构造函数,但考虑到他们调用 native 代码http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.2.1_r1/android/media/ExifInterface.java,这似乎真的很痛苦。

我的问题分为两部分:

  1. 有谁知道 byte[] 数组是否包含完整的 EXIF jpeg header 数据原样或通过 BitmapFactory.decode(...)/的路径BitmapFactory.compress(...) 以某种方式添加?

  2. 如果此 EXIF 数据存在于字节数组中,我该如何解析 以可靠的方式提供方向信息?

编辑 2012 年 10 月 18 日

pcans 下面的回答涉及我问题的第 2 部分。正如我在他的回答下面的评论中指出的那样,如果您想使用该解析器,您必须将源代码合并到您的项目中。该链接的 SO 帖子中提到的更改已在此处进行并重新发布: https://github.com/strangecargo/metadata-extractor

NOTE newer versions of metadata-extractor work directly on Android without modification, and are available via Maven.

但是,对于第 1 部分,当我使用从 takePicture 获得的字节数组运行它时,我从解析器返回 0 个标签。我开始担心字节数组没有我需要的数据。我将继续对此进行研究,但欢迎任何进一步的见解。

最佳答案

使用Camera.takePicture()2.9.1版从图像byte[](对metadata extraction library in Java有用)读取元数据/EXIF由 Drew Noakes :

try
{
// Extract metadata.
Metadata metadata = ImageMetadataReader.readMetadata(new BufferedInputStream(new ByteArrayInputStream(imageData)), imageData.length);

// Log each directory.
for(Directory directory : metadata.getDirectories())
{
Log.d("LOG", "Directory: " + directory.getName());

// Log all errors.
for(String error : directory.getErrors())
{
Log.d("LOG", "> error: " + error);
}

// Log all tags.
for(Tag tag : directory.getTags())
{
Log.d("LOG", "> tag: " + tag.getTagName() + " = " + tag.getDescription());
}
}
}
catch(Exception e)
{
// TODO: handle exception
}

要读取图像的 EXIF 方向(不是缩略图的方向):

try
{
// Get the EXIF orientation.
final ExifIFD0Directory exifIFD0Directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
if(exifIFD0Directory.containsTag(ExifIFD0Directory.TAG_ORIENTATION))
{
final int exifOrientation = exifIFD0Directory.getInt(ExifIFD0Directory.TAG_ORIENTATION);

/* Work on exifOrientation */
}
else
{
/* Not found */
}
}
catch(Exception e)
{
// TODO: handle exception
}

方向是从 1 到 8。见 here , here , herehere .


根据 EXIF 方向转换位图:

try
{
final Matrix bitmapMatrix = new Matrix();
switch(exifOrientation)
{
case 1: break; // top left
case 2: bitmapMatrix.postScale(-1, 1); break; // top right
case 3: bitmapMatrix.postRotate(180); break; // bottom right
case 4: bitmapMatrix.postRotate(180); bitmapMatrix.postScale(-1, 1); break; // bottom left
case 5: bitmapMatrix.postRotate(90); bitmapMatrix.postScale(-1, 1); break; // left top
case 6: bitmapMatrix.postRotate(90); break; // right top
case 7: bitmapMatrix.postRotate(270); bitmapMatrix.postScale(-1, 1); break; // right bottom
case 8: bitmapMatrix.postRotate(270); break; // left bottom
default: break; // Unknown
}

// Create new bitmap.
final Bitmap transformedBitmap = Bitmap.createBitmap(imageBitmap, 0, 0, imageBitmap.getWidth(), imageBitmap.getHeight(), bitmapMatrix, false);
}
catch(Exception e)
{
// TODO: handle exception
}

关于java - 从图片回调中读取 android jpeg EXIF 元数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12944123/

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