ru.org.linux.util.image.ImageInfo.java Source code

Java tutorial

Introduction

Here is the source code for ru.org.linux.util.image.ImageInfo.java

Source

/*
 * Copyright 1998-2013 Linux.org.ru
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package ru.org.linux.util.image;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.imgscalr.Scalr;
import ru.org.linux.util.BadImageException;

import javax.imageio.IIOException;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

/**
 * Gets image dimensions by parsing file headers.
 * <p/>
 * currently supported file types: Jpeg Gif Png
 */
public class ImageInfo {
    private static final Log logger = LogFactory.getLog(ImageInfo.class);

    private int height = -1;
    private int width = -1;
    private int size = 0;

    private final String filename;

    @SuppressWarnings("UseOfSystemOutOrSystemErr")
    public static void main(String[] args) throws Exception {
        ImageInfo info = new ImageInfo(args[0]);

        if (info.width > info.height) {
            System.out.print("horizontal ");
        } else {
            System.out.print("vertical ");
        }

        System.out.println(info.width + " " + info.height);
    }

    /**
     * constructs image from filename
     * <p/>
     * file type is determined from file's extension
     */
    public ImageInfo(String filename) throws BadImageException, IOException {
        this.filename = filename;

        FileInputStream fileStream = null;

        try {
            fileStream = new FileInputStream(filename);
            size = (int) new File(filename).length();

            String lowname = filename.toLowerCase();

            if (lowname.endsWith("gif")) {
                getGifInfo(fileStream);
            } else if (lowname.endsWith("jpg") || lowname.endsWith("jpeg")) {
                getJpgInfo(fileStream);
            } else if (lowname.endsWith("png")) {
                getPngInfo(fileStream);
            } else {
                throw new BadImageException("Invalid image extension");
            }

            if (height == -1 || width == -1) {
                throw new BadImageException();
            }
        } finally {
            if (fileStream != null) {
                fileStream.close();
            }
        }
    }

    public ImageInfo(File file, String extension) throws BadImageException, IOException {
        filename = file.getName();

        FileInputStream fileStream = null;

        try {
            fileStream = new FileInputStream(file);
            size = fileStream.available();

            if ("gif".equals(extension)) {
                getGifInfo(fileStream);
            } else if ("jpg".equals(extension) || "jpeg".equals(extension)) {
                getJpgInfo(fileStream);
            } else if ("png".equals(extension)) {
                getPngInfo(fileStream);
            } else {
                throw new BadImageException("Invalid image extension");
            }

            if (height == -1 || width == -1) {
                throw new BadImageException();
            }
        } finally {
            if (fileStream != null) {
                fileStream.close();
            }
        }
    }

    private void getGifInfo(FileInputStream fileStream) throws IOException, BadImageException {
        byte[] bytes = new byte[13];
        int bytesread = fileStream.read(bytes);
        if (bytesread == 13) {
            String header = new String(bytes);
            if ("GIF".equals(header.substring(0, 3))) //It's a gif, continue processing
            {
                width = shortLittleEndian(bytes[6], bytes[7]);
                height = shortLittleEndian(bytes[8], bytes[9]);
            } else {
                throw new BadImageException("Bad GIF image: " + filename);
            }
        }
    }

    private void getPngInfo(FileInputStream fileStream) throws IOException, BadImageException {
        byte[] bytes = new byte[24];
        int bytesread = fileStream.read(bytes);
        if (bytesread == 24) {
            String header = new String(bytes);
            if ("PNG".equals(header.substring(1, 4))) {
                width = intBigEndian(bytes[16], bytes[17], bytes[18], bytes[19]);
                height = intBigEndian(bytes[20], bytes[21], bytes[22], bytes[23]);
            } else {
                throw new BadImageException("Bad PNG image: " + filename);
            }
        }
    }

    private void getJpgInfo(FileInputStream fileStream) throws IOException, BadImageException {
        if (fileStream.read() == 0xFF && fileStream.read() == 0xD8) {
            while (true) {
                int marker;
                do {
                    marker = fileStream.read();
                } while (marker != 0xFF);
                do {
                    marker = fileStream.read();
                } while (marker == 0xFF);

                if (((marker >= 0xC0) && (marker <= 0xC3)) || ((marker >= 0xC5) && (marker <= 0xCB))
                        || ((marker >= 0xCD) && (marker <= 0xCF))) {
                    fileStream.skip(3);
                    height = shortBigEndian((byte) fileStream.read(), (byte) fileStream.read());
                    width = shortBigEndian((byte) fileStream.read(), (byte) fileStream.read());
                    break;
                } else {
                    int skip = shortBigEndian((byte) fileStream.read(), (byte) fileStream.read()) - 2;

                    if (skip < 0) {
                        throw new BadImageException("Bad JPG image: " + filename);
                    }

                    fileStream.skip(skip);
                }
            }
        } else {
            throw new BadImageException("Bad JPG image: " + filename);
        }
    }

    private static short shortBigEndian(byte firstRead, byte lastRead) {
        return (short) (((firstRead & 0xFF) << 8) | lastRead & 0xFF);
    }

    private static short shortLittleEndian(byte firstRead, byte lastRead) {
        return shortBigEndian(lastRead, firstRead);
    }

    private static int intBigEndian(byte a1, byte a2, byte a3, byte a4) {
        return ((a1 & 0xFF) << 24) | ((a2 & 0xFF) << 16) | ((a3 & 0xFF) << 8) | a4 & 0xFF;
    }

    public int getHeight() {
        return height;
    }

    public int getWidth() {
        return width;
    }

    /**
     * get file size
     */
    public int getSize() {
        return size;
    }

    /**
     * get file size in user-printable form
     */
    public String getSizeString() {
        return size / 1024 + " Kb";
    }

    /**
     * get HTML code for inclusion into IMG tag
     */
    public String getCode() {
        return "width=" + width + " height=" + height;
    }

}