2010-11-18 4 views
2

Ich möchte den Inhalt eines Verzeichnisses, das beliebige Dateien (ein typisches "Downloads" -Verzeichnis) enthält, ermitteln und programmgesteuert bestimmen, ob es sich bei einer bestimmten Datei um ein Bild eines beliebigen Typs handelt.Wie kann ich feststellen, ob eine Datei ein Bild auf der JVM ist?

Ich arbeite in Clojure, aber alles auf der JVM ist faires Spiel.

Vielen Dank im Voraus!

+1

Hier ist ein nützlicher Link: http://webcache.googleusercontent.com/search?q=cache:2Gkd-GcGI5AJ:forums.sun.com/thread.jspa%3FthreadID%3D5398376 + java + bestimmen + wenn + a + file + ist + ein + bild & cd = 1 & hl = sv & ct = clnk & gl = se & client = firefox-a –

Antwort

2

Ended in der Lage, dies zu lösen, indem Sie den Kommentar zu Ihrer Frage zusammen mit meiner früheren Antwort von here kombinieren. Kleinere Änderungen am Code lassen ihn mit Bildern arbeiten, die keine Bilder sind.

Ich habe es nicht geändert, um in Unterverzeichnisse zu recurse. Wäre einfach genug zu tun.

(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]) 

Nach einem wenig darüber nachzudenken fühlt es schmutzig die Prüfung für eine Datei mit dem Herausziehen die Breite und Höhe, um ein Bild zu kombinieren. Alternativ könnten Sie eine Funktion definieren, die diese Filterung separat durchführt und Ihnen eine Folge von Bildern gibt.

(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 [email protected]: type = 5 ColorModel: #pixelBits = 24 numComponents = 3 color space = java.awt.color.ICC_Color\ 
[email protected] transparency = 1 has alpha = false isAlphaPre = false ByteInterleavedRaster: width = 32 height = 32 #numDataElements 3 \ 
dataOff[0] = 2> 

]

+0

Große Antwort. Sobald ich mit dem Code herumspiele, werde ich wahrscheinlich Danke, danke. –

2

Offensichtlich ist die einfachste Sache, die Dateinamenerweiterung zu sehen. Natürlich ist es nicht unbedingt zuverlässig, aber es kann unter Umständen ausreichen.

Kurz das ganze Bild zu lesen, könnten Sie die ersten paar Bytes der Datei lesen, um es durch seine "magische Zahl" zu identifizieren. Zum Beispiel beginnen JPEG-Dateien immer mit den zwei Bytes 0xFFD8 und enden mit 0xFFD9; PDFs beginnen immer mit der Zeichenkette "% PDF".

Dies erspart Ihnen den Aufwand beim Erstellen eines Abbilds im Speicher und beschleunigt möglicherweise auch Ihre E/A (da Sie nur wenige Byte der Datei benötigen).

Wenn Sie nicht alle diese magischen Zahlen selbst erforschen möchten, können Sie eine Bibliothek wie jMimeMagic versuchen. Ich habe es nie benutzt, daher kann ich nicht für seine Qualität oder Vollständigkeit bürgen, aber es ist LGPL. Ich bin sicher, dass Sie auch andere Alternativen finden können.

+0

tika library hat mehr passende lizenz ;-) –

+0

Ich würde nicht sagen, welche Lizenz am meisten ist geeignet für jemand anderes Projekt, aber Tika sieht wie eine robuste und gut entwickelte Bibliothek aus. Danke für den Vorschlag. – eaj

+0

das ist sehr einfach, nur tun (verwenden 'Tika) (Detect-Mime-Typ-Datei), aber anstelle der Datei können Sie Zeichenfolge, URL oder InputStream verwenden –

2

Sie können die Tika library verwenden, die in der Lage ist, viele Dateitypen zu erkennen und auch Metadaten aus vielen von ihnen zu extrahieren. Ich habe sehr einfach Clojure wrapper dafür

+0

Würde es Ihnen etwas ausmachen, einige Beispiel-Code für die Wirkung von '(Filter ist -image (file-seq "dir") "? Ich denke, das ist, wie ich will, dass ich funktioniere, das auf dem Verzeichnis funktioniert. –

Verwandte Themen