public MyImage Fractale(int choixFractale, int choixCouleur) { MyImage fractale = new MyImage("tigre.bmp"); //SETTINGS pour le cadrage de l'image double x1; double x2; double y1; double y2; if (choixFractale == 1) { x1 = -2.1; x2 = 0.6; y1 = -1.2; y2 = 1.2; } else { x1 = -1; x2 = 1; y1 = -1.2; y2 = 1.2; } int zoom = 1000; //zoom idéal pour l'affichage de l'image int iterationMax = 100; int image_x = Convert.ToInt32((x2 - x1) * zoom); int image_y = Convert.ToInt32((y2 - y1) * zoom); while (image_y % 4 != 0 || image_x % 4 != 0) { if (image_x % 4 != 0) { image_x++; } if (image_y % 4 != 0) { image_y++; } } fractale.height = image_x; fractale.width = image_y; fractale.size = fractale.height * fractale.width * 3 + 54; fractale.imageMatrix = new Pixel[image_x, image_y]; Pixel noir = new Pixel(0, 0, 0); Pixel blanc = new Pixel(255, 255, 255); for (int x = 0; x < image_x; x++) { for (int y = 0; y < image_y; y++) { double val_x = x; double val_y = y; byte i = 0; if (choixFractale == 1) { Complex c = new Complex(val_x / zoom + x1, val_y / zoom + y1); Complex z = new Complex(0, 0); /*-0.70176; -0.3842; */ do { i = (byte)(i + 1); z.Square(); z.Add(c); } while (z.Test() < 4 && i < iterationMax); } else if (choixFractale == 2) //JULIA SET 1 { Complex c = new Complex(val_x / zoom + x1, val_y / zoom + y1); Complex z = new Complex(-0.4, 0.6); do { i = (byte)(i + 1); c.Square(); c.Add(z); } while (c.Test() < 4 && i < iterationMax); } else //JULIA SET 2 { Complex c = new Complex(val_x / zoom + x1, val_y / zoom + y1); Complex z = new Complex(-0.70176, -0.3842); do { i = (byte)(i + 1); c.Square(); c.Add(z); } while (c.Test() < 4 && i < iterationMax); } if (i == iterationMax) { fractale.imageMatrix[x, y] = noir; //new Pixel(255,255,255) pour du blanc; } else { //set par défaut Pixel couleur = new Pixel(Convert.ToByte((Math.Sqrt(i * 655))), Convert.ToByte((Math.Sqrt(i * 655))), Convert.ToByte((Math.Sqrt(i * 655)))); if (choixCouleur == 2) //blue set { couleur = new Pixel(Convert.ToByte((Math.Sqrt(i * 655))), 0, 0); } if (choixCouleur == 3) //green set { couleur = new Pixel(0, Convert.ToByte((Math.Sqrt(i * 655))), 0); } if (choixCouleur == 4) //red set { couleur = new Pixel(0, 0, Convert.ToByte((Math.Sqrt(i * 655)))); } if (choixCouleur == 5) { if (i <= 20) //blue set { couleur = new Pixel(Convert.ToByte((Math.Sqrt(i * 655))), 0, 0); } else if (20 <= i && i <= 50) //green set { couleur = new Pixel(0, Convert.ToByte((Math.Sqrt(i * 655))), 0); } else //red set { couleur = new Pixel(0, 0, Convert.ToByte((Math.Sqrt(i * 655)))); } } fractale.imageMatrix[x, y] = couleur; } } } return(fractale); }
/// <summary> /// Creates an histogragram of the picture /// </summary> public void Histo() { // Nombre d'occurence de chaque valeur de pixel int[] maxR = new int[256]; int[] maxG = new int[256]; int[] maxB = new int[256]; int max = 0; // Compte le nombre d'occurence de chaque valeur de pixel for (int i = 0; i < this.height; i++) { for (int j = 0; j < this.width; j++) { maxR[this.imageMatrix[i, j].R]++; maxG[this.imageMatrix[i, j].G]++; maxB[this.imageMatrix[i, j].B]++; } } for (int j = 0; j < 256; j++) { if (maxR[j] > max) { max = maxR[j]; } if (maxG[j] > max) { max = maxG[j]; } if (maxB[j] > max) { max = maxB[j]; } } // Remplit l'histogramme de pixels noirs Pixel[,] histo = new Pixel[100, 256]; for (int i = 0; i < histo.GetLength(0); i++) { for (int j = 0; j < histo.GetLength(1); j++) { histo[i, j] = new Pixel(0, 0, 0); } } for (int i = 0; i < 256; i++) { for (int j = 0; j < maxR[i] * 100 / max; j++) { histo[j, i] = new Pixel(255, 0, 0); } for (int j = 0; j < maxG[i] * 100 / max; j++) { if (histo[j, i].R == 0) { histo[j, i] = new Pixel(0, 255, 0); } else { histo[j, i] = new Pixel(255, 100, 0); } } for (int j = 0; j < maxB[i] * 100 / max; j++) { if (histo[j, i].R == 0 & histo[j, i].G == 0) { histo[j, i] = new Pixel(0, 0, 255); } else if (histo[j, i].R > 0 & histo[j, i].G == 0) { histo[j, i] = new Pixel(255, 0, 100); } else if (histo[j, i].R == 0 & histo[j, i].G > 0) { histo[j, i] = new Pixel(0, 255, 100); } } } this.height = histo.GetLength(0); this.width = histo.GetLength(1); this.imageMatrix = histo; }
/// <summary> /// Applique une matrice de convolution à l'image /// </summary> /// <param name="mat">Matrice de convolution</param> public void Convolution(int[,] mat, bool flou) { // Code très moche mais qui marche (pardon) // Faire un code optimisé avec 4 boucle pour créait un décalage au niveau des index // Pas le temps de l'améliorer plus // Nouvelles composantes RGB int newRed = 0; int newGreen = 0; int newBlue = 0; // Matrice après convolution Pixel[,] afterConvo = new Pixel[this.height, this.width]; // Matrice temporaire pour pallier aux dépassements Pixel[,] tmp = new Pixel[this.height + 2, this.width + 2]; // On duplique les contours dans la matrice temp for (int i = 1; i < this.width + 1; i++) { tmp[0, i] = imageMatrix[0, i - 1]; } for (int i = 1; i < this.height + 1; i++) { tmp[i, 0] = imageMatrix[i - 1, 0]; } for (int i = 1; i < this.width + 1; i++) { tmp[this.height + 1, i] = imageMatrix[this.height - 1, i - 1]; } for (int i = 1; i < this.height + 1; i++) { tmp[i, this.width + 1] = imageMatrix[i - 1, this.width - 1]; } // On place la matrice initiale dans la temp for (int i = 1; i < this.height + 1; i++) { for (int j = 1; j < this.width + 1; j++) { tmp[i, j] = this.imageMatrix[i - 1, j - 1]; } } // On duplique les coins dans la temp tmp[0, 0] = this.imageMatrix[0, 0]; tmp[0, width + 1] = this.imageMatrix[0, width - 1]; tmp[height + 1, width + 1] = this.imageMatrix[height - 1, width - 1]; tmp[height + 1, 0] = this.imageMatrix[height - 1, 0]; // CONVOLUTION for (int i = 1; i < tmp.GetLength(0) - 1; i++) { for (int j = 1; j < tmp.GetLength(1) - 1; j++) { newRed = tmp[i - 1, j - 1].B * mat[0, 0] + tmp[i - 1, j].B * mat[0, 1] + tmp[i - 1, j + 1].B * mat[0, 2] + tmp[i, j - 1].B * mat[1, 0] + tmp[i, j].B * mat[1, 1] + tmp[i, j + 1].B * mat[1, 2] + tmp[i + 1, j - 1].B * mat[2, 0] + tmp[i + 1, j].B * mat[2, 1] + tmp[i + 1, j + 1].B * mat[2, 2]; newGreen = tmp[i - 1, j - 1].G * mat[0, 0] + tmp[i - 1, j].G * mat[0, 1] + tmp[i - 1, j + 1].G * mat[0, 2] + tmp[i, j - 1].G * mat[1, 0] + tmp[i, j].G * mat[1, 1] + tmp[i, j + 1].G * mat[1, 2] + tmp[i + 1, j - 1].G * mat[2, 0] + tmp[i + 1, j].G * mat[2, 1] + tmp[i + 1, j + 1].G * mat[2, 2]; newBlue = tmp[i - 1, j - 1].R * mat[0, 0] + tmp[i - 1, j].R * mat[0, 1] + tmp[i - 1, j + 1].R * mat[0, 2] + tmp[i, j - 1].R * mat[1, 0] + tmp[i, j].R * mat[1, 1] + tmp[i, j + 1].R * mat[1, 2] + tmp[i + 1, j - 1].R * mat[2, 0] + tmp[i + 1, j].R * mat[2, 1] + tmp[i + 1, j + 1].R * mat[2, 2]; if (flou) { newRed /= 9; newGreen /= 9; newBlue /= 9; } // On borne les valeurs newRed = newRed > 255 ? 255 : newRed; newRed = newRed < 0 ? 0 : newRed; newGreen = newGreen > 255 ? 255 : newGreen; newGreen = newGreen < 0 ? 0 : newGreen; newBlue = newBlue > 255 ? 255 : newBlue; newBlue = newBlue < 0 ? 0 : newBlue; // Remplissage de la nouvelle matrice afterConvo[i - 1, j - 1] = new Pixel((byte)(newBlue), (byte)(newGreen), (byte)(newRed)); } } this.imageMatrix = afterConvo; }