PNG - Est-il possible de réduire la palette en utilisant Java 2D?
-
27-10-2019 - |
Question
Si j'ai une image PNG ouvert en tant BufferedImage, est-il possible de réduire la palette dans l'image PNG afin qu'il y ait moins de couleur (moins de bits par pixel / profondeur de couleur)?
Par exemple, si vous regardez Profondeur des couleurs dans Wikipedia, je voudrais utiliser 16 couleurs dans mon image PNG (3ème image vers le bas du côté droit).
S'il est impossible avec Java 2D, est-il une bibliothèque là-bas qui me permettra de le faire efficacement?
La solution
I think Martijn Courteaux was right:
Here is example implementation:
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
}
}
Autres conseils
Create a new BufferedImage with the lower palette and use createGraphic()
to acquire a Graphics2D
object. Draw the original image on the graphics. dispose()
the graphics and here you are.
BufferedImage img = new BufferedImage(orig.getWidth(), orig.getHeight(),
BufferedImage.TYPE_USHORT_555_RGB);