Как я могу определить, является ли файл изображением на JVM? - PullRequest
2 голосов
/ 18 ноября 2010

Я хотел бы получить содержимое каталога, содержащего произвольные файлы (типичный каталог «Downloads»), и определить программно, является ли данный файл образом любого типа.

Я работаюв Clojure, но все, что доступно на JVM, является честной игрой.

Заранее спасибо!

Ответы [ 3 ]

2 голосов
/ 18 ноября 2010

Вы можете использовать библиотеку Tika , которая способна обнаруживать многие типы файлов, а также извлекать метаданные из многих из них. У меня очень простая Clojure оболочка для нее

2 голосов
/ 22 ноября 2010

Закончилась возможность решить эту проблему, объединив комментарий к вашему вопросу вместе с моим более ранним ответом от здесь . Незначительные изменения в коде позволяют работать с изображениями, которые не являются изображениями.

Я не изменил его, чтобы переходить в подкаталоги. Было бы достаточно легко сделать.

(defn files-in-dir [dir]                                                                                                               
  (filter #(not (.isDirectory %))                                                                                                      
          (.listFiles (java.io.File. dir))))                                                                                           

(defn figure-out-height-width                                                                                                          
  [files]                                                                                                                              
  (remove nil?                                                                                                                         
          (map (fn [file]                                                                                                               
                 (with-open [r (java.io.FileInputStream. file)]                                                                        
                   (if-let [img (javax.imageio.ImageIO/read r)]                                                                        
                     [file (.getWidth img) (.getHeight img)])))                                                                        
               files)))                                                                                                                

user> (pprint (files-in-dir "/home/jmccrary/Downloads/"))                                                                              
(#<File /home/jmccrary/Downloads/Girl_Talk_-_All_Day_(IA123)_mp3s.zip>                                                                 
 #<File /home/jmccrary/Downloads/CSS3-for-Web-Designers.zip>                                                                           
 #<File /home/jmccrary/Downloads/manual.pdf>                                                                                           
 #<File /home/jmccrary/Downloads/test.jpeg>                                                                                            
 #<File /home/jmccrary/Downloads/nautilus-dropbox_0.6.7_amd64.deb>                                                                     
 #<File /home/jmccrary/Downloads/rubygems-1.3.7.tgz>                                                                                   
 #<File /home/jmccrary/Downloads/HTML5-FOR-WEB-DESIGNERS.zip>                                                                          
 #<File /home/jmccrary/Downloads/bcompare-3.1.11.12238.tar.gz>                                                                         
 #<File /home/jmccrary/Downloads/shared_ptr_example.cpp>)                                                                              
nil                                                                                                                                    
user> (figure-out-height-width (files-in-dir "/home/jmccrary/Downloads"))                                                              
([#<File /home/jmccrary/Downloads/test.jpeg> 32 32])

Подумав немного, кажется грязным объединять проверку на наличие файла, представляющего собой изображение, с вытягиванием ширины и высоты. В качестве альтернативы вы можете определить функцию, которая выполняет эту фильтрацию отдельно и выдает последовательность изображений.

(defn filter-images                                                                                                                    
  [files]                                                                                                                              
  (reduce (fn [res file]                                                                                                                
            (if-let [img (javax.imageio.ImageIO/read file)]                                                                            
              (conj res img)                                                                                                           
              res))                                                                                                                    
          []                                                                                                                           
          files))

user> (filter-images (files-in-dir "/home/jmccrary/Downloads"))                                                                        
[#<BufferedImage BufferedImage@24753433: type = 5 ColorModel: #pixelBits = 24 numComponents = 3 color space = java.awt.color.ICC_Color\
Space@43036651 transparency = 1 has alpha = false isAlphaPre = false ByteInterleavedRaster: width = 32 height = 32 #numDataElements 3 \
dataOff[0] = 2>

]

2 голосов
/ 18 ноября 2010

Очевидно, что проще всего взглянуть на расширение имени файла.Конечно, это не обязательно надежно, но в некоторых случаях этого может быть достаточно.

Если не считать всего изображения, вы можете прочитать первые несколько байтов файла, чтобы идентифицировать его по «магическому номеру».Например, файлы JPEG всегда начинаются с двух байтов 0xFFD8 и заканчиваются 0xFFD9;PDF-файлы всегда начинаются со строки «% PDF».

Это экономит ваши накладные расходы на создание изображения в памяти и может также ускорить ваш ввод-вывод (поскольку вам потребуется всего несколько байтов файла).

Если вы не хотите исследовать все эти магические числа самостоятельно, вы можете попробовать библиотеку, такую ​​как jMimeMagic .Я никогда не использовал его, поэтому я не могу поручиться за его качество или полноту, но это LGPL.Я уверен, что вы можете найти и другие альтернативы.

...