Commit 77e62751 authored by Théophile BORNON's avatar Théophile BORNON

Load and save working

parent 45249fb9
...@@ -66,14 +66,14 @@ namespace S04_Projet ...@@ -66,14 +66,14 @@ namespace S04_Projet
} while (!validPath); } while (!validPath);
Console.Clear(); Console.Clear();
Thread waitingThread = new Thread(new ThreadStart(WaitingScreen)); /*Thread waitingThread = new Thread(new ThreadStart(WaitingScreen));
Stopwatch sw = new Stopwatch(); Stopwatch sw = new Stopwatch();
sw.Start(); sw.Start();
waitingThread.Start(); waitingThread.Start();*/
MyImage image = new MyImage(path); MyImage image = new MyImage(path);
waitingThread.Abort(); /*waitingThread.Abort();
sw.Stop(); sw.Stop();
Console.Clear(); Console.Clear();
...@@ -81,7 +81,7 @@ namespace S04_Projet ...@@ -81,7 +81,7 @@ namespace S04_Projet
elapsedTime = sw.ElapsedMilliseconds; elapsedTime = sw.ElapsedMilliseconds;
lastOperationMessage = "Image chargée en " + elapsedTime + "ms"; lastOperationMessage = "Image chargée en " + elapsedTime + "ms";
fileInfos = image.ToString(); fileInfos = image.ToString();
*/
return image; return image;
} }
...@@ -139,7 +139,7 @@ namespace S04_Projet ...@@ -139,7 +139,7 @@ namespace S04_Projet
/// <param name="ope">Opération désirée</param> /// <param name="ope">Opération désirée</param>
/// <param name="img">Image sur laquelle effectuer l'opération</param> /// <param name="img">Image sur laquelle effectuer l'opération</param>
/// <returns>Image avec l'opération effectuée dessus</returns> /// <returns>Image avec l'opération effectuée dessus</returns>
public static MyImage PerformOperation(Operation ope, MyImage img) /*public static MyImage PerformOperation(Operation ope, MyImage img)
{ {
MyImage output = null; MyImage output = null;
Stopwatch sw = new Stopwatch(); Stopwatch sw = new Stopwatch();
...@@ -238,6 +238,6 @@ namespace S04_Projet ...@@ -238,6 +238,6 @@ namespace S04_Projet
Console.Write("."); Console.Write(".");
Thread.Sleep(250); Thread.Sleep(250);
} }
} }*/
} }
} }
...@@ -50,7 +50,6 @@ ...@@ -50,7 +50,6 @@
<Compile Include="MyImage.cs" /> <Compile Include="MyImage.cs" />
<Compile Include="Display.cs" /> <Compile Include="Display.cs" />
<Compile Include="Options.cs" /> <Compile Include="Options.cs" />
<Compile Include="Pixel.cs" />
<Compile Include="Program.cs" /> <Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
......
...@@ -22,8 +22,6 @@ namespace S04_Projet ...@@ -22,8 +22,6 @@ namespace S04_Projet
private byte[] file; private byte[] file;
private int nbPixel; private int nbPixel;
private int nbProcessors; private int nbProcessors;
private Pixel[,] Pixels;
private Pixel[,] NewPixels;
private Options opt; private Options opt;
private short[,] filter; private short[,] filter;
private double factor; private double factor;
...@@ -45,14 +43,14 @@ namespace S04_Projet ...@@ -45,14 +43,14 @@ namespace S04_Projet
nbProcessors = Environment.ProcessorCount; nbProcessors = Environment.ProcessorCount;
} }
public MultiThreadedTask(Operation ToDo, Pixel[,] Pixels, Options opt, short[,] filter, double factor) public unsafe MultiThreadedTask(Operation ToDo, byte* rPixelPtr, byte* gPixelPtr, byte* bPixelPtr, Options opt, short[,] filter, double factor)
{ {
this.ToDo = ToDo; this.ToDo = ToDo;
this.opt = opt; this.opt = opt;
this.Pixels = Pixels;
this.filter = filter; this.filter = filter;
this.factor = factor; this.factor = factor;
size = filter.GetLength(0); size = filter.GetLength(0);
nbProcessors = Environment.ProcessorCount;
} }
public void Start() public void Start()
...@@ -64,7 +62,6 @@ namespace S04_Projet ...@@ -64,7 +62,6 @@ namespace S04_Projet
#region LoadImage #region LoadImage
public void LoadImage() public void LoadImage()
{ {
Pixels = new Pixel[opt.width, opt.height];
Thread[] threads = new Thread[nbProcessors]; Thread[] threads = new Thread[nbProcessors];
for (int i = 0; i < nbProcessors; i++) for (int i = 0; i < nbProcessors; i++)
{ {
...@@ -78,7 +75,7 @@ namespace S04_Projet ...@@ -78,7 +75,7 @@ namespace S04_Projet
public void LoadImageTask(object i) public void LoadImageTask(object i)
{ {
if (file != null && Pixels != null) if (file != null)
{ {
int start = nbPixel / nbProcessors * (int)i; int start = nbPixel / nbProcessors * (int)i;
int end = nbPixel / nbProcessors * ((int)i + 1); int end = nbPixel / nbProcessors * ((int)i + 1);
...@@ -93,8 +90,6 @@ namespace S04_Projet ...@@ -93,8 +90,6 @@ namespace S04_Projet
b = file[j * 3 + opt.padding * y + opt.offset]; b = file[j * 3 + opt.padding * y + opt.offset];
g = file[j * 3 + opt.padding * y + opt.offset + 1]; g = file[j * 3 + opt.padding * y + opt.offset + 1];
r = file[j * 3 + opt.padding * y + opt.offset + 2]; r = file[j * 3 + opt.padding * y + opt.offset + 2];
Pixels[x, y] = new Pixel(r, g, b);
} }
} }
} }
...@@ -103,11 +98,12 @@ namespace S04_Projet ...@@ -103,11 +98,12 @@ namespace S04_Projet
#region Filter #region Filter
public void ApplyFilter() public void ApplyFilter()
{ {
NewPixels = new Pixel[opt.width, opt.height];
int pixelNumber = opt.width * opt.height; int pixelNumber = opt.width * opt.height;
nbProcessors = Environment.ProcessorCount;
int pixelPerThread = pixelNumber / nbProcessors; int pixelPerThread = pixelNumber / nbProcessors;
Thread[] threads = new Thread[nbProcessors]; Thread[] threads = new Thread[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));
...@@ -145,8 +141,7 @@ namespace S04_Projet ...@@ -145,8 +141,7 @@ namespace S04_Projet
r = ConvolutionalResult(rMatrixPtr, filterPtr, size, factor); r = ConvolutionalResult(rMatrixPtr, filterPtr, size, factor);
g = ConvolutionalResult(gMatrixPtr, filterPtr, size, factor); g = ConvolutionalResult(gMatrixPtr, filterPtr, size, factor);
b = ConvolutionalResult(bMatrixPtr, filterPtr, size, factor); b = ConvolutionalResult(bMatrixPtr, filterPtr, size, factor);
NewPixels[x, y] = new Pixel(r, g, b);
} }
} }
} }
...@@ -172,12 +167,12 @@ namespace S04_Projet ...@@ -172,12 +167,12 @@ namespace S04_Projet
if (y < 0) y = 0; if (y < 0) y = 0;
else if (y >= opt.height) y = opt.height - 1; else if (y >= opt.height) y = opt.height - 1;
if (rgb == RGB.R) if (rgb == RGB.R) ;
*(matrixPtr + i) = Pixels[x, y].r; // *(matrixPtr + i) = Pixels[x, y].r;
else if (rgb == RGB.G) else if (rgb == RGB.G) ;
*(matrixPtr + i) = Pixels[x, y].g; // *(matrixPtr + i) = Pixels[x, y].g;
else if (rgb == RGB.B) else if (rgb == RGB.B) ;
*(matrixPtr + i) = Pixels[x, y].b; // *(matrixPtr + i) = Pixels[x, y].b;
} }
} }
...@@ -202,15 +197,5 @@ namespace S04_Projet ...@@ -202,15 +197,5 @@ namespace S04_Projet
else return (byte)r; else return (byte)r;
} }
#endregion #endregion
public Pixel[,] getPixelMatrix()
{
return Pixels;
}
public Pixel[,] getFilteredMatrix()
{
return NewPixels;
}
} }
} }
...@@ -7,7 +7,7 @@ namespace S04_Projet ...@@ -7,7 +7,7 @@ namespace S04_Projet
public class MyImage public class MyImage
{ {
private Options opt; private Options opt;
private Pixel[,] Pixels; byte[] rPixels, gPixels, bPixels;
byte[] file; byte[] file;
public enum GrayFilterType public enum GrayFilterType
...@@ -69,10 +69,12 @@ namespace S04_Projet ...@@ -69,10 +69,12 @@ namespace S04_Projet
/// </summary> /// </summary>
/// <param name="opt">Options de l'image</param> /// <param name="opt">Options de l'image</param>
/// <param name="Pixels">Matrice de pixels constituant l'image</param> /// <param name="Pixels">Matrice de pixels constituant l'image</param>
public MyImage(Options opt, Pixel[,] Pixels) public MyImage(Options opt, byte[] rPixels, byte[] gPixels, byte[] bPixels)
{ {
this.opt = opt; this.opt = opt;
this.Pixels = Pixels; this.rPixels = rPixels;
this.gPixels = gPixels;
this.bPixels = bPixels;
} }
/// <summary> /// <summary>
...@@ -103,39 +105,36 @@ namespace S04_Projet ...@@ -103,39 +105,36 @@ namespace S04_Projet
#endregion #endregion
#region Pixel array #region Pixel array
int pixelNumber = opt.width * opt.height; int pixelNumber = opt.width * opt.height;
Pixels = new Pixel[opt.width, opt.height]; rPixels = new byte[pixelNumber];
gPixels = new byte[pixelNumber];
bPixels = new byte[pixelNumber];
#region Mono #region Mono
if (!Program.MULTITHREADING_LOAD) if (!Program.MULTITHREADING_LOAD)
{ {
int x, y; int y;
byte r, g, b; fixed (byte* filePtr = file, rPtr = rPixels, gPtr = gPixels, bPtr = bPixels)
fixed (byte* filePtr = file)
{ {
for (int i = 0; i < pixelNumber; i++) for (int i = 0; i < pixelNumber; i++)
{ {
x = i % opt.width;
y = i / opt.width; y = i / opt.width;
/*b = file[i * 3 + opt.padding * y + opt.offset];
g = file[i * 3 + opt.padding * y + opt.offset + 1]; *(rPtr + i) = *(filePtr + i * 3 + opt.padding * y + opt.offset + 2);
r = file[i * 3 + opt.padding * y + opt.offset + 2];*/ *(gPtr + i) = *(filePtr + i * 3 + opt.padding * y + opt.offset + 1);
b = *(filePtr + i * 3 + opt.padding * y + opt.offset); *(bPtr + i) = *(filePtr + i * 3 + opt.padding * y + opt.offset);
g = *(filePtr + i * 3 + opt.padding * y + opt.offset + 1);
r = *(filePtr + i * 3 + opt.padding * y + opt.offset + 2);
Pixels[x, y] = new Pixel(r, g, b);
} }
} }
} }
#endregion #endregion
#region Multithreading #region Multithreading
else /*else
{ {
MultiThreadedTask LoadImageTask = new MultiThreadedTask(MultiThreadedTask.Operation.Load, file, opt); MultiThreadedTask LoadImageTask = new MultiThreadedTask(MultiThreadedTask.Operation.Load, file, opt);
LoadImageTask.Start(); LoadImageTask.Start();
Pixels = LoadImageTask.getPixelMatrix(); Pixels = LoadImageTask.getPixelMatrix();
} }*/
#endregion #endregion
file = null; file = null;
...@@ -185,7 +184,10 @@ namespace S04_Projet ...@@ -185,7 +184,10 @@ namespace S04_Projet
{ {
x = i % opt.width; x = i % opt.width;
y = i / opt.width; y = i / opt.width;
MixArrays(file, Pixels[x, y].getBGR(), opt.offset + (i * 3) + opt.padding * y);
file[i * 3 + opt.padding * y + opt.offset] = bPixels[i];
file[i * 3 + opt.padding * y + opt.offset + 1] = gPixels[i];
file[i * 3 + opt.padding * y + opt.offset + 2] = rPixels[i];
} }
#endregion #endregion
...@@ -200,7 +202,7 @@ namespace S04_Projet ...@@ -200,7 +202,7 @@ namespace S04_Projet
{ {
FromImageToFile(output); FromImageToFile(output);
} }
/*
#region Rotations #region Rotations
/// <summary> /// <summary>
/// Tourne l'image de 90° dans le sens horaire /// Tourne l'image de 90° dans le sens horaire
...@@ -257,13 +259,13 @@ namespace S04_Projet ...@@ -257,13 +259,13 @@ namespace S04_Projet
return new MyImage(options, PixelArr); return new MyImage(options, PixelArr);
} }
#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. WIP
/// </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 MyImage Enlarge(int coeff)
{ {
Options options = opt.Copy(); Options options = opt.Copy();
options.width *= coeff; options.width *= coeff;
...@@ -286,14 +288,14 @@ namespace S04_Projet ...@@ -286,14 +288,14 @@ namespace S04_Projet
} }
return null; return null;
} }*/
/// <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 MyImage Shrink(int coeff)
{ {
Options options = opt.Copy(); Options options = opt.Copy();
options.width /= coeff; options.width /= coeff;
...@@ -332,7 +334,7 @@ namespace S04_Projet ...@@ -332,7 +334,7 @@ namespace S04_Projet
} }
return new MyImage(options, PixelArr); return new MyImage(options, PixelArr);
} }*/
/// <summary> /// <summary>
/// Passe l'image en nuances de gris /// Passe l'image en nuances de gris
...@@ -340,7 +342,8 @@ namespace S04_Projet ...@@ -340,7 +342,8 @@ namespace S04_Projet
/// <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 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;
...@@ -355,7 +358,7 @@ namespace S04_Projet ...@@ -355,7 +358,7 @@ namespace S04_Projet
PixelArr[x, y] = Pixels[x, y].getGrayScaleLuminosity(scale); PixelArr[x, y] = Pixels[x, y].getGrayScaleLuminosity(scale);
} }
return new MyImage(options, PixelArr); return new MyImage(options, PixelArr);
} }*/
/// <summary> /// <summary>
/// Applique un filtre de convolution à l'image /// Applique un filtre de convolution à l'image
...@@ -363,7 +366,7 @@ namespace S04_Projet ...@@ -363,7 +366,7 @@ namespace S04_Projet
/// <param name="filter">Filtre de convolution</param> /// <param name="filter">Filtre de convolution</param>
/// <param name="factor">Facteur de normalisation</param> /// <param name="factor">Facteur de normalisation</param>
/// <returns>Image avec le filtre de convolution appliqué</returns> /// <returns>Image avec le filtre de convolution appliqué</returns>
public MyImage ApplyConvFilter(short[,] filter, double factor) /*public MyImage ApplyConvFilter(short[,] filter, double factor)
{ {
if (filter.GetLength(0) == filter.GetLength(1) && filter.GetLength(0) % 2 == 1) if (filter.GetLength(0) == filter.GetLength(1) && filter.GetLength(0) % 2 == 1)
{ {
...@@ -466,7 +469,7 @@ namespace S04_Projet ...@@ -466,7 +469,7 @@ namespace S04_Projet
if (r > 255) return 255; if (r > 255) return 255;
else if (r < 0) return 0; else if (r < 0) return 0;
else return (byte)r; else return (byte)r;
} }*/
/// <summary> /// <summary>
/// Passe d'un nombre au format Endian à un nombre entier /// Passe d'un nombre au format Endian à un nombre entier
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace S04_Projet
{
public class Pixel
{
public byte r { get; private set; }
public byte g { get; private set; }
public byte b { get; private set; }
public double H { get; private set; }
public double S { get; private set; }
public double L { get; private set; }
public void SetR(byte r) => this.r = r;
public void SetG(byte g) => this.g = g;
public void SetB(byte b) => this.b = b;
/// <summary>
/// Prend les trois couleurs en paramètres
/// </summary>
/// <param name="r">Rouge</param>
/// <param name="g">Vert</param>
/// <param name="b">Bleu</param>
public Pixel(byte r, byte g, byte b)
{
this.r = r;
this.g = g;
this.b = b;
}
public unsafe Pixel(byte* r, byte* g, byte* b)
{
this.r = *r;
this.g = *g;
this.b = *b;
}
/// <summary>
/// Assigne une même valeur à toutes les couleurs
/// </summary>
/// <param name="unifiedColors">Valeur souhaitée pour toutes les couleurs</param>
public Pixel(byte unifiedColors)
{
r = unifiedColors;
g = unifiedColors;
b = unifiedColors;
}
/// <summary>
/// Créer un pixel à partir d'un tableau contenant les couleurs rouge, vert, bleu (respectivement)
/// </summary>
/// <param name="rgb">Tableau composé dans cet ordre des couleurs rouge, vert, bleu</param>
public Pixel(byte[] rgb)
{
r = rgb[0];
g = rgb[1];
b = rgb[2];
}
/// <summary>
/// Créer un pixel à partir d'un tableau contenant les couleurs rouge, vert, bleu (respectivement)
/// </summary>
/// <param name="rgb">Tableau composé dans cet ordre des couleurs rouge, vert, bleu</param>
public Pixel(int[] rgb)
{
r = (byte)rgb[0];
g = (byte)rgb[1];
b = (byte)rgb[2];
}
/// <summary>
/// Retourne un tableau contenant les valeurs RGB du pixel
/// </summary>
/// <returns>Composantes rouge, verte et bleue du pixel</returns>
public byte[] getRGB()
{
return new byte[] { r, g, b };
}
public unsafe byte* getRGBPtr()
{
unsafe
{
fixed (byte* ptr = new byte[] { r, g, b })
return ptr;
}
}
public byte[] getBGR()
{
return new byte[] { b, g, r };
}
/// <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 Pixel getGrayScale(byte scale)
{
byte total = (byte)((r + g + b) / 3);
total = (byte)(Math.Round((double)total / (255 / (scale - 1))) * (255 / (scale - 1)));
return new Pixel(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 Pixel getGrayScaleLuminosity(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 new Pixel(total);
}
/// <summary>
/// Calcul les valeurs de variables HSL (Hue, Saturation, Lightness)
/// </summary>
private void computeHSL()
{
double rH = r / 255.0;
double gH = g / 255.0;
double bH = b / 255.0;
double Cmax = Math.Max(Math.Max(rH, gH), bH);
double Cmin = Math.Min(Math.Min(rH, gH), bH);
double delta = Cmax - Cmin;
L = (Cmin + Cmax) / 2.0;
if (delta == 0) S = 0;
else S = delta / (1.0 - Math.Abs(2.0 * L - 1));
if (delta == 0) H = 0;
else if (Cmax == rH) H = 60 * (((gH - bH) / delta) % 6);
else if (Cmax == gH) H = 60 * (((bH - rH) / delta) + 2);
else H = 60 * (((rH - gH) / delta) + 4);
}
}
}
...@@ -60,11 +60,12 @@ namespace S04_Projet ...@@ -60,11 +60,12 @@ namespace S04_Projet
Stopwatch sw = new Stopwatch(); Stopwatch sw = new Stopwatch();
MyImage imgg = new MyImage("img/flocon.bmp");
Console.WriteLine("Loading done");
sw.Start(); sw.Start();
imgg.ApplyConvFilter(edgeDetect1Filter, 1); MyImage imgg = new MyImage("img/flocon.bmp");
sw.Stop(); sw.Stop();
imgg.Save("test.bmp");
Console.WriteLine("Loading done");
//imgg.ApplyConvFilter(edgeDetect1Filter, 1);
Console.WriteLine(sw.ElapsedMilliseconds); Console.WriteLine(sw.ElapsedMilliseconds);
Console.Read(); Console.Read();
......
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