/// <summary> /// crée un histogramme et le rajoute en dessous de l'image /// </summary> public void Histogramme() { #region création de l'histogramme int[] rouge = new int[256]; int[] bleu = new int[256]; int[] vert = new int[256]; ///parcoure toute les valeurs de byte possibles, compte le nombre de byte rouge,vert et bleu associé à cette valeur et le met dans chaque tableau associé int compteurR = 0; int compteurG = 0; int compteurB = 0; for (int i = 0; i <= 255; i++) { foreach (Pixel p in imagePixel) { ///la case i de chaque tableau contient le nombre de byte de couleur égaux à i if (hauteur * largeur > 450000)///si l'image est très grande, on ne compte qu'une fois sur 500 pour limiter la mémoire utilisée { if (p.R == (byte)(i) && compteurR % 500 == 0) { rouge[i]++; } else { compteurR++; } if (p.G == (byte)(i) && compteurG % 500 == 0) { vert[i]++; } else { compteurG++; } if (p.B == (byte)(i) && compteurB % 500 == 0) { bleu[i]++; } else { compteurB++; } } else { if (p.R == (byte)(i)) { rouge[i]++; } if (p.G == (byte)(i)) { vert[i]++; } if (p.B == (byte)(i)) { bleu[i]++; } } } } ///cherche la valeur maximale des tableaux int max = rouge[maxTableau(rouge)]; if (bleu[maxTableau(bleu)] > max) { max = bleu[maxTableau(bleu)]; } if (vert[maxTableau(vert)] > max) { max = vert[maxTableau(vert)]; } ///crée une matrice de pixel qui va contenir uniquement l'histogramme Pixel[,] histogramme = CreationMatricePixel(max, 256 * 3, 255); ///on dessine l'histogramme associé à chaque couleur for (int j = 0; j < 256; j++) { ///plus la valeur contenue dans la case j sera grande, plus la barre de pixel sera haute for (int i = 0; i < rouge[j]; i++) { histogramme[i, j] = new Pixel(255, 0, 0); } } for (int j = 256; j < 512; j++) { for (int i = 0; i < vert[j - 256]; i++) { histogramme[i, j] = new Pixel(0, 255, 0); } } for (int j = 512; j < histogramme.GetLength(1); j++) { for (int i = 0; i < bleu[j - 512]; i++) { histogramme[i, j] = new Pixel(0, 0, 255); } } ///on ramène la hauteur de l'histogramme à 100 pour avoir la même taille pour toutes les images histogramme = ChangerTailleMatrice(100d / max, 1, histogramme); #endregion #region on fusionne l'histogramme qu'on vient de créer avec l'image originelle ///on veut mettre l'histogramme en dessous de l'image originelle donc on doit rajouter 100 pixels à hauteur hauteur = 100 + hauteur; ///la largeur doit être supérieur à la largeur de l'histogramme while (largeur < 768) { largeur++; } ///on ajuste les attributs de l'image int largeurmultiple4 = largeur * (bitparcouleur / 8); padding = 0; if ((largeur * (bitparcouleur / 8)) % 4 != 0) { //rajoute un octet à la fin de la ligne tant que la largeur n'est pas multiple de 4 et retient le décalage (padding) while (largeurmultiple4 % 4 != 0) { padding++; largeurmultiple4++; } } taille = (hauteur * largeur * (bitparcouleur / 8)) + hauteur * padding + tailleOffset; Pixel[,] clone = cloneImage(imagePixel); imagePixel = CreationMatricePixel(hauteur, largeur, 255); ///on remplit d'abord avec l'image de base for (int i = 0; i < clone.GetLength(0); i++) { for (int j = 0; j < clone.GetLength(1); j++) { imagePixel[hauteur - 1 - i, j].R = clone[clone.GetLength(0) - 1 - i, j].R; imagePixel[hauteur - 1 - i, j].G = clone[clone.GetLength(0) - 1 - i, j].G; imagePixel[hauteur - 1 - i, j].B = clone[clone.GetLength(0) - 1 - i, j].B; } } ///on rajoute ensuite l'histogramme en dessous for (int i = 0; i < histogramme.GetLength(0); i++) { for (int j = 0; j < histogramme.GetLength(1); j++) { imagePixel[i, j].R = histogramme[i, j].R; imagePixel[i, j].G = histogramme[i, j].G; imagePixel[i, j].B = histogramme[i, j].B; } } #endregion }
public MyImage(string myfile) ///récupère les informations de l'image bitmap à partir du nom du fichier { byte[] tab = File.ReadAllBytes(myfile); //récupère les byte du fichier byte[] t2 = new byte[2]; byte[] t4 = new byte[4]; #region definition caractéristiques image for (int m = 0; m < 2; m++) { t2[m] = tab[m]; } type = ASCIIEncoding.ASCII.GetString(t2); for (int m = 2; m < 6; m++) { t4[m - 2] = tab[m]; } taille = Convertir_Endian_To_Int(t4); for (int m = 10; m < 14; m++) { t4[m - 10] = tab[m]; } tailleOffset = Convertir_Endian_To_Int(t4); for (int m = 18; m < 22; m++) { t4[m - 18] = tab[m]; } largeur = Convertir_Endian_To_Int(t4); for (int m = 22; m < 26; m++) { t4[m - 22] = tab[m]; } hauteur = Convertir_Endian_To_Int(t4); for (int m = 28; m < 30; m++) { t2[m - 28] = tab[m]; } bitparcouleur = Convertir_Endian_To_Int(t2); #endregion #region remplissage matrice de pixel int y = tailleOffset; bool fini = false; int ligne = 0; int colonne = 0; imagePixel = new Pixel[hauteur, largeur]; int largeurmultiple4 = largeur * (bitparcouleur / 8);//bitparcouleur/8 sert à avoir le nombre d'octet par pixel padding = 0; if ((largeur * (bitparcouleur / 8)) % 4 != 0) { //rajoute un octet à la fin de la ligne tant que la largeur n'est pas multiple de 4 et retient le décalage (padding) while (largeurmultiple4 % 4 != 0) { padding++; largeurmultiple4++; } } do { if (colonne == largeur + padding)//quand on arrive à la fin de la ligne on remet les colonnes à zéro et on incrémente les lignes { colonne = 0; ligne++; } else { if (y + 2 < tab.Length && ligne < hauteur) //on vérifie si on est arrivé à la fin du tableau { if (colonne < largeur) //tant qu'on est dans la largeur théorique (sans le padding) on récupère les octets 3 par 3 { imagePixel[ligne, colonne] = new Pixel(tab[y + 2], tab[y + 1], tab[y]); y = y + (bitparcouleur / 8); colonne++; } else//si on est dans le padding on augmente y et colonne mais on ne remplit pas la matrice { colonne++; y++; } } else { fini = true; //pour sortir des boucles } } } while (fini == false); #endregion }