2013-03-21 54 views
5

我有一個要求,我需要確定圖像的類型而不是通過文件擴展名,但通過驗證標頭。我試圖通過幻數驗證來驗證JPEG文件。Java驗證圖像標頭

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 2013-03-21 09:22:46

回答

2

在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具體,所以你米AY要仔細檢查你爲什麼要檢查這個

以下是該代碼使用,使支票按照維基百科:

 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 2013-03-21 09:29:30

+0

不客氣。 Java中的所有基本數字數據類型均以二進制補碼錶示形式進行簽名和表示,請參閱http://en.wikipedia.org/wiki/Two's_complement。您會注意到,當以二進制補碼錶示時,無符號255是-1 – 2013-03-21 09:31:23