Рассчитать размер файла измененного изображения (например, JPEG) перед изменением размера - PullRequest
1 голос
/ 07 июня 2011

Как рассчитать размер файла изображения с измененным размером (например, JPEG), прежде чем изменить его размер?

Мне нужно отправить HTTP-запрос Content-length, затем я изменю размер изображения, иначе nginx получит ответ об истечении времени ожидания.

Ответы [ 3 ]

0 голосов
/ 08 июня 2011

zen0n, если вам абсолютно необходимо это сделать, использование предложения Эндрю с незначительной модификацией - единственный способ сделать это (выполнить всю операцию изменения размера, выводя байты в ByteArrayOutputStream, чтобы вы могли посчитать их заранее).

Модификация, которую я бы использовал, - это выполнение на стороне сервера с простой библиотекой изменения размера изображения, такой как imgscalr , передача BufferedImage, представляющего загруженное изображение, и получение измененного размера BufferedImage, представляющегоизображение нового размера.Затем прокачайте его через ImageIO.write и выведите его в BufferedArrayOutputStream.

Затем установите заголовок «Content-Length» и отправьте обратно содержимое изображения.

Поскольку преобразование необработанных байтов изображения в JPGвводит последовательность сжатия и кодирования событий, нет точного способа заранее предсказать точную длину файла, а затем использовать ImageIO.write для потоковой передачи байтов обратно клиенту.Сначала вам придется полностью изменить размер изображения (в памяти), используя технику, упомянутую выше, а затем записать данные обратно клиенту.

0 голосов
/ 09 июня 2011

Это мое решение:

public class IOSUtil {

private static int FILEBUFFERSIZE = 1024;

public static int input2OutputStream(InputStream is, OutputStream os)
        throws IOException {
        byte[] bytes = new byte[FILEBUFFERSIZE];
        int bytesRead;
        int allBytes = 0;
        while ((bytesRead = is.read(bytes)) != -1) {
            os.write(bytes, 0, bytesRead);
            allBytes+=bytesRead;
        }

        is.close();
        os.close();
        return allBytes;
    }

public IOSUtil() {
        super();
    }

}
................
protected InputStream setLength(InputStream is) throws IOException
{
    PipedInputStream in = new PipedInputStream();
    PipedOutputStream pout = new PipedOutputStream(in);
    length = IOSUtil.input2OutputStream(is, pout);
    return in;
}

@Override
protected InputStream getInputStreamContent(CMObject cmObject) throws CMException {

    try {
        Integer cacheLength = new Integer(0);
        if((cacheLength = (Integer) getCacheService().getCache(getCacheService().createKeyForImageResize(cmObject.getCode(), ImageProcessor.getWidth(width, height), height))) == null)
        {
        return setLength(resizeImage(cmObject));
        } else
        {
            length = cacheLength;
            return resizeImage(cmObject);
        }
    } catch (IOException e) {
        length = super.getLength(cmObject);
        log.error("Error resize image", e);
    }

    return super.getInputStreamContent(cmObject);
}
private InputStream resizeImage(CMObject cmObject)
{
.......
}
0 голосов
/ 07 июня 2011

Чтобы сделать это на стороне клиента, используйте свободно плавающий или встроенный апплет или фрейм.

Используйте ImageIO.write(Image,String,InputStream) для сериализации изображения в ByteArrayOutputStream.

Размер изображения с измененным размером можно найти, baos.toByteArray().length.

Если апплет или фрейм запущен с использованием Java Web Start , он получит доступк услугам API JNLP.Затем FileOpenService можно использовать для получения изображений из локальной файловой системы клиента в изолированном приложении.Приложение в песочнице.можно только загрузить изображения на сервер, с которого они пришли.

Вот мое демо.файловых служб JNLP .

...