Bonjour à tous,
Je souhaiterais réaliser un petit algorithme de compression d'image et j'aurais besoin de vos conseils et de votre aide pour l'implémenter en Java.
Principe de l'algorithme
Commençons par donner quelques explications…
Objectif de l'algorithme
Réduire le poids d'une image (c'est un algorithme de compression). On donne une image en entrée qui fait une taille de XXX. On obtient une image en sortie, qui fait la même taille.
Mais l'image de sortie est calculée à partir d'un arbre qui lui est issu de la compression. Et c'est précisément cet arbre qui a une taille plus petite que l'image.
Fonctionnement
On crée un QuadTree (arbre à 4 noeuds). Celui-ci sera utile, lisez la suite. Un noeud peut être un noeud-RGB, auquel cas il représente un bloc de pixel(s) et possède donc les attributs RGB. Un noeud peut être également un noeud-Children, auquel cas il ne contient pas d'attribut RGB, mais un attribut "children" qui est une liste de 4 noeuds (noeuds-Children ou bien noeuds-RGB en différentes proportions dans la liste ou bien uniquement des noeuds-Children ou bien uniquement des noeuds-RGB).
On divise l'image en 4 gros blocs : 2*2 (2 lignes et 2 colonnes quoi ). Je dis "gros blocs" car chacun d'eux est constitué de plusieurs pixels. Ces 4 gros blocs sont de même taille (l'image étant un carré de hauteur divisible par 2 on va dire).
On parcourt chacun des 4 blocs de l'image.
-
Si le bloc courant possède des pixels de même couleur, alors on crée un noeud-RVB ; ce noeud possédera les attributs RVB initialisés aux RVB du bloc courant. Puis on ajoute ce noeud dans l'arbre.
-
Sinon : on crée un noeud-Children ; ce noeud n'aura pas de RVB, mais son attribut "children" sera initialisé (ie. :
= new ArrayList<>(4)
). On indique à l'arbre que les prochains noeuds-RVB ou noeud-Children seront à placer dans celui-ci. Enfin, on fait un appel récursif : on divise ce bloc en 4 gros blocs, on les parcourt, si le bloc courant possède [blablabla…].
A la fin de ce processus, on devrait normalement tomber sur des "gros blocs" de 1*1 pixel, ce qui veut évidemment dire que le point n°2 ne sera pas lu : seul le point n°1 le sera. C'est donc une condition d'arrêt de la récursivité.
On peut faire un parallèle avec…
Un algorithme de flou, c'est un peu le même principe finalement.
Reconstruction de l'image
A l'issue de tout ce que j'ai expliqué, on obtient juste un QuadTree rempli avec des noeuds-RGB. Mais l'image en soi n'est pas retouchée.
L'idée est de créer une nouvelle image à partir de ce QuadTree.
La nouvelle image a la même taille que l'ancienne si je ne m'abuse. Par contre : la taille du QuadTree est bien plus petite car les noeuds-RGB peuvent très bien représenter chacun un gros bloc de pixelS !
On parcourt donc ce QuadTree, et quand on trouve un noeud-RGB, on le dessine, en tenant compte de sa taille. Quand on trouve un noeud-Children, on parcourt ses fils.
Mes questions
-
Comme vous avez pu le constater, je n'ai pas bien compris la reconstruction de l'image… Si vous pouviez m'aiguiller ce sera sympa !
-
Est-ce que vous avez déjà réalisé cet algo ? Est-ce très fastidieux à faire ? Y aurait-il moyen de m'inspirer de codes déjà faits, ou de pseudo-codes, pour que je puisse comprendre rapidement comment mettre tout ça en place ?
Merci d'avance et bonne continuation à vous !