In meiner Webanwendung habe ich ein Modul zum Hochladen von Bildern. Ich möchte überprüfen, ob es sich bei der hochgeladenen Datei um eine Bilddatei oder eine andere Datei handelt. Ich verwende Java auf der Serverseite.
Das Bild wird gelesen als BufferedImage
in Java und dann schreibe ich es auf die Festplatte mit ImageIO.write()
Wie soll ich das überprüfen? BufferedImage
, ob es sich wirklich um ein Bild oder etwas anderes handelt?
Alle Vorschläge oder Links wären dankbar.
Ich gehe davon aus, 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) zu erhalten. Überprüfe einfach, ob es mit beginnt image/
.
String fileName = uploadedFile.getFileName();
String mimeType = getServletContext().getMimeType(fileName);
if (mimeType.startsWith("image/")) {
// It's an image.
}
Die Standard-Mime-Typen sind in der web.xml
des betreffenden Servletcontainers. In Tomcat zum Beispiel befindet es sich in /conf/web.xml
. Sie können es im erweitern/überschreiben /WEB-INF/web.xml
Ihrer Webapp wie folgt:
<mime-mapping>
<extension>svg</extension>
<mime-type>image/svg+xml</mime-type>
</mime-mapping>
Dies schützt Sie jedoch nicht vor Benutzern, die Sie durch Ändern der Dateierweiterung täuschen. Wenn Sie dies auch abdecken möchten, können Sie den Mime-Typ auch anhand der tatsächlich Dateiinhalt. 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 . füttern ImageIO#read()
und überprüfen Sie, 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.
}
}
Wenn Sie jedoch auch mehr Bildtypen abdecken möchten, sollten Sie eine Bibliothek von Drittanbietern verwenden, die die gesamte Arbeit durch Schnüffeln der Bilder erledigt Dateiheader. Beispielsweise JMimeMagic oder Apache Tika die sowohl BMP, GIF, JPG, PNG, TIF und PSD unterstützen (aber nicht SVG). Apache Batik unterstützt SVG. Das folgende Beispiel verwendet 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 ggf. Kombinationen verwenden und das eine und das andere überwiegen.
Das heißt, du brauchst nicht unbedingt ImageIO#write()
um das hochgeladene Bild auf der Festplatte zu speichern. Schreiben Sie einfach das erhaltene InputStream
direkt zu a Path
oder irgendein OutputStream
mögen FileOutputStream
der übliche Java-IO-Weg ist mehr als ausreichend (siehe auch Empfohlene Methode zum Speichern hochgeladener Dateien in einer Servlet-Anwendung):
try (InputStream input = uploadedFile.getInputStream()) {
Files.copy(input, new File(uploadFolder, fileName).toPath());
}
Es sei denn, Sie möchten einige Bildinformationen wie die Abmessungen sammeln und/oder sie bearbeiten (zuschneiden/Größe ändern/drehen/konvertieren/usw.).
ich benutzte 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. Es löst ImageReadException aus, wenn die hochgeladene Datei kein Bild ist.
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
}
Dies ist in das JDK integriert und erfordert lediglich einen Stream mit Unterstützung für
byte[] data = ;
InputStream is = new BufferedInputStream(new ByteArrayInputStream(data));
String mimeType = URLConnection.guessContentTypeFromStream(is);
//...close stream
Versuchen Sie es mit einer mehrteiligen Datei anstelle von BufferedImage
import org.apache.http.entity.ContentType;
...
public void processImage(MultipartFile file) {
if(!Arrays.asList(ContentType.IMAGE_JPEG.getMimeType(), ContentType.IMAGE_PNG.getMimeType(), ContentType.IMAGE_GIF.getMimeType()).contains(file.getContentType())) {
throw new IllegalStateException("File must be an Image");
}
}
.
Am besten schauen Sie sich die Dateierweiterung an. Es gibt keine 100-prozentige Methode, um festzustellen, ob es sich bei einer Datei um ein Bild handelt oder nicht.
– AndersK
12. November ’10 um 22:44