2016-04-18 81 views
1

我將圖像存儲在數據庫中作爲Base64編碼的字符串。我想讀取這個字符串,將它解碼爲一個字節數組並顯示它。到現在爲止還挺好。從圖像的字節檢索創建日期

現在我還想顯示關於這張圖片的其他信息。我非常在意何時拍攝/創建該圖像。

我嘗試了幾種方法。當文件系統中存在映像時,沒有問題。但是,當我讀取編碼字符串時,將其解碼爲字節,就會出現問題。我用元數據提取器庫。

<dependency> 
     <groupId>com.drewnoakes</groupId> 
     <artifactId>metadata-extractor</artifactId> 
     <version>2.9.0</version> 
    </dependency> 



public void processData(String data) { 
    if (data == null || data.isEmpty()) { 
     return; 
    } 
    byte[] base64Decoded = DatatypeConverter.parseBase64Binary(data); 
    read(base64Decoded); 
    //displayImage(); 
    //displayImageInfo(); 
} 




public void read(byte [] data) { 
    try { 
     InputStream inputStream = new ByteArrayInputStream(data); 
     BufferedImage image = ImageIO.read(inputStream); 
     retrieveImageInfo(); 

     Metadata metadata = ImageMetadataReader.readMetadata(inputStream); 
     retrieveAdditiaonlInfo2(metadata); 
    } catch (Exception e) { 
     //throw new RuntimeException("Failed to read the image from bytes.", e); 
    } 
} 

private void retrieveImageInfo() { 
    imageWidth = (long) image.getWidth(); 
    imageHeight = (long) image.getHeight(); 
    imageSize = (long) data.length; 

} 

private void retrieveAdditiaonlInfo2(Metadata metadata) { 
    for (Directory directory : metadata.getDirectories()) { 
     for (Tag tag : directory.getTags()) { 
      System.out.format("[%s] - %s = %s", directory.getName(), tag.getTagName(), tag.getDescription()); 
      System.out.println(); 
     } 
     if (directory.hasErrors()) { 
      for (String error : directory.getErrors()) { 
       System.err.format("ERROR: %s", error); 
       System.err.println(); 
      } 
     } 
    } 
} 

這適用於從文件中讀取的圖像。但對於我們的數據庫它不起作用。它說,

引起:java.io.IOException:流結束之前文件的幻數可以確定。 在com.drew.imaging.FileTypeDetector.detectFileType(FileTypeDetector.java:97)

enter image description here

+1

以下的答案可能是你的興趣:如何讓用Java創建日期的圖片](http://stackoverflow.com/questions/83787/how-to-get -date-picture-created-in-java) – uniknow

+0

或者:http://johnbokma.com/java/obtaining-image-metadata.html –

+0

我試過這個庫。 '迭代器閱讀器= ImageIO.getImageReaders(inputStream); \t \t \t而(readers.hasNext()){...}' ** ** hasNext是** **假' –

回答

2

研究和調試後,我發現這一點。 BufferedInputStream是必不可少的!

 File imageFile = new File(filename); 
     Path path = imageFile.toPath(); 
     byte[] data = Files.readAllBytes(path); 

     String str = DatatypeConverter.printBase64Binary(data); 
     //Store encoded data. 
     //Retrieve encoded string from the database. 
     byte [] data2 = DatatypeConverter.parseBase64Binary(str); 

     InputStream inputStream = new ByteArrayInputStream(data2); 
     BufferedInputStream bis = new BufferedInputStream(inputStream); 
     Metadata metadata = ImageMetadataReader.readMetadata(bis); 

因此它的工作!

有一件事,並非所有的圖像包含元數據(我需要日期時間)。 以下是兩個元數據示例。

[JPEG] - Compression Type = Baseline 
[JPEG] - Data Precision = 8 bits 
[JPEG] - Image Height = 758 pixels 
[JPEG] - Image Width = 1024 pixels 
[JPEG] - Number of Components = 3 
[JPEG] - Component 1 = Y component: Quantization table 0, Sampling factors 2 horiz/2 vert 
[JPEG] - Component 2 = Cb component: Quantization table 1, Sampling factors 1 horiz/1 vert 
[JPEG] - Component 3 = Cr component: Quantization table 1, Sampling factors 1 horiz/1 vert 
[JFIF] - Version = 1.1 
[JFIF] - Resolution Units = none 
[JFIF] - X Resolution = 1 dot 
[JFIF] - Y Resolution = 1 dot 
[JFIF] - Thumbnail Width Pixels = 0 
[JFIF] - Thumbnail Height Pixels = 0 

[JPEG] - Compression Type = Baseline 
[JPEG] - Data Precision = 8 bits 
[JPEG] - Image Height = 3104 pixels 
[JPEG] - Image Width = 4192 pixels 
[JPEG] - Number of Components = 3 
[JPEG] - Component 1 = Y component: Quantization table 0, Sampling factors 2 horiz/1 vert 
[JPEG] - Component 2 = Cb component: Quantization table 1, Sampling factors 1 horiz/1 vert 
[JPEG] - Component 3 = Cr component: Quantization table 1, Sampling factors 1 horiz/1 vert 
[Exif IFD0] - Software = Flyme 
[Exif IFD0] - Orientation = Top, left side (Horizontal/normal) 
[Exif IFD0] - Unknown tag (0x0224) = 1 
[Exif IFD0] - Unknown tag (0x0225) = 
[Exif IFD0] - Date/Time = 2016:04:13 10:20:08 
[Exif IFD0] - Model = m1 note       
[Exif IFD0] - Unknown tag (0x0222) = 0 
[Exif IFD0] - Unknown tag (0x0223) = 0 
[Exif IFD0] - Unknown tag (0x0220) = 0 
[Exif IFD0] - Unknown tag (0x0221) = 0 
[Exif IFD0] - Y Resolution = 72 dots per inch 
[Exif IFD0] - X Resolution = 72 dots per inch 
[Exif IFD0] - YCbCr Positioning = Datum point 
[Exif IFD0] - Resolution Unit = Inch 
[Exif IFD0] - Image Description =         
[Exif IFD0] - Make = Meizu       
[GPS] - GPS Img Direction = 49 degrees 
[GPS] - GPS Img Direction Ref = Magnetic direction 
[Exif SubIFD] - Date/Time Digitized = 2016:04:13 10:20:08 
[Exif SubIFD] - Color Space = sRGB 
[Exif SubIFD] - Date/Time Original = 2016:04:13 10:20:08 
[Exif SubIFD] - FlashPix Version = 1.00 
[Exif SubIFD] - Metering Mode = Center weighted average 
[Exif SubIFD] - Exposure Bias Value = 0 EV 
[Exif SubIFD] - Exif Image Height = 3104 pixels 
[Exif SubIFD] - Exif Version = 2.20 
[Exif SubIFD] - Exif Image Width = 4192 pixels 
[Exif SubIFD] - Focal Length = 3.8 mm 
[Exif SubIFD] - Digital Zoom Ratio = 1 
[Exif SubIFD] - White Balance = (Other) 
[Exif SubIFD] - Scene Capture Type = Standard 
[Exif SubIFD] - Flash = Flash did not fire 
[Exif SubIFD] - White Balance Mode = Auto white balance 
[Exif SubIFD] - Exposure Mode = Auto exposure 
[Exif SubIFD] - Exposure Time = 79999/1000000 sec 
[Exif SubIFD] - ISO Speed Ratings = 810 
[Exif SubIFD] - Components Configuration = YCbCr 
[Exif SubIFD] - F-Number = f/2.2 
[Exif SubIFD] - Exposure Program = Unknown (0) 
[Interoperability] - Interoperability Index = Recommended Exif Interoperability Rules (ExifR98) 
[Interoperability] - Interoperability Version = 1.00 
[Exif Thumbnail] - Orientation = Top, left side (Horizontal/normal) 
[Exif Thumbnail] - Compression = JPEG (old-style) 
[Exif Thumbnail] - Thumbnail Offset = 962 bytes 
[Exif Thumbnail] - YCbCr Positioning = Datum point 
[Exif Thumbnail] - Thumbnail Length = 0 bytes 
[Exif Thumbnail] - Y Resolution = 72 dots per inch 
[Exif Thumbnail] - Resolution Unit = Inch 
[Exif Thumbnail] - X Resolution = 72 dots per inch 
+0

的BufferedInputStream的BufferedInputStream =的inputStream的instanceof的BufferedInputStream ? (BufferedInputStream)inputStream :new BufferedInputStream(inputStream);' 'readMetadata'自動調用。令人懷疑這是實際的解決方案。 – Anthony