PNG - Можно ли уменьшить палитру с помощью Java 2D? - PullRequest
6 голосов
/ 26 июля 2011

Если у меня есть изображение PNG, открытое как BufferedImage, возможно ли уменьшить палитру в изображении PNG, чтобы было меньше цвета (меньше битов на пиксель / глубину цвета)?

Например, если вы посмотрите Глубина цвета в Википедии, я хотел бы использовать 16 цветов в своем изображении PNG (3-е изображение внизу справа).

Если это невозможно с Java 2D, есть ли библиотека, которая позволит мне сделать это эффективно?

Ответы [ 2 ]

8 голосов
/ 27 июля 2011

Я думаю, что Мартин Курто был прав:

comparison

Вот пример реализации:

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.IndexColorModel;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class ImagingTest2 {
    public static void main(String[] args) throws IOException {
        BufferedImage src = ImageIO.read(new File("in.png")); // 71 kb

        // here goes custom palette
        IndexColorModel cm = new IndexColorModel(
                3, // 3 bits can store up to 8 colors
                6, // here I use only 6
                //          RED  GREEN1 GREEN2  BLUE  WHITE BLACK              
                new byte[]{-100,     0,     0,    0,    -1,     0},
                new byte[]{   0,  -100,    60,    0,    -1,     0},
                new byte[]{   0,     0,     0, -100,    -1,     0});

        // draw source image on new one, with custom palette
        BufferedImage img = new BufferedImage(
                src.getWidth(), src.getHeight(), // match source
                BufferedImage.TYPE_BYTE_INDEXED, // required to work
                cm); // custom color model (i.e. palette)
        Graphics2D g2 = img.createGraphics();
        g2.drawImage(src, 0, 0, null);
        g2.dispose();

        // output
        ImageIO.write(img, "png", new File("out.png"));   // 2,5 kb
    } 
}
3 голосов
/ 26 июля 2011

Создайте новый BufferedImage с нижней палитрой и используйте createGraphic(), чтобы получить объект Graphics2D.Нарисуйте оригинальное изображение на графике.dispose() графика и вот вы здесь.

BufferedImage img = new BufferedImage(orig.getWidth(), orig.getHeight(),
                                      BufferedImage.TYPE_USHORT_555_RGB);
...