diff --git a/build/fr/iutfbleau/sae/mhuffman/FrequencyTable.class b/build/fr/iutfbleau/sae/mhuffman/FrequencyTable.class new file mode 100644 index 0000000..980e373 Binary files /dev/null and b/build/fr/iutfbleau/sae/mhuffman/FrequencyTable.class differ diff --git a/build/fr/iutfbleau/sae/mimage/Pixel.class b/build/fr/iutfbleau/sae/mimage/Pixel.class new file mode 100644 index 0000000..424078e Binary files /dev/null and b/build/fr/iutfbleau/sae/mimage/Pixel.class differ diff --git a/build/fr/iutfbleau/sae/mimage/RGBImage.class b/build/fr/iutfbleau/sae/mimage/RGBImage.class new file mode 100644 index 0000000..351c0e6 Binary files /dev/null and b/build/fr/iutfbleau/sae/mimage/RGBImage.class differ diff --git a/build/fr/iutfbleau/sae/vconverter/ConverterWindow.class b/build/fr/iutfbleau/sae/vconverter/ConverterWindow.class index 6080a1f..63526d5 100644 Binary files a/build/fr/iutfbleau/sae/vconverter/ConverterWindow.class and b/build/fr/iutfbleau/sae/vconverter/ConverterWindow.class differ diff --git a/build/fr/iutfbleau/sae/vconverter/ImagePreviewPanel.class b/build/fr/iutfbleau/sae/vconverter/ImagePreviewPanel.class index 92d61d8..013c129 100644 Binary files a/build/fr/iutfbleau/sae/vconverter/ImagePreviewPanel.class and b/build/fr/iutfbleau/sae/vconverter/ImagePreviewPanel.class differ diff --git a/makefile b/makefile index 8420b0e..cd7daf2 100644 --- a/makefile +++ b/makefile @@ -31,6 +31,7 @@ all: \ # Compilation des classes main $(BIN)/$(PKG_PATH)/Convertisseur.class: $(BIN) \ $(BIN)/$(PKG_PATH)/vconverter/ConverterWindow.class \ + $(BIN)/$(PKG_PATH)/ConverterController.class \ $(SRC)/$(PKG_PATH)/Convertisseur.java $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/Convertisseur.java @@ -68,7 +69,7 @@ $(BIN)/$(PKG_PATH)/mhuffman/HuffmanNode.class: $(BIN) \ # Compilation des classe mimages $(BIN)/$(PKG_PATH)/mimage/RGBImage.class: $(BIN) \ $(BIN)/$(PKG_PATH)/mimage/Pixel.class \ - $(BIN)/$(PKG_PATH)/mimage/RGBImage.java + $(SRC)/$(PKG_PATH)/mimage/RGBImage.java $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/mimage/RGBImage.java $(BIN)/$(PKG_PATH)/mimage/Pixel.class: $(BIN) \ @@ -99,6 +100,17 @@ $(BIN)/$(PKG_PATH)/vconverter/CodeTablePanel.class: $(BIN) \ # Compilation des classes mpif +# Compilation du controleur +$(BIN)/$(PKG_PATH)/ConverterController.class: $(BIN) \ + $(BIN)/$(PKG_PATH)/mimage/Pixel.class \ + $(BIN)/$(PKG_PATH)/mimage/RGBImage.class \ + $(BIN)/$(PKG_PATH)/mhuffman/FrequencyTable.class \ + $(BIN)/$(PKG_PATH)/mhuffman/CanonicalCode.class \ + $(BIN)/$(PKG_PATH)/vconverter/ConverterWindow.class \ + $(SRC)/$(PKG_PATH)/ConverterController.java + $(JAVAC) -cp $(BIN) -d $(BIN) $(SRC)/$(PKG_PATH)/ConverterController.java + + #Compilation des classes util $(BIN)/$(PKG_PATH)/util/Config.class: $(BIN) \ $(SRC)/$(PKG_PATH)/util/Config.java diff --git a/src/fr/iutfbleau/sae/ConverterController.java b/src/fr/iutfbleau/sae/ConverterController.java index 49360c0..cc6dad0 100644 --- a/src/fr/iutfbleau/sae/ConverterController.java +++ b/src/fr/iutfbleau/sae/ConverterController.java @@ -1,24 +1,80 @@ package fr.iutfbleau.sae; - -import java.awt.*; -import java.io.*; -import javax.imageio.ImageIO; +import fr.iutfbleau.sae.mhuffman.CanonicalCode; +import fr.iutfbleau.sae.mhuffman.FrequencyTable; +import fr.iutfbleau.sae.mimage.Pixel; +import fr.iutfbleau.sae.mimage.RGBImage; +import fr.iutfbleau.sae.vconverter.ConverterWindow; import java.awt.image.BufferedImage; +import java.io.File; +import java.util.Map; +import javax.imageio.ImageIO; +/** + * Contrôleur pour la conversion d'images. + *

+ * Cette classe gère le chargement des fichiers image et les opérations + * de conversion associées. tel que + *

+ * + */ public class ConverterController { + // Image convertie en RGBImage + private RGBImage image; - public BufferedImage loadImage(File f){ - //verification si le fichier contient quelque chose, si il est exesistant et si c'est un fichier "normal" d'apres la javadoc. - if (f == null || !f.exists() || !f.isFile()) { - return null; + // Table de fréquences pour chaque composante + private FrequencyTable frequencyTable; + + // Arbres de Huffman pour chaque composante + private Map abrHuffmanR; + private Map abrHuffmanG; + private Map abrHuffmanB; + + // Codes canoniques pour chaque composante + private CanonicalCode canonRED; + private CanonicalCode canonGREEN; + private CanonicalCode canonBLUE; + + // La fenêtre du convertisseur + private ConverterWindow fen; + + public ConverterController(ConverterWindow fen) { + this.fen = fen; + } + + + // charger une image depuis un fichier avec bufferedImage et la convertir en RGBImage + public void loadImage(String filepath) { + File FI = new File(filepath); + try{ + // Lire l'image avec BufferedImage + BufferedImage buffimage = ImageIO.read(FI); + if (buffimage == null) { + throw new IllegalArgumentException("Le fichier spécifié n'est pas une image valide."); + } + + int w = buffimage.getWidth(); + int h = buffimage.getHeight(); + + // Créer une RGBImage de la même taille + this.image = new RGBImage(w, h); + // remplir la RGBImage avec les pixels de BufferedImage + for (int y = 0; y < h; y++) { + for (int x = 0; x < w; x++) { + int rgb = buffimage.getRGB(x, y); // obtenir la valeur RGB du pixel + // Extraire les composantes R, G, B + int r = (rgb >> 16) & 0xFF; + int g = (rgb >> 8) & 0xFF; + int b = rgb & 0xFF; + // Créer un pixel et l'ajouter à la RGBImage + this.image.setPixel(x, y, new Pixel(r, g, b)); + } + } + + // Mettre à jour le GUI + this.fen.setImagePreview(buffimage); + + } catch (Exception e) { + e.printStackTrace(); } - BufferedImage image; - try { - image = ImageIO.read(f); - } catch (IOException e){ - return null; - } - return image; - } } diff --git a/src/fr/iutfbleau/sae/Convertisseur.java b/src/fr/iutfbleau/sae/Convertisseur.java index d914050..95d3c36 100644 --- a/src/fr/iutfbleau/sae/Convertisseur.java +++ b/src/fr/iutfbleau/sae/Convertisseur.java @@ -7,6 +7,10 @@ public class Convertisseur { public static void main(String[] args) { // Créer et stocker la référence à la fenêtre ConverterWindow window = new ConverterWindow(); + + // je la passe au controleur + ConverterController controller = new ConverterController(window); + controller.loadImage("C:\\Magasin\\COURS\\BUT2\\SAES3\\SAE32_2025\\temp"); // Exemple d'utilisation pour les codes Huffman Map codesRouge = new HashMap<>(); diff --git a/src/fr/iutfbleau/sae/mhuffman/CanonicalCode.java b/src/fr/iutfbleau/sae/mhuffman/CanonicalCode.java index d06a2ba..017a06c 100644 --- a/src/fr/iutfbleau/sae/mhuffman/CanonicalCode.java +++ b/src/fr/iutfbleau/sae/mhuffman/CanonicalCode.java @@ -2,11 +2,11 @@ package fr.iutfbleau.sae.mhuffman; import java.util.*; public class CanonicalCode{ - private Map codeLengths = HuffmanTree.getDictionnary(); - private Map canonicalCodes = new HashMap<>(); + private Map codeLengths = new HashMap<>(); // Changer ici car la premiere version est incorecte + private Map canonicalCodes = new HashMap<>(); - public Map generateCodes(){ + public Map generateCodes(){ // 1 ere chose à faire : on regarde uniquement la longueur des codes initiaux(Huffman) // 2eme chose à faire : remettre dans l'ordre des longueurs : si meme taille ==> regarder valeur // 3eme chose à faire : ecriture des codes canoniques : @@ -37,16 +37,16 @@ public class CanonicalCode{ } - public int getCode(){ + public int getCode(int value){ return 0; } - public int getLength(){ + public int getLength(int value){ return 0; } - public Map getCanonicalCodes(){ + public Map getCanonicalCodes(){ return this.canonicalCodes; } } diff --git a/src/fr/iutfbleau/sae/mhuffman/FrequencyTable.java b/src/fr/iutfbleau/sae/mhuffman/FrequencyTable.java index 71b0831..e290162 100644 --- a/src/fr/iutfbleau/sae/mhuffman/FrequencyTable.java +++ b/src/fr/iutfbleau/sae/mhuffman/FrequencyTable.java @@ -1,4 +1,5 @@ package fr.iutfbleau.sae.mhuffman; +import fr.iutfbleau.sae.mimage.RGBImage; /** * Représente une table de fréquences pour une image RGB. @@ -72,11 +73,12 @@ public class FrequencyTable { puis on fait de même pour les composantes verte et bleue. on répète ce processus pour tous les pixels de l'image. */ - for (int i = 0; i < img.getWidth() * img.getHeight(); i++) { - // En un mot: frequence[Composante] += 1 - this.freqR[img.getPixel(i).getR()]++; // Incrémente la fréquence de la composante rouge - this.freqG[img.getPixel(i).getG()]++; // Incrémente la fréquence de la composante verte - this.freqB[img.getPixel(i).getB()]++; // Incrémente la fréquence de la composante bleue + for (int ligne = 0; ligne < img.getWidth(); ligne++) { + for (int colonne = 0; colonne < img.getHeight(); colonne++) { + this.freqR[img.getPixel(ligne, colonne).getR()]++; // Incrémente la fréquence de la composante rouge + this.freqG[img.getPixel(ligne, colonne).getG()]++; // Incrémente la fréquence de la composante verte + this.freqB[img.getPixel(ligne, colonne).getB()]++; // Incrémente la fréquence de la composante bleue + } } } diff --git a/src/fr/iutfbleau/sae/mhuffman/HuffmanTree.java b/src/fr/iutfbleau/sae/mhuffman/HuffmanTree.java index 5081ede..ed0312c 100644 --- a/src/fr/iutfbleau/sae/mhuffman/HuffmanTree.java +++ b/src/fr/iutfbleau/sae/mhuffman/HuffmanTree.java @@ -57,7 +57,9 @@ public class HuffmanTree { /** * Dictionnaire pour enregistrer les codes Huffman */ - private static Map codes; + // j'ai retirer le static car chaque arbre a ses propres codes et j'utilise string plutot que int pour stocker les codes car on construit une chaine de 0 et de 1 + private Map codes; + /** * Chaine de caracteres qui va nous permettre de sauvegader le code Huffman @@ -85,12 +87,7 @@ public class HuffmanTree { // J'initialise la racine à null. this.root = null; - // je cree une collection de feuilles - - /////////////////////////////////// Voir si ya moyen doptimiser ////////////////////////////////////// - - // tu pourrait utiliser une PriorityQueue pour placer selon les fréquences comme dit dans l'énoncé !!!! - + // je cree une collection de feuilles List feuilles = new ArrayList<>(); // pour chaque valeur(symbole) dans la table de frequence @@ -132,26 +129,13 @@ public class HuffmanTree { // a la fin il ne reste qu'un seul noeud : la racine de l'arbre this.root = feuilles.get(0); } - - - /** - * Retourne la racine de l'arbre de Huffman. - *

- * Cette méthode permet d'accéder à la structure complète de l'arbre, - * notamment lors de la génération des codes ou du décodage des données. - *

- * - * @return le nœud racine de l'arbre de Huffman - */ - public HuffmanNode getRoot() { - return root; - } - - /** + + // Méthode pour générer les codes Huffman à partir de l'arbre + // pourquoi string et pas int ? car on va construire une chaine de 0 et de 1 + /** * @return Map on stockera les codes Huffman sous forme de dictionnaire - */ - - public Map generateCodes(){ + */ + public Map generateCodes() { /** * Le but de cette méthode est de pouvoir generer les codes Huffman à partir de l'arbre : * Les branches prendront comme valeur 1 ou 0 selon differents cas : @@ -159,42 +143,76 @@ public class HuffmanTree { * 0 - si on saute vers un fils gauche. * On construit les codes qui partent de la racine jusqu'à notre objectif */ - - this.codes = new HashMap<>(); - this.chaineCarac = new String(); - - if(root.isLeaf()){ - codes.put(root.getValue(),Integer.parseInt(chaineCarac)); - return codes; - } - - HuffmanNode temp = root; - - if (root.getLeft() != null) { - root = root.getLeft(); - chaineCarac = chaineCarac + "0"; - generateCodes(); - // on retire le dernier bit lorsqu'on remonte car sinon les codes seront faussés - chaineCarac = chaineCarac.substring(0, chaineCarac.length() - 1); - } - - if (temp.getRight() != null) { - root = temp.getRight(); - chaineCarac = chaineCarac + "1"; - generateCodes(); - chaineCarac = chaineCarac.substring(0, chaineCarac.length() - 1); - } - - - root = temp; - return codes; - -} - - - public static Map getDictionnary(){ + this.codes = new HashMap<>(); + // je lance la methode recursive avec une chaine vide qui va se remplir au fur et à mesure + generateCodesRec(this.root, ""); return codes; } + + private void generateCodesRec(HuffmanNode node, String prefiixe) { + // Cas de base: si le noeud est une feuille, on ajoute le code au dictionnaire + if (node.isLeaf()) { + if (prefiixe.length() > 0){ + this.codes.put(node.getValue(), prefiixe); + }else{ + this.codes.put(node.getValue(), "0"); + } + return; + } + + //Case general : sinon on continue a parcourir l'arbre + // On va a gauche en ajoutant "0" au code + generateCodesRec(node.getLeft(), prefiixe + "0"); + // On va a droite en ajoutant "1" au code + generateCodesRec(node.getRight(), prefiixe + "1"); + + + // this.codes = new HashMap<>(); + // this.chaineCarac = new String(); + + // if(root.isLeaf()){ + // codes.put(root.getValue(),Integer.parseInt(chaineCarac)); + // return codes; + // } + + // HuffmanNode temp = root; + + // if (root.getLeft() != null) { + // root = root.getLeft(); + // chaineCarac = chaineCarac + "0"; + // generateCodes(); + // // on retire le dernier bit lorsqu'on remonte car sinon les codes seront faussés + // chaineCarac = chaineCarac.substring(0, chaineCarac.length() - 1); + // } + + // if (temp.getRight() != null) { + // root = temp.getRight(); + // chaineCarac = chaineCarac + "1"; + // generateCodes(); + // chaineCarac = chaineCarac.substring(0, chaineCarac.length() - 1); + // } + + + // root = temp; + // return codes; + } + + /** + * @return Dictionnaire des codes Huffman + */ + public Map getCodes(){ + return codes; + } + + /** + * @return le nœud racine de l'arbre de Huffman + */ + public HuffmanNode getRoot() { + return root; + } + + + } diff --git a/src/fr/iutfbleau/sae/mimage/RGBImage.java b/src/fr/iutfbleau/sae/mimage/RGBImage.java index 92ef420..8808505 100644 --- a/src/fr/iutfbleau/sae/mimage/RGBImage.java +++ b/src/fr/iutfbleau/sae/mimage/RGBImage.java @@ -4,16 +4,14 @@ public class RGBImage { private int width; private int height; - private Pixel [] pixels; + private Pixel [][] pixels; public RGBImage (int lar, int haut){ this.width=lar; this.height=haut; - int[][] matrice = new int[this.width][this.height]; + this.pixels = new Pixel[this.width][this.height]; } - - public int getWidth() { return width; } @@ -22,11 +20,11 @@ public class RGBImage { return height; } - public Pixel[] getPixels() { - return pixels; + public void setPixel(int x, int y, Pixel p) { + this.pixels[x][y] = p; } - public void setPixels(Pixel[] pixels) { - this.pixels = pixels; + public Pixel getPixel(int x, int y) { + return this.pixels[x][y]; } } \ No newline at end of file diff --git a/src/fr/iutfbleau/sae/mpif/PIFWriter.java b/src/fr/iutfbleau/sae/mpif/PIFWriter.java index c31139e..7c47a73 100644 --- a/src/fr/iutfbleau/sae/mpif/PIFWriter.java +++ b/src/fr/iutfbleau/sae/mpif/PIFWriter.java @@ -1,18 +1,17 @@ package fr.iutfbleau.sae.mpif; -import fr.iutfbleau.sae.util.bitOutputStream; +import fr.iutfbleau.sae.util.BitOutputStream; +import java.util.Map; public class PIFWriter { - - - public void writeHeader(bitOutputStream out,int width, int height){ + public void writeHeader(BitOutputStream out,int width, int height){ } - public void writeTables(bitOutputStream out, Map canonicalCodes){ + public void writeTables(BitOutputStream out, Map canonicalCodes){ } - public void encodePixels(bitOutputStream out){ + public void encodePixels(BitOutputStream out){ } } diff --git a/src/fr/iutfbleau/sae/util/GestErreur.java b/src/fr/iutfbleau/sae/util/GestErreur.java new file mode 100644 index 0000000..86e4a22 --- /dev/null +++ b/src/fr/iutfbleau/sae/util/GestErreur.java @@ -0,0 +1,5 @@ +package fr.iutfbleau.sae.util; + +public class GestErreur { + +} diff --git a/src/fr/iutfbleau/sae/vconverter/ConverterWindow.java b/src/fr/iutfbleau/sae/vconverter/ConverterWindow.java index 646eefd..54223ad 100644 --- a/src/fr/iutfbleau/sae/vconverter/ConverterWindow.java +++ b/src/fr/iutfbleau/sae/vconverter/ConverterWindow.java @@ -1,10 +1,10 @@ package fr.iutfbleau.sae.vconverter; -import javax.swing.*; +import fr.iutfbleau.sae.util.Config; import java.awt.*; import java.util.Map; - -import fr.iutfbleau.sae.util.Config; +import javax.swing.*; +import java.awt.image.BufferedImage; /** * Fenêtre principale du convertisseur. @@ -101,7 +101,7 @@ public class ConverterWindow extends JFrame { * * @param img image à afficher */ - public void setImagePreview(Object img) { + public void setImagePreview(BufferedImage img) { imagePreviewPanel.setImage(img); } diff --git a/src/fr/iutfbleau/sae/vconverter/ImagePreviewPanel.java b/src/fr/iutfbleau/sae/vconverter/ImagePreviewPanel.java index 404e111..c72ea0d 100644 --- a/src/fr/iutfbleau/sae/vconverter/ImagePreviewPanel.java +++ b/src/fr/iutfbleau/sae/vconverter/ImagePreviewPanel.java @@ -1,6 +1,7 @@ package fr.iutfbleau.sae.vconverter; - import javax.swing.JPanel; +import java.awt.image.BufferedImage; +import javax.swing.JPanel; /** * Le panneau d’aperçu de l’image. @@ -12,11 +13,27 @@ package fr.iutfbleau.sae.vconverter; public class ImagePreviewPanel extends JPanel { + + private BufferedImage image; + public ImagePreviewPanel() { // constructeur vide pour l'instant } - public void setImage(Object img) { - // Implémentation à ajouter + public void setImage(BufferedImage img) { + this.image = img; + repaint(); + + } + + @Override + protected void paintComponent(java.awt.Graphics g) { + super.paintComponent(g); + if (image != null) { + // Dessiner l'image centrée dans le panneau + int x = (getWidth() - image.getWidth()) / 2; + int y = (getHeight() - image.getHeight()) / 2; + g.drawImage(image, x, y, this); + } } } \ No newline at end of file diff --git a/temp/photo.jpg b/temp/photo.jpg new file mode 100644 index 0000000..f5c8714 Binary files /dev/null and b/temp/photo.jpg differ