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

Display++

parent 801cdd6e
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Threading;
namespace S04_Projet
{
public class Display
{
/// <summary>
/// Liste des opérations possibles
/// </summary>
public enum Operation
{
Rotate90,
Rotate180,
Rotate270,
GrayScaleLinear,
GrayScaleLuminosity,
Save
}
/// <summary>
/// Charge l'image
/// </summary>
/// <returns>Retourne l'objet contenant l'image chargée</returns>
public static MyImage LoadImage()
{
string path;
bool validPath = false;
byte[] file = new byte[0];
do
{
Console.WriteLine("Veuillez saisir le nom du fichier à traiter :");
path = Console.ReadLine();
try
{
file = File.ReadAllBytes(path);
}
catch (Exception e)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Une erreur est survenue : " + e.Message);
Console.ForegroundColor = ConsoleColor.White;
}
if (file.Length != 0) validPath = true;
} while (!validPath);
Console.Clear();
MyImageThread myImageThread = new MyImageThread(file);
Thread imageThread = new Thread(new ThreadStart(myImageThread.ThreadLoop));
imageThread.Start();
Console.Write("Traitement en cours de l'image.");
while (imageThread.IsAlive)
{
Thread.Sleep(250);
Console.Write(".");
}
Console.Clear();
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Image chargée en {0}ms\n", myImageThread.loadTime);
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine(myImageThread.image.toString());
Console.ForegroundColor = ConsoleColor.White;
return myImageThread.image;
}
/// <summary>
/// Demande quelles opérations l'on souhaite effectuer sur l'image
/// </summary>
/// <returns>Retourne le type d'opération souhaitée</returns>
public static Operation AskForOperation()
{
int choosenItem = 0;
string[] menuItems = new string[]
{
"Rotation à 90°",
"Rotation à 180°",
"Rotation à 270°",
"Passage à une image en nuances de gris (linéairement)",
"Passage à une image en nuances de gris (luminosité)",
"Sauvegarder"
};
for (int i = 0; i < menuItems.Length; i++)
{
Console.WriteLine(((choosenItem == i) ? ">> " : " ") + menuItems[i]);
}
ConsoleKeyInfo key;
do
{
key = Console.ReadKey();
Console.SetCursorPosition(0, 9 + choosenItem);
Console.Write(" ");
if(key.Key == ConsoleKey.DownArrow)
{
choosenItem++;
if (choosenItem == menuItems.Length) choosenItem = 0;
}
else if(key.Key == ConsoleKey.UpArrow)
{
choosenItem--;
if (choosenItem == -1) choosenItem = menuItems.Length - 1;
}
Console.SetCursorPosition(0, 9 + choosenItem);
Console.Write(">>");
} while (key.Key != ConsoleKey.Escape && key.Key != ConsoleKey.Enter);
if (key.Key == ConsoleKey.Escape) Environment.Exit(0);
return (Operation)choosenItem;
}
/// <summary>
/// Effectue l'opération demandée sur l'image passée en paramètres
/// </summary>
/// <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)
{
MyImage output = null;
Console.Clear();
if (ope == Operation.Rotate90) output = img.Rotate90();
else if (ope == Operation.Rotate180) output = img.Rotate180();
else if (ope == Operation.Rotate270) output = img.Rotate270();
else if(ope == Operation.GrayScaleLinear || ope == Operation.GrayScaleLuminosity)
{
bool retry = false;
int input;
do
{
if (retry) Console.WriteLine("Saisie incorrecte");
Console.WriteLine("Veuillez saisir le nombre de nuances de gris désirées (entre 2 et 255)");
retry = !int.TryParse(Console.ReadLine(), out input);
} while (retry && input >= 2 && input <= 255);
if (ope == Operation.GrayScaleLinear) output = img.ToGrayScale((byte)input, MyImage.grayFilterType.LINEAR);
else if (ope == Operation.GrayScaleLuminosity) output = img.ToGrayScale((byte)input, MyImage.grayFilterType.LUMINOSITY);
}
else if(ope == Operation.Save)
{
string path;
bool anotherTry = false;
do
{
if (anotherTry) Console.WriteLine("Le format du chemin est incorrect");
Console.WriteLine("Veuillez saisir le nom du fichier en sortie");
path = Console.ReadLine();
if (!path.EndsWith(".bmp")) path += ".bmp";
} while (anotherTry = !Uri.IsWellFormedUriString(path, UriKind.RelativeOrAbsolute));
img.Save(path);
}
else
{
throw new Exception("Opération non reconnue");
}
return output;
}
}
}
......@@ -41,80 +41,23 @@ namespace S04_Projet
{
if (file.Length != 0)
{
#region Header
opt.format = (char)file[0] + "" + (char)file[1];
opt.fileSize = EndianToInt(file, 2, 6);
opt.offset = EndianToInt(file, 10, 14);
Console.WriteLine("Format : {0}\nTaille : {1} octets", opt.format, opt.fileSize);
Console.WriteLine("Offset : " + opt.offset);
#endregion
#region File info
opt.fileInfoHeaderSize = EndianToInt(file, 14, 18);
opt.width = EndianToInt(file, 18, 22);
opt.height = EndianToInt(file, 22, 26);
opt.colorPlanesNb = EndianToInt(file, 26, 28);
opt.bitsPerPixel = EndianToInt(file, 28, 30);
opt.compressionMethod = EndianToInt(file, 30, 34);
opt.imgSize = EndianToInt(file, 34, 38);
opt.horizontalRes = EndianToInt(file, 38, 42);
opt.VerticalRes = EndianToInt(file, 42, 46);
opt.nbColor = EndianToInt(file, 46, 50);
opt.nbImportantColor = EndianToInt(file, 50, 54);
Console.WriteLine("File info header size : {0} octets", opt.fileInfoHeaderSize);
Console.WriteLine("Size : {0}x{1}px", opt.width, opt.height);
Console.WriteLine("Color planes number : " + opt.colorPlanesNb);
Console.WriteLine("Bits per pixel : " + opt.bitsPerPixel);
Console.WriteLine("Compression method : " + opt.compressionMethod);
Console.WriteLine("Image size : {0} octets", opt.imgSize);
Console.WriteLine("Horizontal res : {0}\nVertical res : {1}", opt.horizontalRes, opt.VerticalRes);
Console.WriteLine("Number of colors : " + opt.nbColor);
Console.WriteLine("Number of important colors : " + opt.nbImportantColor);
#endregion
#region Pixel array
int pixelNumber = opt.width * opt.height;
Pixels = new Pixel[opt.width, opt.height];
Stopwatch s = new Stopwatch();
FromFileToImage(file);
}
}
}
#region Mono
s.Start();
for (int i = 0; i < pixelNumber; i++)
public MyImage(byte[] file)
{
int x = i % opt.width;
int y = i / opt.width;
byte r = file[i * 3 + opt.offset];
byte g = file[i * 3 + opt.offset + 1];
byte b = file[i * 3 + opt.offset + 2];
Pixels[x, y] = new Pixel(r, g, b);
FromFileToImage(file);
}
s.Stop();
Console.WriteLine(s.ElapsedMilliseconds);
#endregion
#region Parallel
/*
s.Start();
Parallel.For(0, pixelNumber, i =>
public MyImage(Options opt, Pixel[,] Pixels)
{
Pixels[i % opt.width, i / opt.width] = new Pixel(file[i * 3 + opt.offset],
file[i * 3 + opt.offset + 1],
file[i * 3 + opt.offset + 2]
);
});
s.Stop();
Console.WriteLine(s.ElapsedMilliseconds);
*/
#endregion
#endregion
}
}
this.opt = opt;
this.Pixels = Pixels;
}
public MyImage(byte[] file)
private void FromFileToImage(byte[] file)
{
opt = new Options();
#region Header
......@@ -142,10 +85,7 @@ namespace S04_Projet
int pixelNumber = opt.width * opt.height;
Pixels = new Pixel[opt.width, opt.height];
Stopwatch s = new Stopwatch();
#region Mono
s.Start();
for (int i = 0; i < pixelNumber; i++)
{
int x = i % opt.width;
......@@ -155,13 +95,10 @@ namespace S04_Projet
byte b = file[i * 3 + opt.offset + 2];
Pixels[x, y] = new Pixel(r, g, b);
}
s.Stop();
Console.WriteLine(s.ElapsedMilliseconds);
#endregion
#region Parallel
/*
s.Start();
Parallel.For(0, pixelNumber, i =>
{
Pixels[i % opt.width, i / opt.width] = new Pixel(file[i * 3 + opt.offset],
......@@ -169,8 +106,6 @@ namespace S04_Projet
file[i * 3 + opt.offset + 2]
);
});
s.Stop();
Console.WriteLine(s.ElapsedMilliseconds);
*/
#endregion
......@@ -187,12 +122,6 @@ namespace S04_Projet
#endregion
}
public MyImage(Options opt, Pixel[,] Pixels)
{
this.opt = opt;
this.Pixels = Pixels;
}
private void FromImageToFile(string output)
{
int nbPixel = (opt.height * opt.width);
......@@ -228,9 +157,9 @@ namespace S04_Projet
{
MixArrays(file, Pixels[i % opt.width, i / opt.width].getRGB(), 54 + (i * 3));
}
#endregion
File.WriteAllBytes(output, file);
#endregion
}
public void Save(string output)
......@@ -256,12 +185,30 @@ namespace S04_Projet
public MyImage Rotate180()
{
return Rotate90().Rotate90();
Options options = opt.Copy();
Pixel[,] PixelArr = new Pixel[options.width, options.height];
for (int i = 0; i < options.width * options.height; i++)
{
int x = i % opt.width;
int y = i / opt.width;
PixelArr[options.width - x - 1, options.height - y - 1] = Pixels[x, y];
}
return new MyImage(options, PixelArr);
}
public MyImage Rotate270()
{
return Rotate180().Rotate90();
Options options = opt.Copy();
options.width = opt.height;
options.height = opt.width;
Pixel[,] PixelArr = new Pixel[options.width, options.height];
for (int i = 0; i < options.width * options.height; i++)
{
int x = i % opt.width;
int y = i / opt.width;
PixelArr[options.width - 1 - y, x] = Pixels[x, y];
}
return new MyImage(options, PixelArr);
}
#endregion
......
......@@ -12,6 +12,12 @@ namespace S04_Projet
public byte g { get; private set; }
public byte b { get; private set; }
/// <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;
......@@ -19,6 +25,10 @@ namespace S04_Projet
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;
......@@ -26,6 +36,10 @@ namespace S04_Projet
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];
......@@ -33,11 +47,20 @@ namespace S04_Projet
b = 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 };
}
/// <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);
......@@ -45,6 +68,12 @@ namespace S04_Projet
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);
......
......@@ -13,53 +13,19 @@ namespace S04_Projet
{
static void Main(string[] args)
{
//MyImage img = new MyImage("img/coco.bmp");
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("#############################################################");
Console.WriteLine("### Bienvenue ###");
Console.WriteLine("#############################################################");
Console.WriteLine();
string path;
bool validPath = false;
byte[] file = new byte[0];
MyImage img = Display.LoadImage();
Display.Operation ToDo = Display.AskForOperation();
Display.PerformOperation(ToDo, img);
do
{
Console.WriteLine("Veuillez saisir le nom du fichier à traiter :");
path = Console.ReadLine();
try
{
file = File.ReadAllBytes(path);
}
catch (Exception e)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Une erreur est survenue : " + e.Message);
Console.ForegroundColor = ConsoleColor.White;
}
if (file.Length != 0) validPath = true;
} while (!validPath);
Console.Clear();
MyImageThread myImageThread = new MyImageThread(file);
Thread imageThread = new Thread(new ThreadStart(myImageThread.ThreadLoop));
imageThread.Start();
while(imageThread.IsAlive)
{
Console.Write("Traitement en cours de l'image.");
Thread.Sleep(250);
Console.Write(".");
Thread.Sleep(250);
Console.Write(".");
Thread.Sleep(250);
Console.Clear();
}
Console.WriteLine("Image chargée en {0}ms\n", myImageThread.loadTime);
Console.WriteLine(myImageThread.image.toString());
//Console.Clear();
Console.Read();
......
......@@ -44,6 +44,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="MyImage.cs" />
<Compile Include="Display.cs" />
<Compile Include="MyImageThread.cs" />
<Compile Include="Options.cs" />
<Compile Include="Pixel.cs" />
......
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