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
} while (!validPath);
Console.Clear();
Thread waitingThread = new Thread(new ThreadStart(WaitingScreen));
/*Thread waitingThread = new Thread(new ThreadStart(WaitingScreen));
Stopwatch sw = new Stopwatch();
sw.Start();
waitingThread.Start();
waitingThread.Start();*/
MyImage image = new MyImage(path);
waitingThread.Abort();
/*waitingThread.Abort();
sw.Stop();
Console.Clear();
......@@ -81,7 +81,7 @@ namespace S04_Projet
elapsedTime = sw.ElapsedMilliseconds;
lastOperationMessage = "Image chargée en " + elapsedTime + "ms";
fileInfos = image.ToString();
*/
return image;
}
......@@ -139,7 +139,7 @@ namespace S04_Projet
/// <param name="ope">Opération désirée</param>
/// <param name="img">Image sur laquelle effectuer l'opération</param>
/// <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;
Stopwatch sw = new Stopwatch();
......@@ -238,6 +238,6 @@ namespace S04_Projet
Console.Write(".");
Thread.Sleep(250);
}
}
}*/
}
}
......@@ -50,7 +50,6 @@
<Compile Include="MyImage.cs" />
<Compile Include="Display.cs" />
<Compile Include="Options.cs" />
<Compile Include="Pixel.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
......
......@@ -22,8 +22,6 @@ namespace S04_Projet
private byte[] file;
private int nbPixel;
private int nbProcessors;
private Pixel[,] Pixels;
private Pixel[,] NewPixels;
private Options opt;
private short[,] filter;
private double factor;
......@@ -45,14 +43,14 @@ namespace S04_Projet
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.opt = opt;
this.Pixels = Pixels;
this.filter = filter;
this.factor = factor;
size = filter.GetLength(0);
nbProcessors = Environment.ProcessorCount;
}
public void Start()
......@@ -64,7 +62,6 @@ namespace S04_Projet
#region LoadImage
public void LoadImage()
{
Pixels = new Pixel[opt.width, opt.height];
Thread[] threads = new Thread[nbProcessors];
for (int i = 0; i < nbProcessors; i++)
{
......@@ -78,7 +75,7 @@ namespace S04_Projet
public void LoadImageTask(object i)
{
if (file != null && Pixels != null)
if (file != null)
{
int start = nbPixel / nbProcessors * (int)i;
int end = nbPixel / nbProcessors * ((int)i + 1);
......@@ -93,8 +90,6 @@ namespace S04_Projet
b = file[j * 3 + opt.padding * y + opt.offset];
g = file[j * 3 + opt.padding * y + opt.offset + 1];
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
#region Filter
public void ApplyFilter()
{
NewPixels = new Pixel[opt.width, opt.height];
int pixelNumber = opt.width * opt.height;
nbProcessors = Environment.ProcessorCount;
int pixelPerThread = pixelNumber / nbProcessors;
Thread[] threads = new Thread[nbProcessors];
Console.WriteLine("Creating {0} thread(s)", nbProcessors);
for (int i = 0; i < nbProcessors; i++)
{
threads[i] = new Thread(new ParameterizedThreadStart(ApplyFilterTask));
......@@ -146,7 +142,6 @@ namespace S04_Projet
g = ConvolutionalResult(gMatrixPtr, filterPtr, size, factor);
b = ConvolutionalResult(bMatrixPtr, filterPtr, size, factor);
NewPixels[x, y] = new Pixel(r, g, b);
}
}
}
......@@ -172,12 +167,12 @@ namespace S04_Projet
if (y < 0) y = 0;
else if (y >= opt.height) y = opt.height - 1;
if (rgb == RGB.R)
*(matrixPtr + i) = Pixels[x, y].r;
else if (rgb == RGB.G)
*(matrixPtr + i) = Pixels[x, y].g;
else if (rgb == RGB.B)
*(matrixPtr + i) = Pixels[x, y].b;
if (rgb == RGB.R) ;
// *(matrixPtr + i) = Pixels[x, y].r;
else if (rgb == RGB.G) ;
// *(matrixPtr + i) = Pixels[x, y].g;
else if (rgb == RGB.B) ;
// *(matrixPtr + i) = Pixels[x, y].b;
}
}
......@@ -202,15 +197,5 @@ namespace S04_Projet
else return (byte)r;
}
#endregion
public Pixel[,] getPixelMatrix()
{
return Pixels;
}
public Pixel[,] getFilteredMatrix()
{
return NewPixels;
}
}
}
......@@ -7,7 +7,7 @@ namespace S04_Projet
public class MyImage
{
private Options opt;
private Pixel[,] Pixels;
byte[] rPixels, gPixels, bPixels;
byte[] file;
public enum GrayFilterType
......@@ -69,10 +69,12 @@ namespace S04_Projet
/// </summary>
/// <param name="opt">Options de 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.Pixels = Pixels;
this.rPixels = rPixels;
this.gPixels = gPixels;
this.bPixels = bPixels;
}
/// <summary>
......@@ -103,39 +105,36 @@ namespace S04_Projet
#endregion
#region Pixel array
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
if (!Program.MULTITHREADING_LOAD)
{
int x, y;
byte r, g, b;
fixed (byte* filePtr = file)
int y;
fixed (byte* filePtr = file, rPtr = rPixels, gPtr = gPixels, bPtr = bPixels)
{
for (int i = 0; i < pixelNumber; i++)
{
x = 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];
r = file[i * 3 + opt.padding * y + opt.offset + 2];*/
b = *(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);
*(rPtr + i) = *(filePtr + i * 3 + opt.padding * y + opt.offset + 2);
*(gPtr + i) = *(filePtr + i * 3 + opt.padding * y + opt.offset + 1);
*(bPtr + i) = *(filePtr + i * 3 + opt.padding * y + opt.offset);
}
}
}
#endregion
#region Multithreading
else
/*else
{
MultiThreadedTask LoadImageTask = new MultiThreadedTask(MultiThreadedTask.Operation.Load, file, opt);
LoadImageTask.Start();
Pixels = LoadImageTask.getPixelMatrix();
}
}*/
#endregion
file = null;
......@@ -185,7 +184,10 @@ namespace S04_Projet
{
x = 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
......@@ -200,7 +202,7 @@ namespace S04_Projet
{
FromImageToFile(output);
}
/*
#region Rotations
/// <summary>
/// Tourne l'image de 90° dans le sens horaire
......@@ -257,13 +259,13 @@ namespace S04_Projet
return new MyImage(options, PixelArr);
}
#endregion
*/
/// <summary>
/// Agrandit l'image par rapport au coefficient passé en paramètre. WIP
/// </summary>
/// <param name="coeff">Coefficient d'agrandissement de l'image</param>
/// <returns>Image élargie</returns>
public MyImage Enlarge(int coeff)
/* public MyImage Enlarge(int coeff)
{
Options options = opt.Copy();
options.width *= coeff;
......@@ -286,14 +288,14 @@ namespace S04_Projet
}
return null;
}
}*/
/// <summary>
/// Rétrécit l'image par rapport au coefficient passé en paramètres
/// </summary>
/// <param name="coeff">Coefficient de rétrécissement de l'image</param>
/// <returns>Image rétrécie</returns>
public MyImage Shrink(int coeff)
/* public MyImage Shrink(int coeff)
{
Options options = opt.Copy();
options.width /= coeff;
......@@ -332,7 +334,7 @@ namespace S04_Projet
}
return new MyImage(options, PixelArr);
}
}*/
/// <summary>
/// Passe l'image en nuances de gris
......@@ -340,6 +342,7 @@ 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="type">Type de transformation. Linéaire ou en fonction de la luminosité de la couleur</param>
/// <returns>Image en nuances de gris</returns>
/*
public MyImage ToGrayScale(byte scale, GrayFilterType type)
{
Options options = opt.Copy();
......@@ -355,7 +358,7 @@ namespace S04_Projet
PixelArr[x, y] = Pixels[x, y].getGrayScaleLuminosity(scale);
}
return new MyImage(options, PixelArr);
}
}*/
/// <summary>
/// Applique un filtre de convolution à l'image
......@@ -363,7 +366,7 @@ namespace S04_Projet
/// <param name="filter">Filtre de convolution</param>
/// <param name="factor">Facteur de normalisation</param>
/// <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)
{
......@@ -466,7 +469,7 @@ namespace S04_Projet
if (r > 255) return 255;
else if (r < 0) return 0;
else return (byte)r;
}
}*/
/// <summary>
/// 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
Stopwatch sw = new Stopwatch();
MyImage imgg = new MyImage("img/flocon.bmp");
Console.WriteLine("Loading done");
sw.Start();
imgg.ApplyConvFilter(edgeDetect1Filter, 1);
MyImage imgg = new MyImage("img/flocon.bmp");
sw.Stop();
imgg.Save("test.bmp");
Console.WriteLine("Loading done");
//imgg.ApplyConvFilter(edgeDetect1Filter, 1);
Console.WriteLine(sw.ElapsedMilliseconds);
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