【问题标题】:Java validate image headerJava验证图像头
【发布时间】:2013-03-10 16:22:40
【问题描述】:

我有一个要求,我需要不是通过文件扩展名而是通过验证标题来识别图像的类型。我正在尝试通过幻数验证来验证 JPEG 文件。

File imgFile =
   new File("C:\\Users\\Public\\Pictures\\Sample Pictures\\Chrysanthemum.jpg");
byte[] ba = Files.toByteArray(imgFile); //Its a google guava library
int i = 0; 
if(ba [i] == 0xFF && ba[i+1] == 0xD8 && ba[i+2] == 0xFF && ba[i+3] == 0xE0){
   System.out.println("isJPEG");
}

但条件根本没有得到满足。 ba[i] 返回-1

我做错了什么?

【问题讨论】:

标签: java image bytearray


【解决方案1】:

在 Java 中,byte 原语是有符号的,其范围从 -128 到 127,这意味着您的 ba[0] 输出为 -1,而 0xFF 被解释为 int 为 255。如果您使用& 运算符对0xFF 进行按位与运算,这会将有符号字节转换为正确的值,您的代码将正常工作,如下所示:

    File imgFile =
           new File("C:\\Users\\Public\\Pictures\\Sample Pictures\\Chrysanthemum.jpg");
        byte[] ba = Files.toByteArray(imgFile); //Its a google guava library
        int i = 0; 
        if((ba [i] & 0xFF) == 0xFF && (ba[i+1] & 0xFF) == 0xD8 && (ba[i+2] & 0xFF) == 0xFF 
           && (ba[i+3] & 0xFF) == 0xE0) {
           System.out.println("isJPEG");
        }

我不确定您使用的确切逻辑,因为维基百科指出 JPEG 的幻数如下:

JPEG 图像文件以 FF D8 开头并以 FF D9 结尾

FF E0 是 JFIF 特定的,因此您可能需要仔细检查为什么要检查此内容

以下是用于根据 Wikipedia 进行检查的代码:

        File imgFile =                 
                    new File("C:\\Users\\Public\\Pictures\\Sample Pictures\\Chrysanthemum.jpg");
        byte[] ba = Files.toByteArray(imgFile); //Its a google guava library
        int i = 0; 
        if((ba [i] & 0xFF) == 0xFF && (ba[i+1] & 0xFF) == 0xD8 && (ba[ba.length - 2] & 0xFF) == 0xFF 
           && (ba[ba.length - 1] & 0xFF) == 0xD9) {
           System.out.println("isJPEG");
        }

【讨论】:

  • 谢谢。它成功了。我想我需要更多地研究按位操作。
  • 不客气。 Java 中的所有原始数字数据类型都以二进制补码表示法进行签名和表示,请参见此处:en.wikipedia.org/wiki/Two's_complement。您会注意到,在二进制补码中表示时,无符号 255 为 -1
猜你喜欢
  • 2014-09-30
  • 2015-03-02
  • 2013-07-30
  • 1970-01-01
  • 2022-01-22
  • 1970-01-01
  • 1970-01-01
  • 2011-12-28
  • 2012-10-12
相关资源
最近更新 更多