Prueba si un archivo es un archivo de imagen

Estoy usando un archivo IO y quiere saber si hay un método para comprobar si un archivo es una imagen?

preguntado el 10 de marzo de 12 a las 01:03

stackoverflow.com/questions/670546/… (C#, pero se trata de verificar los encabezados, que no es específico del idioma), o stackoverflow.com/questions/2192717/check-if-a-file-is-an-image o el stackoverflow.com/questions/9244710/… o -

8 Respuestas

Esto funciona bastante bien para mí. Espero poder ayudar

import javax.activation.MimetypesFileTypeMap;
import java.io.File;
class Untitled {
    public static void main(String[] args) {
        String filepath = "/the/file/path/image.jpg";
        File f = new File(filepath);
        String mimetype= new MimetypesFileTypeMap().getContentType(f);
        String type = mimetype.split("/")[0];
        if(type.equals("image"))
            System.out.println("It's an image");
        else 
            System.out.println("It's NOT an image");
    }
}

respondido 15 mar '12, 13:03

hola @dermoritz Esto parece ser un problema en su sistema. Echa un vistazo a esta publicación SO stackoverflow.com/questions/4855627/… - Ismael

¿Qué tal si es de URL? ¿Antes de guardar la URL en un archivo? Obtuve "aplicación/flujo de octetos" en lugar de imagen. Alguna idea ? - guauarco

@dermoritz, yo también."new MimetypesFileTypeMap().getContentType(path)" devuelve "application/octet-stream", pero "URLConnection.guessContentTypeFromName(path)" devuelve el tipo mime correcto. - wangqi060934

Esto solo verifica en función de la extensión del archivo. Las imágenes no válidas (otros archivos binarios sin contenido de imagen y encabezados de archivo adecuados) no se pueden detectar con este método. - Alex Fedulov

Esta es una mala manera de probar si el archivo es una imagen. una mejor solución es: Files.probeContentType(ruta); - Biagio Cannistraro

if( ImageIO.read(*here your input stream*) == null)
    *IS NOT IMAGE*    

Y también hay una respuesta: ¿Cómo verificar un archivo cargado si es una imagen u otro archivo?

contestado el 23 de mayo de 17 a las 13:05

Esta es la única forma en que pude encontrar si un archivo es un archivo de imagen (en un sistema Ubuntu con Java 8). - zafar142003

En Java 7, existe el java.nio.file.Files.probeContentType() método. En Windows, utiliza la extensión del archivo y el registro (no analiza el contenido del archivo). Luego puede verificar la segunda parte del tipo MIME y verificar si está en el formulario <X>/image.

respondido 10 mar '12, 02:03

En Linux, parece que solo mira la extensión en mi máquina. Cambió un archivo .jpeg a .txt y devolvió "texto/simple". Me gusta la respuesta de Krystian a continuación. - yngwietiger

Puedes probar algo como esto:

String pathname="abc\xyz.png"
File file=new File(pathname);


String mimetype = Files.probeContentType(file.toPath());
//mimetype should be something like "image/png"

if (mimetype != null && mimetype.split("/")[0].equals("image")) {
    System.out.println("it is an image");
}

Respondido el 09 de junio de 16 a las 06:06

Puedes probar algo como esto:

   import javax.activation.MimetypesFileTypeMap;

   File myFile;

   String mimeType = new MimetypesFileTypeMap().getContentType( myFile ));
   // mimeType should now be something like "image/png"

   if(mimeType.substring(0,5).equalsIgnoreCase("image")){
         // its an image
   }

esto debería funcionar, aunque no parece ser la versión más elegante.

respondido 10 mar '12, 02:03

lo siento, cuando escribí mi respuesta no estaba la tuya... tal vez me tomó mucho tiempo escribirla. Pero tienes razón, es completamente lo mismo :) - GameDroids

jejeje, no hay problema. Creo que le pasa a todo el mundo todo el tiempo aquí. :) - Ismael

@ismaelga - De hecho, sucede con tanta frecuencia que la mayoría de la gente ni siquiera se molestaría en comentarlo. - Stephen C

@StephenC - Soy una mala persona, lo sé. Acabo de comentar por la brecha de unos 30 minutos, pero sé que sigue siendo algo normal. :) y no estoy siendo sarcástico - Ismael

Hay una variedad de maneras de hacer esto; ver otras respuestas y los enlaces a preguntas relacionadas. (El enfoque de Java 7 me parece el más atractivo, porque utiliza convenciones específicas de la plataforma de forma predeterminada y puede proporcionar su propio esquema para la determinación del tipo de archivo).

Sin embargo, me gustaría señalar que ningún mecanismo es completamente infalible:

  • Los métodos que dependen del sufijo del archivo serán engañados si el sufijo no es estándar o es incorrecto.

  • Los métodos que dependen de los atributos del archivo (por ejemplo, en el sistema de archivos) serán engañados si el archivo tiene un atributo de tipo de contenido incorrecto o ninguno.

  • Los métodos que se basan en mirar la firma del archivo pueden ser engañados por archivos binarios que tienen los mismos bytes de firma.

  • Incluso el simple intento de leer el archivo como una imagen puede ser engañado si no tiene suerte... dependiendo de los formatos de imagen que intente.

Respondido 16 Abr '19, 08:04

Otras respuestas sugieren cargar la imagen completa en la memoria (ImageIO.read) o para usar métodos JDK estándar (MimetypesFileTypeMap y Files.probeContentType).

La primera forma no es eficiente si no se requiere leer la imagen y todo lo que realmente quiere es probar si es una imagen o no (y tal vez guardar su tipo de contenido para configurarlo Content-Type encabezado de respuesta cuando esta imagen se lea en el futuro).

Las formas de JDK entrantes generalmente solo prueban la extensión del archivo y realmente no le dan un resultado en el que pueda confiar.

La forma en que funciona para mí es usar apache tika biblioteca.

private final Tika tika = new Tika();

private MimeType detectImageContentType(InputStream inputStream, String fileExtension) {
    Assert.notNull(inputStream, "InputStream must not be null");

    String fileName = fileExtension != null ? "image." + fileExtension : "image";
    MimeType detectedContentType = MimeType.valueOf(tika.detect(inputStream, fileName));
    log.trace("Detected image content type: {}", detectedContentType);

    if (!validMimeTypes.contains(detectedContentType)) {
        throw new InvalidImageContentTypeException(detectedContentType);
    }

    return detectedContentType;
}

La detección de tipo se basa en el contenido del flujo de documentos dado y el nombre del documento. Solo se lee un número limitado de bytes del flujo.

paso fileExtension como un indirecta para Tika. Funciona sin él. Pero según la documentación ayuda a detectar mejor en algunos casos.

  • La principal ventaja de este método en comparación con ImageIO.read es que Tika no lee el archivo completo en la memoria, solo los primeros bytes.

  • La principal ventaja en comparación con JDK MimetypesFileTypeMap y Files.probeContentType es que Tika realmente lee los primeros bytes del archivo, mientras que JDK solo verifica la extensión del archivo en la implementación actual.

TLDR

  • Si planea hacer algo con la imagen leída (como cambiar el tamaño/recortar/rotarla), use ImageIO.read desde la respuesta de kristian.

  • Si solo desea verificar (y tal vez almacenar) Content-Type, luego use Tika (esta respuesta).

  • Si trabaja en un entorno de confianza y está 100 % seguro de que la extensión del archivo es correcta, utilice Files.probeContentType desde La respuesta de Prunge.

Respondido el 22 de Septiembre de 20 a las 02:09

Aquí está mi código basado en la respuesta usando tika.

private static final Tika TIKA = new Tika();
public boolean isImageMimeType(File src) {
    try (FileInputStream fis = new FileInputStream(src)) {
        String mime = TIKA.detect(fis, src.getName());
        return mime.contains("/") 
                && mime.split("/")[0].equalsIgnoreCase("image");
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

Respondido el 25 de Septiembre de 20 a las 05:09

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.