Commit bef5662b authored by BORNON Théophile's avatar BORNON Théophile

Begining of enlarge gradient. Enlarge done

parent 7531c00a
...@@ -27,22 +27,14 @@ namespace S04_Projet ...@@ -27,22 +27,14 @@ namespace S04_Projet
private short[,] filter; private short[,] filter;
private double factor; private double factor;
private int size; private int size;
//private double stepSize;
private Operation ToDo;
#endregion #endregion
public void SetNbPixel(int nbPixel) => this.nbPixel = nbPixel; public void SetNbPixel(int nbPixel) => this.nbPixel = nbPixel;
public void SetFile(byte[] file) => this.file = file; public void SetFile(byte[] file) => this.file = file;
private Operation ToDo;
public MultiThreadedTask(Operation ToDo, byte[] file, Options opt)
{
this.ToDo = ToDo;
this.opt = opt;
this.file = file;
nbPixel = opt.width * opt.height;
nbProcessors = Environment.ProcessorCount;
}
public unsafe MultiThreadedTask(Operation ToDo, byte* rPixelPtr, byte* gPixelPtr, byte* bPixelPtr, Options opt, short[,] filter, double factor) public unsafe MultiThreadedTask(Operation ToDo, byte* rPixelPtr, byte* gPixelPtr, byte* bPixelPtr, Options opt, short[,] filter, double factor)
{ {
...@@ -58,21 +50,33 @@ namespace S04_Projet ...@@ -58,21 +50,33 @@ namespace S04_Projet
nbProcessors = 4; nbProcessors = 4;
} }
public unsafe MultiThreadedTask(Operation ToDo, Options opt, byte* rPixelPtr, byte* gPixelPtr, byte* bPixelPtr)
{
this.ToDo = ToDo;
this.rPixelPtr = rPixelPtr;
this.gPixelPtr = gPixelPtr;
this.bPixelPtr = bPixelPtr;
nbPixel = opt.width * opt.height;
}
#region Filter #region Filter
public MyImage ApplyFilter() public MyImage ApplyFilter()
{ {
int nbPixel = opt.width * opt.height;
int pixelPerThread = nbPixel / nbProcessors; int pixelPerThread = nbPixel / nbProcessors;
NewRMatrix = new byte[nbPixel]; NewRMatrix = new byte[nbPixel];
NewGMatrix = new byte[nbPixel]; NewGMatrix = new byte[nbPixel];
NewBMatrix = new byte[nbPixel]; NewBMatrix = new byte[nbPixel];
//stepSize = (Math.E - 1) / nbProcessors;
Thread[] threads = new Thread[nbProcessors]; Thread[] threads = new Thread[nbProcessors];
Console.WriteLine("Creating {0} thread(s)", nbProcessors); Console.WriteLine("Creating {0} thread(s)", nbProcessors);
for (int i = 0; i < nbProcessors; i++) for (int i = 0; i < nbProcessors; i++)
{ {
threads[i] = new Thread(new ParameterizedThreadStart(ApplyFilterTask)); threads[i] = new Thread(new ParameterizedThreadStart(ApplyFilterTask));
//double param = 1 + i * stepSize;
threads[i].Start(i); threads[i].Start(i);
} }
...@@ -87,8 +91,19 @@ namespace S04_Projet ...@@ -87,8 +91,19 @@ namespace S04_Projet
private unsafe void ApplyFilterTask(object i) private unsafe void ApplyFilterTask(object i)
{ {
int x, y; int x, y;
int start = opt.width * opt.height / nbProcessors * (int)i; int nbPixel = opt.width * opt.height;
int end = opt.width * opt.height / nbProcessors * ((int)i + 1); int start = nbPixel / nbProcessors * (int)i;
int end = nbPixel / nbProcessors * ((int)i + 1);
/*double param = (double)i;
int start = (int)(Math.Log(param) * nbPixel);
int end;
if (param + stepSize < Math.E) end = (int)(Math.Log(param + stepSize) * nbPixel);
else end = nbPixel;
Console.WriteLine((double)i + "Start : " + start);
Console.WriteLine((double)i + "End : " + end);*/
byte[,] rMatrix = new byte[size, size]; byte[,] rMatrix = new byte[size, size];
byte[,] gMatrix = new byte[size, size]; byte[,] gMatrix = new byte[size, size];
byte[,] bMatrix = new byte[size, size]; byte[,] bMatrix = new byte[size, size];
......
...@@ -6,6 +6,7 @@ namespace S04_Projet ...@@ -6,6 +6,7 @@ namespace S04_Projet
{ {
public class MyImage public class MyImage
{ {
#region Attributs
private Options opt; private Options opt;
byte[] rPixels, gPixels, bPixels; byte[] rPixels, gPixels, bPixels;
byte[] file; byte[] file;
...@@ -23,12 +24,9 @@ namespace S04_Projet ...@@ -23,12 +24,9 @@ namespace S04_Projet
G, G,
B B
} }
#endregion
public Options GetOptions() #region Constructeurs & Save
{
return opt;
}
/// <summary> /// <summary>
/// Constructeur prenant en paramètre un chemin vers un fichier BMP 24 bits /// Constructeur prenant en paramètre un chemin vers un fichier BMP 24 bits
/// </summary> /// </summary>
...@@ -207,166 +205,371 @@ namespace S04_Projet ...@@ -207,166 +205,371 @@ namespace S04_Projet
{ {
FromImageToFile(output); FromImageToFile(output);
} }
/* #endregion
#region Rotations #region Rotations
/// <summary> /// <summary>
/// Tourne l'image de 90° dans le sens horaire /// Tourne l'image de 90° dans le sens horaire
/// </summary> /// </summary>
/// <returns>Image tournée de 90° dans le sens horaire</returns> /// <returns>Image tournée de 90° dans le sens horaire</returns>
public MyImage Rotate90() public unsafe MyImage Rotate90()
{ {
Options options = opt.Copy(); Options options = opt.Copy();
options.width = opt.height; options.width = opt.height;
options.height = opt.width; options.height = opt.width;
Pixel[,] PixelArr = new Pixel[options.width, options.height];
for (int i = 0; i < options.width * options.height; i++) int size = opt.height * opt.width;
byte[] newRPixel = new byte[size];
byte[] newGPixel = new byte[size];
byte[] newBPixel = new byte[size];
fixed (byte* newRPixePtr = newRPixel, newGPixePtr = newGPixel, newBPixePtr = newBPixel)
{ {
int x = i % opt.width; fixed (byte* rPtr = rPixels, gPtr = gPixels, bPtr = bPixels)
int y = i / opt.width; {
PixelArr[y, options.height - 1 - x] = Pixels[x, y]; for (int i = 0; i < size; i++)
{
int x = i % opt.width;
int y = i / opt.width;
*(newRPixePtr + y + (options.height - 1 - x) * options.width) = *(rPtr + i);
*(newGPixePtr + y + (options.height - 1 - x) * options.width) = *(gPtr + i);
*(newBPixePtr + y + (options.height - 1 - x) * options.width) = *(bPtr + i);
}
}
} }
return new MyImage(options, PixelArr); return new MyImage(options, newRPixel, newGPixel, newBPixel);
} }
/// <summary> /// <summary>
/// Tourne l'image de 180° dans le sens horaire /// Tourne l'image de 180° dans le sens horaire
/// </summary> /// </summary>
/// <returns>Image tournée de 180° dans le sens horaire</returns> /// <returns>Image tournée de 180° dans le sens horaire</returns>
public MyImage Rotate180() public unsafe MyImage Rotate180()
{ {
Options options = opt.Copy(); Options options = opt.Copy();
Pixel[,] PixelArr = new Pixel[options.width, options.height]; int size = opt.height * opt.width;
for (int i = 0; i < options.width * options.height; i++)
byte[] newRPixel = new byte[size];
byte[] newGPixel = new byte[size];
byte[] newBPixel = new byte[size];
fixed (byte* newRPixePtr = newRPixel, newGPixePtr = newGPixel, newBPixePtr = newBPixel)
{ {
int x = i % opt.width; fixed (byte* rPtr = rPixels, gPtr = gPixels, bPtr = bPixels)
int y = i / opt.width; {
PixelArr[options.width - x - 1, options.height - y - 1] = Pixels[x, y]; for (int i = 0; i < options.width * options.height; i++)
{
int x = i % opt.width;
int y = i / opt.width;
*(newRPixePtr - x - 1 + (options.height - y) * options.width) = *(rPtr + i);
*(newGPixePtr - x - 1 + (options.height - y) * options.width) = *(gPtr + i);
*(newBPixePtr - x - 1 + (options.height - y) * options.width) = *(bPtr + i);
}
}
} }
return new MyImage(options, PixelArr); return new MyImage(options, newRPixel, newGPixel, newBPixel);
} }
/// <summary> /// <summary>
/// Tourne l'image de 270° dans le sens horaire /// Tourne l'image de 270° dans le sens horaire
/// </summary> /// </summary>
/// <returns>Image tournée de 270° dans le sens horaire</returns> /// <returns>Image tournée de 270° dans le sens horaire</returns>
public MyImage Rotate270() public unsafe MyImage Rotate270()
{ {
Options options = opt.Copy(); Options options = opt.Copy();
options.width = opt.height; options.width = opt.height;
options.height = opt.width; options.height = opt.width;
Pixel[,] PixelArr = new Pixel[options.width, options.height]; int size = opt.height * opt.width;
for (int i = 0; i < options.width * options.height; i++)
byte[] newRPixel = new byte[size];
byte[] newGPixel = new byte[size];
byte[] newBPixel = new byte[size];
fixed (byte* newRPixePtr = newRPixel, newGPixePtr = newGPixel, newBPixePtr = newBPixel)
{ {
int x = i % opt.width; fixed (byte* rPtr = rPixels, gPtr = gPixels, bPtr = bPixels)
int y = i / opt.width; {
PixelArr[options.width - 1 - y, x] = Pixels[x, y]; for (int i = 0; i < options.width * options.height; i++)
{
int x = i % opt.width;
int y = i / opt.width;
*(newRPixePtr + options.width - 1 - y + x * options.width) = *(rPtr + i);
*(newGPixePtr + options.width - 1 - y + x * options.width) = *(gPtr + i);
*(newBPixePtr + options.width - 1 - y + x * options.width) = *(bPtr + i);
//PixelArr[options.width - 1 - y, x] = Pixels[x, y];
}
}
} }
return new MyImage(options, PixelArr);
return new MyImage(options, newRPixel, newGPixel, newBPixel);
} }
#endregion #endregion
*/
/// <summary> /// <summary>
/// Agrandit l'image par rapport au coefficient passé en paramètre. WIP /// Agrandit l'image par rapport au coefficient passé en paramètre
/// </summary> /// </summary>
/// <param name="coeff">Coefficient d'agrandissement de l'image</param> /// <param name="coeff">Coefficient d'agrandissement de l'image</param>
/// <returns>Image élargie</returns> /// <returns>Image élargie</returns>
/* public MyImage Enlarge(int coeff) public unsafe MyImage Enlarge(int coeff)
{ {
Options options = opt.Copy(); Options options = opt.Copy();
options.width *= coeff; options.width *= coeff;
options.height *= coeff; options.height *= coeff;
Pixel[,] PixelArr = new Pixel[opt.width * 2, opt.height * 2];
for (int i = 0; i < options.width * options.height; i++) int nbPixel = opt.width * opt.height;
{ int nbNewPixel = options.width * options.height;
int x = i % options.width;
int y = i % options.height; byte[] newPixelR = new byte[nbNewPixel];
byte[] newPixelG = new byte[nbNewPixel];
byte[] fromX = Pixels[x, y].getRGB(); byte[] newPixelB = new byte[nbNewPixel];
byte[] toX;
byte[] toY; int x, y, x0, y0;
byte[] toXY;
fixed (byte* newRPtr = newPixelR, newGPtr = newPixelG, newBPtr = newPixelB)
if (x + 1 < options.width) toX = Pixels[x + 1, y].getRGB(); {
if (y + 1 < options.height) toY = Pixels[x, y + 1].getRGB(); fixed (byte* rPtr = rPixels, gPtr = gPixels, bPtr = bPixels)
if (y + 1 < options.height && x + 1 < options.width) toXY = Pixels[x + 1, y + 1].getRGB(); {
for (int i = 0; i < nbPixel; i++)
{
} x0 = i % opt.width;
return null; y0 = i / opt.width;
}*/ for (int j = 0; j < coeff * coeff; j++)
{
x = x0 * coeff + j % coeff;
y = y0 * coeff + j / coeff;
*(newRPtr + x + y * options.width) = *(rPtr + i);
*(newGPtr + x + y * options.width) = *(gPtr + i);
*(newBPtr + x + y * options.width) = *(bPtr + i);
}
}
}
}
return new MyImage(options, newPixelR, newPixelG, newPixelB);
}
public unsafe MyImage EnlargeGradient(int coeff)
{
Options options = opt.Copy();
options.width *= coeff;
options.height *= coeff;
int nbPixel = opt.width * opt.height;
int nbNewPixel = options.width * options.height;
byte[] newPixelR = new byte[nbNewPixel];
byte[] newPixelG = new byte[nbNewPixel];
byte[] newPixelB = new byte[nbNewPixel];
int x, y, x0, y0;
fixed (byte* newRPtr = newPixelR, newGPtr = newPixelG, newBPtr = newPixelB)
{
fixed (byte* rPtr = rPixels, gPtr = gPixels, bPtr = bPixels)
{
for (int i = 0; i < nbPixel; i++)
{
x0 = i % opt.width;
y0 = i / opt.width;
for (int j = 0; j < coeff * coeff; j++)
{
x = x0 * coeff + j % coeff;
y = y0 * coeff + j / coeff;
*(newRPtr + x + y * options.width) = *(rPtr + i);
*(newGPtr + x + y * options.width) = *(gPtr + i);
*(newBPtr + x + y * options.width) = *(bPtr + i);
}
}
}
}
return new MyImage(options, newPixelR, newPixelG, newPixelB);
}
private unsafe byte[] GenerateGradient(int x, int y, int coeff, RGB rgb, byte* rPtr, byte* gPtr, byte* bPtr)
{
// cf https://stackoverflow.com/a/1106986
int squareCoeff = coeff * coeff;
byte[,] grad = new byte[squareCoeff,3];
byte[] A_RGB, B_RGB, C_RGB, D_RGB;
#region Define ABCD
int xPlus = x + 1 < opt.width ? x + 1 : x;
int yPlus = y + 1 < opt.width ? y + 1 : y;
A_RGB = new byte[] {
*(rPtr + x + y * opt.width),
*(gPtr + x + y * opt.width),
*(bPtr + x + y * opt.width)
};
B_RGB = new byte[] {
*(rPtr + xPlus + y * opt.width),
*(gPtr + xPlus + y * opt.width),
*(bPtr + xPlus + y * opt.width)
};
C_RGB = new byte[] {
*(rPtr + xPlus + yPlus * opt.width),
*(gPtr + xPlus + yPlus * opt.width),
*(bPtr + xPlus + yPlus * opt.width)
};
D_RGB = new byte[] {
*(rPtr + x + yPlus * opt.width),
*(gPtr + x + yPlus * opt.width),
*(bPtr + x + yPlus * opt.width)
};
#endregion
int x0, y0;
for (int i = 1; i < squareCoeff; i++)
{
x0 = i % coeff;
y0 = i / coeff;
}
}
/// <summary> /// <summary>
/// Rétrécit l'image par rapport au coefficient passé en paramètres /// Rétrécit l'image par rapport au coefficient passé en paramètres
/// </summary> /// </summary>
/// <param name="coeff">Coefficient de rétrécissement de l'image</param> /// <param name="coeff">Coefficient de rétrécissement de l'image</param>
/// <returns>Image rétrécie</returns> /// <returns>Image rétrécie</returns>
/* public MyImage Shrink(int coeff) public unsafe MyImage Shrink(int coeff)
{ {
Options options = opt.Copy(); Options options = opt.Copy();
options.width /= coeff; options.width /= coeff;
options.height /= coeff; options.height /= coeff;
options.padding = options.width % 4; options.padding = options.width % 4;
options.imgSize = options.width * options.height * 3 + options.padding * options.height; options.imgSize = options.width * options.height * 3 + options.padding * options.height;
options.fileSize = options.imgSize + options.fileInfoHeaderSize; options.fileSize = options.imgSize + options.fileInfoHeaderSize;
Pixel[,] PixelArr = new Pixel[options.width, options.height]; int size = options.width * options.height;
int x0, y0, x, y; byte[] newRPixel = new byte[size];
int[] rgb; byte[] newGPixel = new byte[size];
byte[] _rgb; byte[] newBPixel = new byte[size];
for (int i = 0; i < options.width * options.height; i++) int x0, y0, x, y;
{ int r, g, b;
x0 = i % options.width; fixed (byte* newRPixePtr = newRPixel, newGPixePtr = newGPixel, newBPixePtr = newBPixel)
y0 = i / options.width; {
fixed (byte* rPtr = rPixels, gPtr = gPixels, bPtr = bPixels)
{
for (int i = 0; i < size; i++)
{
x0 = i % options.width;
y0 = i / options.width;
rgb = new int[] { 0, 0, 0 }; r = g = b = 0;
for (int j = 0; j < coeff * coeff; j++) for (int j = 0; j < coeff * coeff; j++)
{ {
x = x0 * coeff + j % coeff; x = x0 * coeff + j % coeff;
y = y0 * coeff + j / coeff; y = y0 * coeff + j / coeff;
_rgb = Pixels[x, y].getRGB(); r += *(rPtr + x + y * opt.width);
for (int k = 0; k < 3; k++) g += *(gPtr + x + y * opt.width);
rgb[k] += _rgb[k]; b += *(bPtr + x + y * opt.width);
} }
for (int j = 0; j < 3; j++) r /= coeff * coeff;
rgb[j] = (byte)(rgb[j] / (coeff * coeff)); g /= coeff * coeff;
b /= coeff * coeff;
PixelArr[x0, y0] = new Pixel(rgb); *(newRPixePtr + x0 + y0 * options.width) = (byte)r;
} *(newGPixePtr + x0 + y0 * options.width) = (byte)g;
*(newBPixePtr + x0 + y0 * options.width) = (byte)b;
}
}
}
return new MyImage(options, PixelArr); return new MyImage(options, newRPixel, newGPixel, newBPixel);
}*/ }
#region Gray tasks
/// <summary> /// <summary>
/// Passe l'image en nuances de gris /// Passe l'image en nuances de gris
/// </summary> /// </summary>
/// <param name="scale">Nombre de nuances de gris désirées (entre 2 et 255) (2 = noir et blanc)</param> /// <param name="scale">Nombre de nuances de gris désirées (entre 2 et 255) (2 = noir et blanc)</param>
/// <param name="type">Type de transformation. Linéaire ou en fonction de la luminosité de la couleur</param> /// <param name="type">Type de transformation. Linéaire ou en fonction de la luminosité de la couleur</param>
/// <returns>Image en nuances de gris</returns> /// <returns>Image en nuances de gris</returns>
/* public unsafe MyImage ToGrayScale(byte scale, GrayFilterType type)
public MyImage ToGrayScale(byte scale, GrayFilterType type) {
{ Options options = opt.Copy();
Options options = opt.Copy(); opt.nbColor = scale;
opt.nbColor = scale; int size = opt.height * opt.width;
Pixel[,] PixelArr = new Pixel[opt.width, opt.height];
for (int i = 0; i < opt.width * opt.height; i++) byte[] newRPixel = new byte[size];
{ byte[] newGPixel = new byte[size];
int x = i % opt.width; byte[] newBPixel = new byte[size];
int y = i / opt.width; fixed (byte* newRPixePtr = newRPixel, newGPixePtr = newGPixel, newBPixePtr = newBPixel)
if (type == GrayFilterType.LINEAR) {
PixelArr[x, y] = Pixels[x, y].getGrayScale(scale); fixed (byte* rPtr = rPixels, gPtr = gPixels, bPtr = bPixels)
else if (type == GrayFilterType.LUMINOSITY) {
PixelArr[x, y] = Pixels[x, y].getGrayScaleLuminosity(scale); for (int i = 0; i < opt.width * opt.height; i++)
} {
return new MyImage(options, PixelArr); int x = i % opt.width;
}*/ int y = i / opt.width;
if (type == GrayFilterType.LINEAR)
public unsafe MyImage {
Filter(short[,] filter, double factor) *(newRPixePtr + x + y * opt.width) =
*(newGPixePtr + x + y * opt.width) =
*(newBPixePtr + x + y * opt.width) = GetGray(*(rPtr + x + y * opt.width), *(gPtr + x + y * opt.width), *(bPtr + x + y * opt.width), scale);
}
else if (type == GrayFilterType.LUMINOSITY)
*(newRPixePtr + x + y * opt.width) =
*(newGPixePtr + x + y * opt.width) =
*(newBPixePtr + x + y * opt.width) = GetGrayLuminosity(*(rPtr + x + y * opt.width), *(gPtr + x + y * opt.width), *(bPtr + x + y * opt.width), scale);
}
}
}
return new MyImage(options, newRPixel, newGPixel, newBPixel);
}
/// <summary>
/// Retourne l'équavalent gris d'un pixel
/// </summary>
/// <param name="scale">Nombre de nuances de gris</param>
/// <returns>Pixel en échelle de gris</returns>
public byte GetGray(byte r, byte g, byte b, byte scale)
{
byte total = (byte)((r + g + b) / 3);
total = (byte)(Math.Round((double)total / (255 / (scale - 1))) * (255 / (scale - 1)));
return total;
}
/// <summary>
/// Retourne l'équivalent gris d'un pixel en prenant en compte les coefficients de luminosité
/// des couleurs RGB
/// </summary>
/// <param name="scale"></param>
/// <returns></returns>
public byte GetGrayLuminosity(byte r, byte g, byte b, byte scale)
{
byte total = (byte)(0.21 * r + 0.72 * g + 0.07 * b);
total = (byte)(Math.Round((double)total / (255 / (scale - 1))) * (255 / (scale - 1)));
return total;
}
#endregion
/// <summary>
/// Applique un filtre de convolution sur une image
/// </summary>
/// <param name="filter">Filtre à appliquer</param>
/// <param name="factor">Facteur de normalisation du filtre</param>
/// <returns>Image modifiée avec le filtre</returns>
public unsafe MyImage Filter(short[,] filter, double factor)
{ {
fixed (byte* rPixelPtr = rPixels, gPixelPtr = gPixels, bPixelPtr = bPixels) fixed (byte* rPixelPtr = rPixels, gPixelPtr = gPixels, bPixelPtr = bPixels)
{ {
...@@ -374,7 +577,157 @@ namespace S04_Projet ...@@ -374,7 +577,157 @@ namespace S04_Projet
return multiThreadedTask.ApplyFilter(); return multiThreadedTask.ApplyFilter();
} }
} }
/// <summary>
/// Generate the 3 histograms of the image
/// </summary>
/// <param name="width"></param>
/// <returns></returns>
public unsafe MyImage[] Histogram(int width)
{
MyImage[] Images = new MyImage[3];
int[,] numberOfRGB = new int[3, 256];
int nbPixel = opt.width * opt.height;
Options options = new Options
{
width = width,
offset = 54,
fileInfoHeaderSize = 40,
bitsPerPixel = 24,
format = "BM"
};
options.height = (int)(options.width / 1.6180339887);
options.fileSize = options.fileInfoHeaderSize + options.width * options.height * 3;
byte[] newRPixel = new byte[options.width * options.height];
byte[] newGPixel = new byte[options.width * options.height];
byte[] newBPixel = new byte[options.width * options.height];
int pixelsPerValue = options.width / 256;
fixed (int* numberOfRGBPtr = numberOfRGB)
{
fixed (byte* rPixelPtr = rPixels, gPixelPtr = gPixels, bPixelPtr = bPixels)
{
for (int i = 0; i < nbPixel; i++)
{
*(numberOfRGBPtr + *(rPixelPtr + i)) += 1;
*(numberOfRGBPtr + 256 * 1 + *(gPixelPtr + i)) += 1;
*(numberOfRGBPtr + 256 * 2 + *(bPixelPtr + i)) += 1;
}
}
int maxR = Max(numberOfRGBPtr, 256);
int maxG = Max(numberOfRGBPtr + 256, 256);
int maxB = Max(numberOfRGBPtr + 256 * 2, 256);
for (int i = 0; i < 256; i++)
{
*(numberOfRGBPtr + i) = (*(numberOfRGBPtr + i) * options.height) / maxR;
*(numberOfRGBPtr + 256 * 1 + i) = (*(numberOfRGBPtr + 256 * 1 + i) * options.height) / maxG;
*(numberOfRGBPtr + 256 * 2 + i) = (*(numberOfRGBPtr + 256 * 2 + i) * options.height) / maxB;
}
fixed (byte* newRPixelPtr = newRPixel, newGPixelPtr = newGPixel, newBPixelPtr = newBPixel)
{
for (int i = 0; i < 256; i++)
{
for (int j = 0; j < options.height; j++)
{
for (int k = 0; k < pixelsPerValue; k++)
{
if (*(numberOfRGBPtr + i) >= j) *(newRPixelPtr + i * pixelsPerValue + k + j * options.width) = 255;
if (*(numberOfRGBPtr + 256 + i) >= j) *(newGPixelPtr + i * pixelsPerValue + k + j * options.width) = 255;
if (*(numberOfRGBPtr + 265 * 2 + i) >= j) *(newBPixelPtr + i * pixelsPerValue + k + j * options.width) = 255;
}
}
}
}
}
Images[0] = new MyImage(options, newRPixel, new byte[options.width * options.height], new byte[options.width * options.height]);
Images[1] = new MyImage(options, new byte[options.width * options.height], newGPixel, new byte[options.width * options.height]);
Images[2] = new MyImage(options, new byte[options.width * options.height], new byte[options.width * options.height], newBPixel);
return Images;
}
#region Helpers
/// <summary>
/// Returns HSV values of the actual image
/// </summary>
/// <returns></returns>
private unsafe double[,] GetHSV()
{
int size = opt.width * opt.height;
double[,] HSV = new double[3, size];
int M, m, C;
double _H = 0;
fixed (byte* rPtr = rPixels, gPtr = gPixels, bPtr = bPixels)
{
fixed (double* hsvPtr = HSV)
{
for (int i = 0; i < size; i++)
{
M = MaxRGB(i);
m = MinRGB(i);
C = M - m;
//Set H value
if (C == 0) _H = 0;
else if (M == *(rPtr + i)) _H = (((*gPtr + i) - *(bPtr + i)) / C) % 6;
else if (M == *(gPtr + i)) _H = (*(bPtr + i) - *(rPtr + i)) / C + 2;
else if (M == *(bPtr + i)) _H = (*(rPtr + i) - *(gPtr + i)) / C + 4;
*(hsvPtr + i) = 60 * _H;
// Set S value
if (M == 0) *(hsvPtr + size + i) = 0;
else *(hsvPtr + size + i) = C / M;
// Set V value
*(hsvPtr + size * 2 + i) = M;
}
}
}
return HSV;
}
private unsafe byte MaxRGB(int i)
{
fixed (byte* rPtr = rPixels, gPtr = gPixels, bPtr = bPixels)
{
byte max = *(rPtr + i) > (*gPtr + i) ? *(rPtr + i) : *(gPtr + i);
max = *(bPtr + i) > max ? *(bPtr + i) : max;
return max;
}
}
private unsafe byte MinRGB(int i)
{
fixed (byte* rPtr = rPixels, gPtr = gPixels, bPtr = bPixels)
{
byte min = *(rPtr + i) < (*gPtr + i) ? *(rPtr + i) : *(gPtr + i);
min = *(bPtr + i) < min ? *(bPtr + i) : min;
return min;
}
}
private unsafe int Max(int* tab, int length)
{
int max = 0;
for (int i = 0; i < length; i++)
{
if (*(tab + i) > max) max = *(tab + i);
}
return max;
}
/// <summary> /// <summary>
/// Passe d'un nombre au format Endian à un nombre entier /// Passe d'un nombre au format Endian à un nombre entier
/// </summary> /// </summary>
...@@ -436,5 +789,6 @@ namespace S04_Projet ...@@ -436,5 +789,6 @@ namespace S04_Projet
return str; return str;
} }
#endregion
} }
} }
\ No newline at end of file
...@@ -24,7 +24,7 @@ namespace S04_Projet ...@@ -24,7 +24,7 @@ namespace S04_Projet
public int fileSize; public int fileSize;
public int offset; public int offset;
public Options() { } public Options() {}
/// <summary> /// <summary>
/// Return a new instance of Options with the same parameters /// Return a new instance of Options with the same parameters
...@@ -32,22 +32,24 @@ namespace S04_Projet ...@@ -32,22 +32,24 @@ namespace S04_Projet
/// <returns>New option instance</returns> /// <returns>New option instance</returns>
public Options Copy() public Options Copy()
{ {
Options options = new Options(); Options options = new Options
options.fileInfoHeaderSize = fileInfoHeaderSize; {
options.width = width; fileInfoHeaderSize = fileInfoHeaderSize,
options.height = height; width = width,
options.padding = padding; height = height,
options.colorPlanesNb = colorPlanesNb; padding = padding,
options.bitsPerPixel = bitsPerPixel; colorPlanesNb = colorPlanesNb,
options.compressionMethod = compressionMethod; bitsPerPixel = bitsPerPixel,
options.imgSize = imgSize; compressionMethod = compressionMethod,
options.horizontalRes = horizontalRes; imgSize = imgSize,
options.VerticalRes = VerticalRes; horizontalRes = horizontalRes,
options.nbColor = nbColor; VerticalRes = VerticalRes,
options.nbImportantColor = nbImportantColor; nbColor = nbColor,
options.format = format; nbImportantColor = nbImportantColor,
options.fileSize = fileSize; format = format,
options.offset = offset; fileSize = fileSize,
offset = offset
};
return options; return options;
} }
......
...@@ -60,12 +60,12 @@ namespace S04_Projet ...@@ -60,12 +60,12 @@ namespace S04_Projet
Stopwatch sw = new Stopwatch(); Stopwatch sw = new Stopwatch();
MyImage imgg = new MyImage("img/flocon.bmp"); MyImage imgg = new MyImage("img/image.bmp");
Console.WriteLine("Loading done"); Console.WriteLine("Loading done");
sw.Start(); sw.Start();
MyImage newImg = imgg.Filter(sharpenFilter, 1); MyImage filter = imgg.Filter(edgeDetect3Filter, 1);
sw.Stop(); sw.Stop();
newImg.Save("filter.bmp"); filter.Save("filter.bmp");
Console.WriteLine(sw.ElapsedMilliseconds); Console.WriteLine(sw.ElapsedMilliseconds);
Console.Read(); Console.Read();
......
This image diff could not be displayed because it is too large. You can view the blob instead.
S04_Projet/bin/Debug/img/coco.bmp

188 KB | W: | H:

S04_Projet/bin/Debug/img/coco.bmp

188 KB | W: | H:

S04_Projet/bin/Debug/img/coco.bmp
S04_Projet/bin/Debug/img/coco.bmp
S04_Projet/bin/Debug/img/coco.bmp
S04_Projet/bin/Debug/img/coco.bmp
  • 2-up
  • Swipe
  • Onion skin
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment