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 ...@@ -41,80 +41,23 @@ namespace S04_Projet
{ {
if (file.Length != 0) if (file.Length != 0)
{ {
#region Header FromFileToImage(file);
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();
#region Mono public MyImage(byte[] file)
s.Start();
for (int i = 0; i < pixelNumber; i++)
{ {
int x = i % opt.width; FromFileToImage(file);
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);
} }
s.Stop();
Console.WriteLine(s.ElapsedMilliseconds);
#endregion
#region Parallel public MyImage(Options opt, Pixel[,] Pixels)
/*
s.Start();
Parallel.For(0, pixelNumber, i =>
{ {
Pixels[i % opt.width, i / opt.width] = new Pixel(file[i * 3 + opt.offset], this.opt = opt;
file[i * 3 + opt.offset + 1], this.Pixels = Pixels;
file[i * 3 + opt.offset + 2]
);
});
s.Stop();
Console.WriteLine(s.ElapsedMilliseconds);
*/
#endregion
#endregion
}
}
} }
public MyImage(byte[] file) private void FromFileToImage(byte[] file)
{ {
opt = new Options(); opt = new Options();
#region Header #region Header
...@@ -142,10 +85,7 @@ namespace S04_Projet ...@@ -142,10 +85,7 @@ namespace S04_Projet
int pixelNumber = opt.width * opt.height; int pixelNumber = opt.width * opt.height;
Pixels = new Pixel[opt.width, opt.height]; Pixels = new Pixel[opt.width, opt.height];
Stopwatch s = new Stopwatch();
#region Mono #region Mono
s.Start();
for (int i = 0; i < pixelNumber; i++) for (int i = 0; i < pixelNumber; i++)
{ {
int x = i % opt.width; int x = i % opt.width;
...@@ -155,13 +95,10 @@ namespace S04_Projet ...@@ -155,13 +95,10 @@ namespace S04_Projet
byte b = file[i * 3 + opt.offset + 2]; byte b = file[i * 3 + opt.offset + 2];
Pixels[x, y] = new Pixel(r, g, b); Pixels[x, y] = new Pixel(r, g, b);
} }
s.Stop();
Console.WriteLine(s.ElapsedMilliseconds);
#endregion #endregion
#region Parallel #region Parallel
/* /*
s.Start();
Parallel.For(0, pixelNumber, i => Parallel.For(0, pixelNumber, i =>
{ {
Pixels[i % opt.width, i / opt.width] = new Pixel(file[i * 3 + opt.offset], Pixels[i % opt.width, i / opt.width] = new Pixel(file[i * 3 + opt.offset],
...@@ -169,8 +106,6 @@ namespace S04_Projet ...@@ -169,8 +106,6 @@ namespace S04_Projet
file[i * 3 + opt.offset + 2] file[i * 3 + opt.offset + 2]
); );
}); });
s.Stop();
Console.WriteLine(s.ElapsedMilliseconds);
*/ */
#endregion #endregion
...@@ -187,12 +122,6 @@ namespace S04_Projet ...@@ -187,12 +122,6 @@ namespace S04_Projet
#endregion #endregion
} }
public MyImage(Options opt, Pixel[,] Pixels)
{
this.opt = opt;
this.Pixels = Pixels;
}
private void FromImageToFile(string output) private void FromImageToFile(string output)
{ {
int nbPixel = (opt.height * opt.width); int nbPixel = (opt.height * opt.width);
...@@ -228,9 +157,9 @@ namespace S04_Projet ...@@ -228,9 +157,9 @@ namespace S04_Projet
{ {
MixArrays(file, Pixels[i % opt.width, i / opt.width].getRGB(), 54 + (i * 3)); MixArrays(file, Pixels[i % opt.width, i / opt.width].getRGB(), 54 + (i * 3));
} }
#endregion
File.WriteAllBytes(output, file); File.WriteAllBytes(output, file);
#endregion
} }
public void Save(string output) public void Save(string output)
...@@ -256,12 +185,30 @@ namespace S04_Projet ...@@ -256,12 +185,30 @@ namespace S04_Projet
public MyImage Rotate180() 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() 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 #endregion
......
...@@ -12,6 +12,12 @@ namespace S04_Projet ...@@ -12,6 +12,12 @@ namespace S04_Projet
public byte g { get; private set; } public byte g { get; private set; }
public byte b { 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) public Pixel(byte r, byte g, byte b)
{ {
this.r = r; this.r = r;
...@@ -19,6 +25,10 @@ namespace S04_Projet ...@@ -19,6 +25,10 @@ namespace S04_Projet
this.b = b; 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) public Pixel(byte unifiedColors)
{ {
r = unifiedColors; r = unifiedColors;
...@@ -26,6 +36,10 @@ namespace S04_Projet ...@@ -26,6 +36,10 @@ namespace S04_Projet
b = 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) public Pixel(byte[] rgb)
{ {
r = rgb[0]; r = rgb[0];
...@@ -33,11 +47,20 @@ namespace S04_Projet ...@@ -33,11 +47,20 @@ namespace S04_Projet
b = rgb[2]; 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() public byte[] getRGB()
{ {
return new byte[] { r, g, b }; 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) public Pixel getGrayScale(byte scale)
{ {
byte total = (byte)((r + g + b) / 3); byte total = (byte)((r + g + b) / 3);
...@@ -45,6 +68,12 @@ namespace S04_Projet ...@@ -45,6 +68,12 @@ namespace S04_Projet
return new Pixel(total); 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) public Pixel getGrayScaleLuminosity(byte scale)
{ {
byte total = (byte)(0.21 * r + 0.72 * g + 0.07 * b); byte total = (byte)(0.21 * r + 0.72 * g + 0.07 * b);
......
...@@ -13,53 +13,19 @@ namespace S04_Projet ...@@ -13,53 +13,19 @@ namespace S04_Projet
{ {
static void Main(string[] args) static void Main(string[] args)
{ {
//MyImage img = new MyImage("img/coco.bmp"); Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("#############################################################"); Console.WriteLine("#############################################################");
Console.WriteLine("### Bienvenue ###"); Console.WriteLine("### Bienvenue ###");
Console.WriteLine("#############################################################"); Console.WriteLine("#############################################################");
Console.WriteLine(); Console.WriteLine();
string path; MyImage img = Display.LoadImage();
bool validPath = false; Display.Operation ToDo = Display.AskForOperation();
byte[] file = new byte[0]; 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.Clear();
Console.Read(); Console.Read();
......
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="MyImage.cs" /> <Compile Include="MyImage.cs" />
<Compile Include="Display.cs" />
<Compile Include="MyImageThread.cs" /> <Compile Include="MyImageThread.cs" />
<Compile Include="Options.cs" /> <Compile Include="Options.cs" />
<Compile Include="Pixel.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