2 votes

Définition des valeurs RVB pour la réduction de la palette dans une image PNG

J'ai le méthode suivante qui réduit la taille de la palette dans une image PNG.

private BufferedImage setColour(BufferedImage image) {
    IndexColorModel cm = new IndexColorModel(
            3, 
            6,       
            new byte[]{-100, 0, 0, 0, -1, 0},  // r 
            new byte[]{0, -100, 60, 0, -1, 0}, // g
            new byte[]{0, 0, 0, -100, -1, 0}); // b
    BufferedImage img = new BufferedImage(
            image.getWidth(), image.getHeight(),
            BufferedImage.TYPE_BYTE_INDEXED,
            cm);
    Graphics2D g2 = img.createGraphics();
    g2.drawImage(image, 0, 0, null);
    g2.dispose();       
    return img;
}

Je comprends que chaque tableau d'octets est utilisé pour indexer la palette associée à un pixel PNG. Ce que je ne comprends pas, c'est comment définir les valeurs dans les tableaux d'octets de sorte que je puisse seulement légèrement réduire le nombre de couleurs dans l'image PNG.

3voto

Paŭlo Ebermann Points 35526

Le modèle de couleurs indexé répertorie essentiellement toutes les couleurs qui peuvent être utilisées dans l'image tamponnée, avec leurs valeurs RVB.

Chaque colonne de

//          red, light green, dark green, blue, white, black
new byte[]{-100,       0,         0,        0,    -1,    0},  // red part
new byte[]{   0,    -100,        60,        0,    -1,    0},  // green part
new byte[]{   0,       0,         0,     -100,    -1,    0}   // blue part

correspond à une couleur - je les ai ajoutés dans la ligne de commentaire.

Seules ces couleurs seront finalement utilisées dans l'image résultante, toutes les autres seront approximées par la couleur la plus proche, ou par un motif à partir des deux couleurs les plus proches :

(in - out)
(Image volée à Réponse de Rekin .)

Si vous voulez réduire le nombre de couleurs à 6, mais aussi à un plus grand nombre, il vous suffit d'en énumérer davantage. Vous pouvez soit utiliser une liste prédéfinie, soit l'adapter à partir des statistiques de l'image originale (par exemple, si l'image est principalement composée de ciel bleu, incluez plusieurs teintes bleues, mais pas autant d'autres couleurs). Vous pouvez également choisir entre plusieurs palettes prédéfinies, en recherchant celle qui présente la plus petite différence par rapport à l'image d'origine.

Au lieu d'utiliser IndexedColorModel, vous pouvez également utiliser l'une des autres implémentations de ColorModel. Par exemple, il s'agirait d'un espace de 64 couleurs avec 4 niveaux de transparence, répartis de manière égale (je pense), utilisant un octet par pixel (deux bits par couleur) :

new DirectColorModel(8, 0xC0, 0x30, 0x0C, 0x03);

Celui-ci n'utiliserait qu'un seul bit pour la transparence, au lieu de trois bits pour le vert (que les yeux humains peuvent voir plus clairement) :

new DirectColorModel(8, 0xC0, 0x38, 0x06, 0x01);

Je ne les ai pas testés avec l'encodeur PNG, veuillez le faire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X