2010-11-12 16 views
22

In meiner Webanwendung habe ich ein Bild-Upload-Modul. Ich möchte die hochgeladene Datei überprüfen, ob es sich um eine Bilddatei oder eine andere Datei handelt. Ich verwende Java auf Serverseite. Ich schreibe es mit ImageIO.write()Wie überprüft man eine hochgeladene Datei, ob es ein Bild oder eine andere Datei ist?

auf der Festplatte

Das Bild wird als BufferedImage in Java lesen und dann Wie soll ich die BufferedImage überprüfen, ob es wirklich ein Bild oder etwas anderes?

Alle Vorschläge oder Links würden geschätzt werden.

+0

Ihre beste Wette auf der Dateierweiterung zu sehen ist, gibt es keine 100% Methode, um festzustellen, ob eine Datei ein Bild oder nicht. –

Antwort

85

Ich nehme an, dass Sie dies in einem Servlet-Kontext ausführen. Wenn es erschwinglich ist, den Inhaltstyp nur anhand der Dateierweiterung zu überprüfen, verwenden Sie ServletContext#getMimeType(), um den Mime-Typ (Inhaltstyp) abzurufen. Überprüfen Sie einfach, ob es mit image/ beginnt.

String fileName = uploadedFile.getFileName(); 
String mimeType = getServletContext().getMimeType(fileName); 
if (mimeType.startsWith("image/")) { 
    // It's an image. 
} 

Die Standard-Mime-Typen sind in den web.xml des servletcontainer in Frage definiertem. In zum Beispiel Tomcat, ist es in /conf/web.xml. Sie können es in der /WEB-INF/web.xml Ihrer Webapp erweitern/verändern wie folgt:

<mime-mapping> 
    <extension>svg</extension> 
    <mime-type>image/svg+xml</mime-type> 
</mime-mapping> 

Aber das ist nicht verhindern, dass Benutzer, die Sie täuschen durch die Dateierweiterung ändern. Wenn Sie dies ebenfalls abdecken möchten, können Sie den MIME-Typ auch anhand des Dateiinhalts actual ermitteln. Wenn es erschwinglich ist, nur nach BMP-, GIF-, JPG- oder PNG-Typen zu suchen (aber nicht nach TIF, PSD, SVG usw.), können Sie es einfach direkt an ImageIO#read() senden und prüfen, ob es keine Ausnahme auslöst.

try (InputStream input = uploadedFile.getInputStream()) { 
    try { 
     ImageIO.read(input).toString(); 
     // It's an image (only BMP, GIF, JPG and PNG are recognized). 
    } catch (Exception e) { 
     // It's not an image. 
    } 
} 

Aber wenn Sie möchten, dass auch mehr Bildtypen abzudecken, dann sollten Sie eine 3rd-Party-Bibliothek, die die ganze Arbeit durch die file headers Sniffing. Zum Beispiel JMimeMagic oder Apache Tika, die sowohl BMP, GIF, JPG, PNG, TIF und PSD (aber nicht SVG) unterstützen. Apache Batik unterstützt SVG. Im Folgenden Beispiel wird JMimeMagic:

try (InputStream input = uploadedFile.getInputStream()) { 
    String mimeType = Magic.getMagicMatch(input, false).getMimeType(); 
    if (mimeType.startsWith("image/")) { 
     // It's an image. 
    } else { 
     // It's not an image. 
    } 
} 

Sie könnten bei Bedarf Gebrauch Kombinationen und die eine und andere aufwiegen.

Das heißt, Sie brauchen nicht unbedingt ImageIO#write(), um das hochgeladene Image auf der Festplatte zu speichern. Gerade die erhaltene InputStream direkt an einen Path oder jede OutputStream wie FileOutputStream die übliche Java IO Art und Weise mehr als ausreichend ist (siehe auch Recommended way to save uploaded files in a servlet application) schreiben:

try (InputStream input = uploadedFile.getInputStream()) { 
    Files.copy(input, new File(uploadFolder, fileName).toPath()); 
} 

Es sei denn, Sie einige Bildinformationen wie seine Dimensionen möchten sammeln und/oder möchte es manipulieren (zuschneiden/Größe ändern/drehen/konvertieren/etc) natürlich.

+2

Sehr umfassende Antwort, die alle Aspekte abdeckt. Gute Arbeit ... – Cahit

+0

Ich habe versucht ImageIO.read (input); Es wird jedoch keine Ausnahme ausgelöst, wenn die Datei kein Bild ist. –

+3

ImageIO.read (Eingabe); Es wird keine Ausnahme ausgelöst, wenn die Datei kein Bild ist. Stattdessen wird null zurückgegeben. –

2

Ich verwendete org.apache.commons.imaging.Imaging in meinem Fall. Unten ist ein Beispielcode, um zu überprüfen, ob ein Bild ein JPEG-Bild ist oder nicht. Wenn die hochgeladene Datei kein Bild ist, wird ImageReadException ausgelöst.

try { 
     //image is InputStream 
     byte[] byteArray = IOUtils.toByteArray(image); 
     ImageFormat mimeType = Imaging.guessFormat(byteArray); 
     if (mimeType == ImageFormats.JPEG) { 
      return; 
     } else { 
      // handle image of different format. Ex: PNG 
     } 
    } catch (ImageReadException e) { 
     //not an image 
    } 
+1

Still - ab Juni 2017 hat die lib keine stabile Version und nur Schnappschüsse. Könnte riskant sein, in prod zu verwenden – George

1

Dies in das JDK gebaut und erfordert lediglich einen Strom mit Unterstützung für

byte[] data = ; 
InputStream is = new BufferedInputStream(new ByteArrayInputStream(data)); 
String mimeType = URLConnection.guessContentTypeFromStream(is); 
//...close stream 
Verwandte Themen