2013-03-21 2 views
5

У меня есть одно требование, когда мне нужно идентифицировать тип изображения не по расширению файлов, а путем проверки заголовка. Я пытаюсь проверить файл JPEG по проверке магического числа.Java validate image header

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.

Что я делаю неправильно?

+0

Связанный: http://stackoverflow.com/q/1915317/1055089 – Vrushank

ответ

2

В Java byte примитив подписан и имеет диапазон от -128 до 127, а это значит, ваш ba[0] выходит как -1, в то время как 0xFF интерпретируется как межд как 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"); 
     } 

Я не уверен, что о точных логиках, которую вы используете, однако как википедия утверждает, что магические числа для JPEGs следующим образом:

JPEG файлов изображений начинаются с FF D8 и заканчиваться FF D9

FF E0 является JFIF специфический, так что вы м ау хотят перепроверить, почему вы проверяете для этого

Ниже будет код, чтобы использовать для проверки согласно Википедии:

 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"); 
     } 
+0

Спасибо. Это сработало. Наверное, мне нужно больше смотреть на операции. – karthick

+0

Добро пожаловать. Все примитивные числовые типы данных в Java подписаны и представлены в примечании о дополнении Two, см. Здесь: http://en.wikipedia.org/wiki/Two's_complement. Вы заметите, что беззнаковый 255 равен -1, если он представлен в дополнении 2 –