Проверьте, является ли файл изображением

Я использую JAI и создаю файл с:

PlanarImage img = JAI.create("fileload", myFilename);

думаю, что если файл существует. Но как я могу проверить, является ли файл a .БМП или .tiff или файл изображения?

кто-нибудь знает?

9 ответов


проект Image Magick имеет средства для идентификации изображения, и есть Java-оболочка для Image Magick под названием JMagick, которую, я думаю, вы можете рассмотреть вместо изобретения колеса:

http://www.jmagick.org

Я использую Image Magick все время, включая его функцию "идентифицировать" из командной строки, и он никогда не ошибался, чтобы идентифицировать изображение.

назад в те дни, когда я абсолютно нуждался в этой функции и JMagick меня еще не существовало!--1--> ImageMagick в identify команда с Java, и она работала отлично.

В настоящее время, что JMagick существует, это, вероятно, больше не нужно (но я еще не пробовал JMagick).

обратите внимание, что он дает гораздо больше, чем просто формат, например:

$  identify tmp3.jpg 
tmp3.jpg JPEG 1680x1050 1680x1050+0+0 DirectClass 8-bit 293.582kb 

$  identify tmp.png
tmp.png PNG 1012x900 1012x900+0+0 DirectClass 8-bit 475.119kb

попробуйте использовать ширину изображения:

boolean isImage(String image_path){
  Image image = new ImageIcon(image_path).getImage();
  if(image.getWidth(null) == -1){
        return false;
  }
  else{
        return true;
  }
}

если ширина равна -1, то это не изображение.


чтобы сказать, является ли что-то png, я использовал этот фрагмент ниже в Android java.

public CompressFormat getCompressFormat(Context context, Uri fileUri) throws IOException {
    // create input stream
    int numRead;
    byte[] signature = new byte[8];
    byte[] pngIdBytes = { -119, 80, 78, 71, 13, 10, 26, 10 };
    InputStream is = null;

    try {
        ContentResolver resolver = context.getContentResolver();
        is = resolver.openInputStream(fileUri);

        // if first 8 bytes are PNG then return PNG reader
        numRead = is.read(signature);

        if (numRead == -1)
            throw new IOException("Trying to reda from 0 byte stream");

    } finally {
        if (is != null)
            is.close();
    }

    if (numRead == 8 && Arrays.equals(signature, pngIdBytes)) {
        return CompressFormat.PNG;
    }

    return null;
}

в начале файлов есть идентифицирующая последовательность символов. Например, файлы JPEG начинаются с FF D8 FF.

вы можете проверить эту последовательность в своей программе, но я не уверен, работает ли это для каждого файла.

для получения информации об идентификации символов вы можете посмотреть наhttp://filext.com


можно использовать дроид, инструмент для идентификации формата файла, который также предлагает API Java, который будет использоваться примерно так:

AnalysisController controller = new AnalysisController();
controller.readSigFile(signatureFileLocation);
controller.addFile(fileToIdentify.getAbsolutePath());
controller.runFileFormatAnalysis();
Iterator<IdentificationFile> it = controller.getFileCollection().getIterator();

документация по использованию API довольно разрежена, но вы можете посмотреть на этот рабочий пример (интересная часть находится в identifyOneBinary метод).


единственный (полу-)надежный способ определить содержимое файла-открыть его и прочитать первые несколько символов. Затем вы можете использовать набор тестов, реализованных в команде Unix file, чтобы сделать обоснованное предположение о содержимом файла.


расширяя ответ Биркана, здесь доступен список "магических чисел":

http://www.astro.keele.ac.uk/oldusers/rno/Computing/File_magic.html

Я только что проверил файл BMP и TIFF (оба только что созданы в Windows XP / Paint), и они кажутся правильными:

First two bytes "42 4d" -> BMP
First four bytes "4d 4d 00 2a" -> TIFF

я использовал VIM для редактирования файлов, а затем сделал инструменты | конвертировать в Hex, но вы также можете использовать "od-c" или что-то подобное, чтобы проверить их.

Как в стороне, я был немного удивлен, когда узнал магические числа, используемые для скомпилированных классов Java: "ca fe ba be" - "cafe babe":)


попробуйте использовать стандартный JavaBeans Платформа Активации (JAF)

с расширением JavaBeans Activation Framework standard разработчики, использующие технологию Java, могут воспользоваться стандартными сервисами для определите тип произвольного фрагмента данных, инкапсулировать доступ к нему, обнаружить операции, доступные на нем, и создать экземпляр соответствующего компонента для выполнения указанных операций. Например, если браузер получил изображение JPEG, это фреймворк позволит браузеру чтобы идентифицировать этот поток данных как изображение JPEG, и из этого типа браузер может найти и создать экземпляр объекта, который может манипулировать или просматривать это изображение.


if(currentImageType ==null){
                    ByteArrayInputStream is = new ByteArrayInputStream(image);
                    String mimeType = URLConnection.guessContentTypeFromStream(is);
                    if(mimeType == null){
                        AutoDetectParser parser = new AutoDetectParser();
                        Detector detector = parser.getDetector();
                        Metadata md = new Metadata();
                        mimeType = detector.detect(is,md).toString();

                        if (mimeType.contains("pdf")){
                            mimeType ="pdf";
                        }
                        else if(mimeType.contains("tif")||mimeType.contains("tiff")){
                            mimeType = "tif";
                        }
                    }
                    if(mimeType.contains("png")){
                        mimeType ="png";
                    }
                    else if( mimeType.contains("jpg")||mimeType.contains("jpeg")){
                        mimeType = "jpg";
                    }
                    else if (mimeType.contains("pdf")){
                        mimeType ="pdf";
                    }
                    else if(mimeType.contains("tif")||mimeType.contains("tiff")){
                        mimeType = "tif";
                    }

                    currentImageType = ImageType.fromValue(mimeType);
                }