Программно уменьшить размер файла JPEG - PullRequest
8 голосов
/ 26 июля 2011

Извиняюсь за любое невежество, но я никогда раньше не работал с изображениями jpeg (не говоря уже о любых типах изображений) в Java.

Предположим, я хочу отправить изображение JPEG из веб-службы клиенту. Можно ли как-нибудь уменьшить размер файла jpeg, каким-либо образом управляя цветовым профилем изображения?

Я уже смог уменьшить размер изображения, масштабируя его с помощью аккуратного инструмента для BufferedImages под названием imgscalr. Смотри здесь .

Мне также хотелось бы, чтобы JPEG имел меньше цветов, чем высококачественное изображение JPEG. Например, я хотел бы иметь возможность использовать 8-битный цвет в моем JPEG вместо, скажем, 16-битный цвет.

Что именно мне нужно изменить, если у меня есть BufferedImage из 2D-пакета Java?

Ответы [ 4 ]

4 голосов
/ 26 июля 2011

Еще один способ уменьшить размер изображения - изменить уровень сжатия. Вы можете сделать это с помощью ImageWriter.

    ImageWriter writer = null;
    Iterator<ImageWriter> iwi = ImageIO.getImageWritersByFormatName("jpg");
    if (!iwi.hasNext())
        return;
    writer = (ImageWriter) iwi.next();
    ImageWriteParam iwp = writer.getDefaultWriteParam();
    iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT) ;
    iwp.setCompressionQuality(compressionQuality);
    writer.setOutput(...);
    writer.write(null, image, iwp);
1 голос
/ 26 июля 2011

Два возможных решения - уменьшить изображение, вот как вы это сделаете:

BufferedImage original = //your image here
scaled = original.getScaledInstance(finalWidth, finalHeight, Image.SCALE_SMOOTH); // scale the image to a smaller one

BufferedImage result = new BufferedImage(finalWidth, finalHeight, original.getType());
Graphics2D g = result.createGraphics();     

g.drawImage(scaled, 0, 0, null); //draw the smaller image
g.dispose();

Очевидно, вам нужно рассчитать масштабированную ширину и высоту, чтобы изображение оставалось с тем же соотношением сторон.

Теперь, когда вы нарисовали его меньше, вы можете превратить это изображение в файл JPEG:

BufferedImage image = // this is the final scaled down image

JPEGImageEncoder jpegEncoder = JPEGCodec.createJPEGEncoder(output);
JPEGEncodeParam jpegEncodeParam = jpegEncoder.getDefaultJPEGEncodeParam(image);

jpegEncodeParam.setDensityUnit(JPEGEncodeParam.DENSITY_UNIT_DOTS_INCH);
jpegEncodeParam.setXDensity(92);
jpegEncodeParam.setYDensity(92);

jpegEncodeParam.setQuality( 0.8F , false);
jpegEncoder.encode(image, jpegEncodeParam);

Эти классы относятся к пакету JAI (точнее com.sun.image.codec.jpeg ), и JVM может жаловаться, что их не следует использовать напрямую, но вы могу игнорировать это.

Возможно, вы можете загрузить JAI с здесь , если он не работает, у меня есть настройка зеркал github для двух библиотек, JAI core и JAI ImageIO .

1 голос
/ 26 июля 2011

Посмотрите на класс ImageIO. Что касается уменьшения размера файла: поскольку изображение уже будет в формате JPEG, единственное, что вы можете сделать, это уменьшить качество или размер изображения.

Еще одна вещь, которую нужно иметь в виду: если изображение в формате CMYK JPEG, оно может быть больше. К сожалению, ImageIO не может справиться с этим, но вы можете попробовать JAI ImageIO конвертировать из CMYK в RGB (который должен быть намного меньше).

1 голос
/ 26 июля 2011

Самый простой способ сделать это - распаковать поток байтов в образ Java, по желанию изменить его размер (что делает его меньше), а затем заново создать из него изображение JPEG с желаемой настройкой качества.

Этозатем новое изображение отправляется клиенту.

...