【问题标题】:Incorrect values from reading image EXIF Orientation on iOS?在 iOS 上读取图像 EXIF 方向的值不正确?
【发布时间】:2014-12-09 23:19:05
【问题描述】:

我正在使用 Exif 信息对从移动相机拍摄的图像进行正确旋转。

在 Android 版本中,可能的值为 1、3、6、8 和 9。

在 iOS 中,我使用相同的代码,但得到了无效值,例如 393216、196608、524288、65536 等。

我不明白为什么会有这样的差异?

【问题讨论】:

  • 从 JPEG 字节读取 EXIF 的方式存在问题。你很可能因为让别人不得不猜测如何帮助你而被否决。可能在您的代码中编辑几行可以解决此问题,但由于没有显示,我只能在下面闲逛..希望它有所帮助。和平。
  • 谢谢你的注意,但问题是我的母语不是英语..也许我有表达问题..抱歉

标签: ios image actionscript-3 air orientation


【解决方案1】:

简答:
对于 iOS,您需要以相反的顺序读取这些字节以获得正确的值。另外,您错误地读取了 24 位(3 个字节)而不是 16 位(2 个字节)。或者,也许您正在提取 2 个字节,但不知何故,您的字节在末尾添加了一个额外的“零”字节??

您可以尝试在 If 语句中使用 OR 检查来检查两个 Endian 类型等效项。既然 Android = 3 会变成 iOS = 768,你可以试试:

if (orient_val == 3 || orient_val == 768) 
{ /* do whatever you do here */ }


PS:1==2562==5123==7684==10245==12806==15367==17928==2048,9==2304

长版:
Android 处理器通常将字节读取为 Little Endian。 Apple 处理器将字节读取为 Big Endian。基本上一种类型是从右到左阅读,另一种是从左到右阅读。其中 AndroidABCDiOS 中变为 DCBA

一些提示:

  • Lil' E 中的 3 为(2 个字节)写为 00+03... 但在 Big E写成03+00
  • 问题是,如果您不适应并只是阅读 03 00 就好像它仍然是 LE,那么您会得到 768
  • 最糟糕的是,不知何故,您将其阅读为03 00 00,这给了您 196608
  • 另一个是 06 00 00 给你 393216 而不是为 1536 阅读 60 00
  • 修复您的代码以在末尾删除额外的 00 字节。

您在 Android 上很幸运,因为我怀疑它需要 4 个字节而不是 2 个字节。所以00 00 06 被读作00 00 00 06,因为x000006x00000006 意思相同=6

无论如何,要正常解决此问题,您只需告诉 AS3 将您的 Jpeg 字节视为 Big Endian,但这现在可以修复 iOS,但随后会在 Android 上破坏它。

一个快速简单的解决方案是检查你得到的数字是否大于 1 位,如果是,那么你假设应用程序在 iOS 上运行并尝试反向排序以查看现在的结果是 1 位数。所以..

注意:代码中显示的选项 B 是有风险的,因为如果你有错误的数字,你会得到错误的结果。你知道电脑..“bad input = bad output; do Next();

import flash.utils.ByteArray;

var Orientation_num:uint = 0;
var jpeg_bytes:ByteArray = new ByteArray(); //holds entire JPEG data as bytes
var bytes_val:ByteArray = new ByteArray(); //holds byte values as needed

Orientation_num = 2048; //Example: Detected big number that should be 8.

if (Orientation_num > 8 ) //since 8 is maximum of orientation types
{
    trace ("Orientation_num is too big : Attempting fix..");

    //## A: CORRECT.. Either read directly from JPEG bytes
    //jpeg_bytes.position = (XX) - 1; //where XX is start of EXIF orientation (2 bytes)
    //bytes_val = jpeg_bytes.readShort(); //extracts the 2 bytes

    //## B: RISKY.. Or use the already detected big number anyway
    bytes_val.writeShort(Orientation_num);

    //Flip the bytes : Make x50 x00 become x00 x50
    var tempNum_ba : ByteArray = new ByteArray(); //temporary number as bytes
    tempNum_ba[0] = bytes_val[1];
    tempNum_ba[1] = bytes_val[0];

    //tempNum_ba.position = 0; //reset pos before checking
    Orientation_num = tempNum_ba.readShort(); //pos also MOVES forward by 2 bytes

    trace ("Orientation_num (FIXED) : " + Orientation_num);
}


【讨论】:

  • 感谢您的回答,但我正在使用此类 Exif Class 以防万一发生任何变化。
  • 昨天我测试了很多次,似乎iOS返回的数字393216、196608、524288、65536是恒定的,所以我做了 if (orient_val == 3 || orient_val == 196608),一切顺利..
  • 但是如果非常好,您仍然可以详细回答.. 谢谢
  • 好的,很高兴它起作用了,但我只是做了一个编辑。无论哪一个对你有用都可以。稍后您仍然可以通过单击中间的 edited 文本来阅读其他答案。
猜你喜欢
  • 2016-04-16
  • 2016-06-02
  • 1970-01-01
  • 2012-01-24
  • 1970-01-01
  • 2017-06-02
  • 2018-12-26
  • 1970-01-01
  • 2020-11-16
相关资源
最近更新 更多