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

threading in da place

parent 2c48fe18
using System; using System;
using System.IO; using System.IO;
using System.Diagnostics; using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
...@@ -13,6 +11,19 @@ namespace S04_Projet ...@@ -13,6 +11,19 @@ namespace S04_Projet
private Options opt; private Options opt;
private Pixel[,] Pixels; private Pixel[,] Pixels;
public enum grayFilterType
{
LINEAR,
LUMINOSITY
}
private enum RGB
{
R,
G,
B
}
public MyImage(string path) public MyImage(string path)
{ {
opt = new Options(); opt = new Options();
...@@ -103,13 +114,75 @@ namespace S04_Projet ...@@ -103,13 +114,75 @@ namespace S04_Projet
} }
} }
public MyImage(byte[] file)
{
opt = new Options();
#region Header
opt.format = (char)file[0] + "" + (char)file[1];
opt.fileSize = EndianToInt(file, 2, 6);
opt.offset = EndianToInt(file, 10, 14);
#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);
#endregion
#region Pixel array
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;
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
/*
s.Start();
Parallel.For(0, pixelNumber, i =>
{
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
}
public MyImage(Options opt, Pixel[,] Pixels) public MyImage(Options opt, Pixel[,] Pixels)
{ {
this.opt = opt; this.opt = opt;
this.Pixels = Pixels; this.Pixels = Pixels;
} }
public void FromImageToFile(string output) private void FromImageToFile(string output)
{ {
int nbPixel = (opt.height * opt.width); int nbPixel = (opt.height * opt.width);
int bytesNumber = nbPixel * 3 + opt.offset; // Multiply by 3 because 3 bytes / pixel int bytesNumber = nbPixel * 3 + opt.offset; // Multiply by 3 because 3 bytes / pixel
...@@ -165,7 +238,7 @@ namespace S04_Projet ...@@ -165,7 +238,7 @@ namespace S04_Projet
{ {
int x = i % opt.width; int x = i % opt.width;
int y = i / opt.width; int y = i / opt.width;
PixelArr[y, options.height - 1- x] = Pixels[x, y]; PixelArr[y, options.height - 1 - x] = Pixels[x, y];
} }
return new MyImage(options, PixelArr); return new MyImage(options, PixelArr);
} }
...@@ -181,7 +254,7 @@ namespace S04_Projet ...@@ -181,7 +254,7 @@ namespace S04_Projet
} }
#endregion #endregion
public MyImage ToGrayScale(byte scale) public MyImage ToGrayScale(byte scale, grayFilterType type)
{ {
Options options = opt.Copy(); Options options = opt.Copy();
opt.nbColor = scale; opt.nbColor = scale;
...@@ -190,19 +263,99 @@ namespace S04_Projet ...@@ -190,19 +263,99 @@ namespace S04_Projet
{ {
int x = i % opt.width; int x = i % opt.width;
int y = i / opt.width; int y = i / opt.width;
if (type == grayFilterType.LINEAR)
PixelArr[x, y] = Pixels[x, y].getGrayScale(scale); PixelArr[x, y] = Pixels[x, y].getGrayScale(scale);
else if (type == grayFilterType.LUMINOSITY)
PixelArr[x, y] = Pixels[x, y].getGrayScaleLuminosity(scale);
} }
return new MyImage(options, PixelArr); return new MyImage(options, PixelArr);
} }
public static int EndianToInt(byte[] arr, int from, int to) public MyImage ApplyConvFilter(int[,] filter, double factor)
{
if (filter.GetLength(0) == filter.GetLength(1) && filter.GetLength(0) % 2 == 1)
{
int size = filter.GetLength(0);
Options options = opt.Copy();
int nbPixel = options.height * options.width;
Pixel[,] PixelArr = new Pixel[opt.width, opt.height];
int x, y;
int[,] rMatrix, gMatrix, bMatrix;
byte r, g, b;
for (int i = 0; i < nbPixel; i++)
{
x = i % options.width;
y = i / options.width;
rMatrix = GetMatrix(x, y, size, RGB.R);
gMatrix = GetMatrix(x, y, size, RGB.G);
bMatrix = GetMatrix(x, y, size, RGB.B);
r = ConvolutionalResult(rMatrix, filter, size, factor);
g = ConvolutionalResult(gMatrix, filter, size, factor);
b = ConvolutionalResult(bMatrix, filter, size, factor);
PixelArr[x, y] = new Pixel(r, g, b);
}
return new MyImage(opt, PixelArr);
}
else if (filter.GetLength(0) != filter.GetLength(1))
{
throw new Exception("Matrice non carrée");
}
else
{
throw new Exception("Matrice de taille paire");
}
}
private int[,] GetMatrix(int x0, int y0, int size, RGB rgb)
{
int[,] matrix = new int[size, size];
for (int i = 0; i < Math.Pow(size, 2); i++)
{
int x = x0 + (i % size) - ((size - 1) / 2);
int y = y0 + (i / size) - ((size - 1) / 2);
if (x >= 0 && x < opt.width && y >= 0 && y < opt.height)
{
if (rgb == RGB.R)
matrix[(i % size), (i / size)] = Pixels[x, y].r;
else if (rgb == RGB.G)
matrix[(i % size), (i / size)] = Pixels[x, y].g;
else if (rgb == RGB.B)
matrix[(i % size), (i / size)] = Pixels[x, y].b;
}
}
return matrix;
}
private byte ConvolutionalResult(int[,] matrix, int[,] conv, int size, double factor)
{
int r = 0;
for (int i = 0; i < Math.Pow(size, 2); i++)
{
int x = i % size;
int y = i / size;
r += matrix[x, y] * conv[(size - 1) - x, (size - 1) - y];
}
r = (int)Math.Round(r * factor);
return (byte)r;
}
private static int EndianToInt(byte[] arr, int from, int to)
{ {
int somme = 0; int somme = 0;
for (int i = from; i < to; i++) somme += (arr[i] << ((i - from) * 8)); for (int i = from; i < to; i++) somme += (arr[i] << ((i - from) * 8));
return somme; return somme;
} }
public static byte[] IntToEndian(int val) private static byte[] IntToEndian(int val)
{ {
byte[] endian = new byte[4]; byte[] endian = new byte[4];
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
...@@ -210,12 +363,28 @@ namespace S04_Projet ...@@ -210,12 +363,28 @@ namespace S04_Projet
return endian; return endian;
} }
public static void MixArrays(byte[] arr, byte[] toAdd, int start) private static void MixArrays(byte[] arr, byte[] toAdd, int start)
{ {
for (int i = start; i < start + toAdd.Length; i++) for (int i = start; i < start + toAdd.Length; i++)
{ {
arr[i] = toAdd[i - start]; arr[i] = toAdd[i - start];
} }
} }
public string toString()
{
string str = "";
str += String.Format("Format : {0}\nTaille : {1} octets", opt.format, opt.fileSize) + "\n";
str += String.Format("Offset : {0} octets", opt.offset) + "\n";
str += String.Format("File info header size : {0} octets", opt.fileInfoHeaderSize) + "\n";
str += String.Format("Size : {0}x{1}px", opt.width, opt.height) + "\n";
str += String.Format("Bits per pixel : " + opt.bitsPerPixel) + "\n";
/*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);*/
return str;
}
} }
} }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace S04_Projet
{
public class MyImageThread
{
public byte[] file;
public MyImage image;
public MyImageThread(byte[] file)
{
this.file = file;
}
public void ThreadLoop()
{
image = new MyImage(file);
}
}
}
...@@ -8,9 +8,9 @@ namespace S04_Projet ...@@ -8,9 +8,9 @@ namespace S04_Projet
{ {
public class Pixel public class Pixel
{ {
byte r; public byte r { get; private set; }
byte g; public byte g { get; private set; }
byte b; public byte b { get; private set; }
public Pixel(byte r, byte g, byte b) public Pixel(byte r, byte g, byte b)
{ {
...@@ -19,6 +19,13 @@ namespace S04_Projet ...@@ -19,6 +19,13 @@ namespace S04_Projet
this.b = b; this.b = b;
} }
public Pixel(byte unifiedColors)
{
r = unifiedColors;
g = unifiedColors;
b = unifiedColors;
}
public Pixel(byte[] rgb) public Pixel(byte[] rgb)
{ {
r = rgb[0]; r = rgb[0];
...@@ -33,20 +40,20 @@ namespace S04_Projet ...@@ -33,20 +40,20 @@ namespace S04_Projet
public Pixel getGrayScale(byte scale) public Pixel getGrayScale(byte scale)
{ {
byte pix = (byte)((r + g + b) / 3); byte total = (byte)((r + g + b) / 3);
pix = (byte)((pix / 255) * (scale-1)); // [0, scale-1] total = (byte)(Math.Round((double)total / (255/(scale-1))) * (255 / (scale - 1)));
if (pix == 1) Console.WriteLine("1"); return new Pixel(total);
pix = (byte)(pix * 255 * (scale-1));
if (pix == 255) Console.WriteLine("255");
return new Pixel(pix, pix, pix);
} }
public Pixel getGrayScaleLuminosity(byte scale) public Pixel getGrayScaleLuminosity(byte scale)
{ {
byte pix = (byte)(0.21 * r + 0.72 * g + 0.07 * b); byte total = (byte)(0.21 * r + 0.72 * g + 0.07 * b);
pix = (byte)(pix / (255 / scale)); total = (byte)(Math.Round((double)total / (255 / (scale - 1))) * (255 / (scale - 1)));
pix = (byte)((pix * (255 / scale)) + (255 / scale)); return new Pixel(total);
return new Pixel(pix, pix, pix);
} }
public void SetR(byte r) { this.r = r; }
public void SetG(byte g) { this.g = g; }
public void SetB(byte b) { this.b = b; }
} }
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading;
using System.Drawing; using System.Drawing;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
...@@ -13,23 +13,83 @@ namespace S04_Projet ...@@ -13,23 +13,83 @@ namespace S04_Projet
{ {
static void Main(string[] args) static void Main(string[] args)
{ {
MyImage img = new MyImage("img/flocon.bmp"); //MyImage img = new MyImage("img/coco.bmp");
Console.WriteLine("#############################################################");
Console.WriteLine("### Bienvenue ###");
Console.WriteLine("#############################################################");
Console.WriteLine();
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();
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(myImageThread.image.toString());
//Console.Clear();
Console.Read();
#region Test
/*MyImage imgRotate90 = img.Rotate90(); /*MyImage imgRotate90 = img.Rotate90();
imgRotate90.Save("90.bmp"); imgRotate90.Save("90.bmp");
MyImage imgRotate180 = img.Rotate180(); MyImage imgRotate180 = img.Rotate180();
imgRotate180.Save("180.bmp"); imgRotate180.Save("180.bmp");
MyImage imgRotate270 = img.Rotate270(); MyImage imgRotate270 = img.Rotate270();
imgRotate270.Save("270.bmp"); imgRotate270.Save("270.bmp");
Console.WriteLine("Rotations terminées");*/ Console.WriteLine("Rotations terminées");
//img.FromImageToFile("test.bmp");
MyImage bw = img.ToGrayScale(4); MyImage bwLumnisity = img.ToGrayScale(2, MyImage.grayFilterType.LUMINOSITY);
bw.Save("bw.bmp"); bwLumnisity.Save("bwLumnosity.bmp");
Console.WriteLine("Done"); MyImage bwLinear = img.ToGrayScale(2, MyImage.grayFilterType.LINEAR);
bwLinear.Save("bwLinear.bmp");
Console.WriteLine("Done");*/
Console.Read(); /*int[,] convFilter = new int[,]
{
{ 0, 0, 0 },
{ 0, 0, 7 },
{ 3, 5, 1 }
};
MyImage conv = img.ApplyConvFilter(convFilter, (1.0 / 16.0));
conv.Save("dither.bmp");
Console.WriteLine("Done");*/
#endregion
} }
} }
} }
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="MyImage.cs" /> <Compile Include="MyImage.cs" />
<Compile Include="MyImageThread.cs" />
<Compile Include="Options.cs" /> <Compile Include="Options.cs" />
<Compile Include="Pixel.cs" /> <Compile Include="Pixel.cs" />
<Compile Include="Program.cs" /> <Compile Include="Program.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