/// <summary> /// Permet de coder une image dans une image puis de la décoder dans le second temps /// </summary> /// <param name="a"> l'image selectionner par l'utilisateur</param> public void ImageCoderetDecoder(MyImage a) { Pixel[,] matcache = ImageCache(a); Pixel[,] mat = new Pixel[a.matRGB.GetLength(0), a.matRGB.GetLength(1)]; int[] binaireR = new int[8]; int[] binaireG = new int[8]; int[] binaireB = new int[8]; int[] ConcatenationR = new int[8]; int[] ConcatenationG = new int[8]; int[] ConcatenationB = new int[8]; for (int i = 0; i < mat.GetLength(0); i++) { for (int j = 0; j < mat.GetLength(1); j++) { mat[i, j] = new Pixel(255, 255, 255); } } for (int i = 0; i < a.matRGB.GetLength(0); i++) { for (int j = 0; j < a.matRGB.GetLength(1); j++) { binaireR = ConvertisseurDecenBinaire(matcache[i, j].red); binaireG = ConvertisseurDecenBinaire(matcache[i, j].green); binaireB = ConvertisseurDecenBinaire(matcache[i, j].blue); for (int x = 0; x < 8; x++) // on vient chercher le sbits cachés de 4 à 8 qu'on met en 0 à 4 { if (x < 4) { ConcatenationR[x] = binaireR[x + 4]; ConcatenationG[x] = binaireG[x + 4]; ConcatenationB[x] = binaireB[x + 4]; } else if (4 <= x) { ConcatenationR[x] = 0; // on remplit le reste à 0 puisqu'on à plus le reste de 4 à 8 ConcatenationG[x] = 0; ConcatenationB[x] = 0; } } mat[i, j].red = ConvertisseurBinaireenDec(ConcatenationR); mat[i, j].green = ConvertisseurBinaireenDec(ConcatenationG); mat[i, j].blue = ConvertisseurBinaireenDec(ConcatenationB); } } for (int i = 0; i < matRGB.GetLength(0); i++) // on met l'image en blanc { for (int j = 0; j < matRGB.GetLength(1); j++) { matRGB[i, j] = new Pixel(255, 255, 255); } } for (int i = 0; i < mat.GetLength(0); i++) // on remplit avec ce qu'on à récuperé juste avant { for (int j = 0; j < mat.GetLength(1); j++) { matRGB[i, j] = mat[i, j]; } } }
/// <summary> /// Permet d'appliquer un filtre en choisissant le noyau correspondant au filtre et l'applique à la matrice de pixel par le procédé de la matrice de convolution /// </summary> /// <param name="NoyauM"> Matrice d'entier correspondant au noyaux qui applique le filtre à l'image </param> public void MatriceConvolution(int[,] NoyauM) { int AccumRed = 0; int AccumGreen = 0; int AccumBlue = 0; int somme = 0; int diviseur = 0; Pixel[,] MatriceRGBcopie = new Pixel[matRGB.GetLength(0), matRGB.GetLength(1)]; Pixel[,] MatriceRGBetendue = new Pixel[matRGB.GetLength(0) + 1, matRGB.GetLength(1) + 1]; // instanciation mat copie for (int i = 0; i < MatriceRGBcopie.GetLength(0); i++) { for (int j = 0; j < MatriceRGBcopie.GetLength(1); j++) { MatriceRGBcopie[i, j] = new Pixel(255, 255, 255); } } // instanciation mat etendue for (int i = 0; i < MatriceRGBetendue.GetLength(0); i++) { for (int j = 0; j < MatriceRGBetendue.GetLength(1); j++) { MatriceRGBetendue[i, j] = new Pixel(255, 255, 255); } } #region matetendu MatriceRGBetendue[0, 0] = matRGB[0, 0]; MatriceRGBetendue[0, MatriceRGBetendue.GetLength(1) - 1] = matRGB[0, matRGB.GetLength(1) - 1]; MatriceRGBetendue[MatriceRGBetendue.GetLength(0) - 1, 0] = matRGB[matRGB.GetLength(0) - 1, 0]; MatriceRGBetendue[MatriceRGBetendue.GetLength(0) - 1, MatriceRGBetendue.GetLength(1) - 1] = matRGB[matRGB.GetLength(0) - 1, matRGB.GetLength(1) - 1]; // on remplit les quatres coins for (int j = 1; j < MatriceRGBetendue.GetLength(1) - 1; j++) // on remplit la ligne superieur { MatriceRGBetendue[0, j] = matRGB[0, j - 1]; } for (int j = 1; j < MatriceRGBetendue.GetLength(1) - 1; j++) // on remplit la ligne inferieur { MatriceRGBetendue[MatriceRGBetendue.GetLength(0) - 1, j] = matRGB[matRGB.GetLength(0) - 1, j - 1]; } for (int i = 1; i < MatriceRGBetendue.GetLength(0) - 1; i++) // on remplit la ligne superieur { MatriceRGBetendue[i, 0] = matRGB[i - 1, 0]; } for (int i = 1; i < MatriceRGBetendue.GetLength(0) - 1; i++) // on remplit la ligne superieur { MatriceRGBetendue[i, MatriceRGBetendue.GetLength(1) - 1] = matRGB[i - 1, matRGB.GetLength(1) - 1]; } //remplissage de toute la matrice (l'interieur ) for (int i = 1; i < matRGB.GetLength(0); i++) { for (int j = 1; j < matRGB.GetLength(1); j++) { MatriceRGBetendue[i, j] = matRGB[i - 1, j - 1]; } } #endregion // travail sur somme et diviseur noyau for (int i = 0; i < NoyauM.GetLength(0); i++) { for (int j = 0; j < NoyauM.GetLength(1); j++) { somme = somme + NoyauM[i, j]; } } if (somme > 0) { diviseur = somme; } else { diviseur = 1; } for (int i = 1; i < matRGB.GetLength(0); i++) { for (int j = 1; j < matRGB.GetLength(1); j++) // parcours toute la matrice { AccumRed = 0; AccumGreen = 0; AccumBlue = 0; int LigneN = 0; int ColonneN = 0; #region Cas général for (int a = i - 1; a < i + 2; a++) { for (int b = j - 1; b < j + 2; b++) //parcours le tour du point selectionné { AccumRed = AccumRed + MatriceRGBetendue[a, b].red * NoyauM[LigneN, ColonneN]; AccumGreen = AccumGreen + MatriceRGBetendue[a, b].green * NoyauM[LigneN, ColonneN]; AccumBlue = AccumBlue + MatriceRGBetendue[a, b].blue * NoyauM[LigneN, ColonneN]; ColonneN++; } ColonneN = 0; LigneN++; } #endregion if (AccumRed / diviseur > 255) { MatriceRGBcopie[i, j].red = 255; MatriceRGBcopie[i - 1, j - 1].red = 255; } else if (AccumRed / diviseur < 0) { MatriceRGBcopie[i, j].red = 0; MatriceRGBcopie[i - 1, j - 1].red = 0; } else { MatriceRGBcopie[i, j].red = AccumRed / diviseur; MatriceRGBcopie[i - 1, j - 1].red = AccumRed / diviseur; } if (AccumGreen / diviseur > 255) { MatriceRGBcopie[i, j].green = 255; MatriceRGBcopie[i - 1, j - 1].green = 255; } else if (AccumGreen / diviseur < 0) { MatriceRGBcopie[i, j].green = 0; MatriceRGBcopie[i - 1, j - 1].green = 0; } else { MatriceRGBcopie[i, j].green = AccumGreen / diviseur; MatriceRGBcopie[i - 1, j - 1].green = AccumGreen / diviseur; } if (AccumBlue / diviseur > 255) { MatriceRGBcopie[i, j].blue = 255; MatriceRGBcopie[i - 1, j - 1].blue = 255; } else if (AccumBlue / diviseur < 0) { MatriceRGBcopie[i, j].blue = 0; MatriceRGBcopie[i - 1, j - 1].blue = 0; } else { MatriceRGBcopie[i, j].blue = AccumBlue / diviseur; MatriceRGBcopie[i - 1, j - 1].blue = AccumBlue / diviseur; } } } MatriceRGBcopie[MatriceRGBcopie.GetLength(0) - 1, 0] = MatriceRGBcopie[MatriceRGBcopie.GetLength(0) - 1, 1]; // on remplit manuellement LE pixel du coing gauche car ne se remplit pas seul for (int i = 0; i < matRGB.GetLength(0); i++) { for (int j = 0; j < matRGB.GetLength(1); j++) { matRGB[i, j].red = MatriceRGBcopie[i, j].red; matRGB[i, j].green = MatriceRGBcopie[i, j].green; matRGB[i, j].blue = MatriceRGBcopie[i, j].blue; } } }
/// <summary> /// Permet de réaliser l'histogramme de l'image sélectionner au préalable par l'utilisateur /// </summary> /// public void Histogramme() { int[] tab = new int[256 * 3]; Pixel a = new Pixel(255, 255, 255); int hauteur = 0; for (int i = 0; i < tab.Length; i++) // on initialise le tableau { tab[i] = 0; } for (int i = 0; i < matRGB.GetLength(0); i++) { for (int j = 0; j < matRGB.GetLength(1); j++) // on parcourt la matrice et pour la valeur du pixel correspondante à l'index on ajoute 1 à l'index du talbeau pour savoir combien de fois elle est presente dans la matrice. { tab[matRGB[i, j].red] = tab[matRGB[i, j].red] + 1; tab[256 + matRGB[i, j].green] = tab[256 + matRGB[i, j].green] + 1; tab[512 + matRGB[i, j].blue] = tab[512 + matRGB[i, j].blue] + 1; } } for (int i = 0; i < tab.Length; i++) { if (hauteur < tab[i]) // on definit le max de hauteur de l'image de l'histogramme { hauteur = tab[i]; } } hauteurI = hauteur; largeurI = 768; tailleF = hauteurI * largeurI * 3 + tailleO; matRGB = new Pixel[hauteurI, largeurI]; for (int i = 0; i < matRGB.GetLength(0); i++) // on initialise la nouvelle matrice redimenssionner de l'image en blanc { for (int j = 0; j < matRGB.GetLength(1); j++) { matRGB[i, j] = a; } } for (int j = 0; j < matRGB.GetLength(1); j++) // on parcourt toutes les colonnes et on remplit chaque couleur de pixel correspondante { int accum2 = 0; while (tab[j] != 0) { if (j < 256) { matRGB[0 + accum2, j] = new Pixel(j, 0, 0); } else if (j < 512) { matRGB[0 + accum2, j] = new Pixel(0, j - 256, 0); } else if (j < 768) { matRGB[0 + accum2, j] = new Pixel(0, 0, j - 512); } tab[j]--; accum2++; } } }
/// <summary> /// Constructeur MyImage a partir du nom de l'image: myfile /// </summary> /// <param name="myfile"> string nom de l'image à ouvrir</param> public MyImage(string myfile) { this.myfile = myfile; byte[] FileByte = File.ReadAllBytes(myfile); byte[] tab = new byte[4]; // initialisation des differentes variables en fonctions des différents Bytes // les 2 premiers octets si 66 et 77 = format bitmap if (FileByte[0] == 66 && FileByte[1] == 77) { typeI = "bmp"; } else { typeI = "Autre que bmp"; } for (int i = 2; i < 6; i++) { tab[i - 2] = FileByte[i]; // taille Fichier } tailleF = Convertir_endian_to_int(tab); for (int i = 10; i < 14; i++) { tab[i - 10] = FileByte[i]; // taille offset } tailleO = Convertir_endian_to_int(tab); for (int i = 18; i < 22; i++) { tab[i - 18] = FileByte[i]; // largeur } largeurI = Convertir_endian_to_int(tab); for (int i = 22; i < 26; i++) { tab[i - 22] = FileByte[i]; // hauteur image } hauteurI = Convertir_endian_to_int(tab); for (int i = 28; i < 30; i++) { tab[i - 28] = FileByte[i]; // nb bit couleur } bitC = Convertir_endian_to_int(tab); int compteur = 54; matRGB = new Pixel[hauteurI, largeurI]; for (int i = 0; i < matRGB.GetLength(0); i++) { for (int j = 0; j < matRGB.GetLength(1); j++) { int taille = FileByte.Length; int red = FileByte[compteur]; int green = FileByte[compteur + 1]; int blue = FileByte[compteur + 2]; matRGB[i, j] = new Pixel(blue, green, red); // remplissage matrice de pixel BGR (blue green red car inversé); compteur = compteur + 3; } } }