Commit 2c48fe18 authored by Théophile BORNON's avatar Théophile BORNON

Rotations + beginning of gray scales

parent f4cc1cd1
......@@ -10,24 +10,12 @@ namespace S04_Projet
{
public class MyImage
{
private int fileInfoHeaderSize;
private int width;
private int height;
private int colorPlanesNb;
private int bitsPerPixel;
private int compressionMethod;
private int imgSize;
private int horizontalRes;
private int VerticalRes;
private int nbColor;
private int nbImportantColor;
private string format;
private int fileSize;
private int offset;
private Options opt;
private Pixel[,] Pixels;
public MyImage(string path)
{
opt = new Options();
byte[] file = new byte[0];
try
{
......@@ -36,117 +24,177 @@ namespace S04_Projet
catch (Exception e)
{
Console.WriteLine("Une erreur est survenue : " + e.Message);
}
finally
{
if (file.Length != 0)
{
#region Header
format = (char)file[0] + "" + (char)file[1];
fileSize = EndianToInt(file, 2, 6);
offset = EndianToInt(file, 10, 14);
Console.WriteLine("Format : {0}\nTaille : {1} octets", format, fileSize);
Console.WriteLine("Offset : " + offset);
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
fileInfoHeaderSize = EndianToInt(file, 14, 18);
width = EndianToInt(file, 18, 22);
height = EndianToInt(file, 22, 26);
colorPlanesNb = EndianToInt(file, 26, 28);
bitsPerPixel = EndianToInt(file, 28, 30);
compressionMethod = EndianToInt(file, 30, 34);
imgSize = EndianToInt(file, 34, 38);
horizontalRes = EndianToInt(file, 38, 42);
VerticalRes = EndianToInt(file, 42, 46);
nbColor = EndianToInt(file, 46, 50);
nbImportantColor = EndianToInt(file, 50, 54);
Console.WriteLine("File info header size : {0} octets", fileInfoHeaderSize);
Console.WriteLine("Size : {0}x{1}px", width, height);
Console.WriteLine("Color planes number : " + colorPlanesNb);
Console.WriteLine("Bits per pixel : " + bitsPerPixel);
Console.WriteLine("Compression method : " + compressionMethod);
Console.WriteLine("Image size : {0} octets", imgSize);
Console.WriteLine("Horizontal res : {0}\nVertical res : {1}", horizontalRes, VerticalRes);
Console.WriteLine("Number of colors : " + nbColor);
Console.WriteLine("Number of important colors : " + nbImportantColor);
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 = width * height;
Pixels = new Pixel[width, height];
int pixelNumber = opt.width * opt.height;
Pixels = new Pixel[opt.width, opt.height];
Stopwatch s = new Stopwatch();
#region Mono
/*s.Start();
s.Start();
for (int i = 0; i < pixelNumber; i++)
{
int x = i % width;
int y = i / width;
byte r = file[i * 3 + offset];
byte g = file[i * 3 + offset + 1];
byte b = file[i * 3 + offset + 2];
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);*/
Console.WriteLine(s.ElapsedMilliseconds);
#endregion
#region Parallel
/*
s.Start();
Parallel.For(0, pixelNumber, i =>
{
Pixels[i % width, i / width] = new Pixel(file[i * 3 + offset], file[i * 3 + offset + 1], file[i * 3 + offset + 2]);
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)
{
this.opt = opt;
this.Pixels = Pixels;
}
public void FromImageToFile(string output)
{
int nbPixel = (height * width);
int bytesNumber = nbPixel * 3 + offset; // Multiply by 3 because 3 bytes / pixel
int nbPixel = (opt.height * opt.width);
int bytesNumber = nbPixel * 3 + opt.offset; // Multiply by 3 because 3 bytes / pixel
byte[] file = new byte[bytesNumber];
#region HEADER
// FORMAT
ASCIIEncoding encoding = new ASCIIEncoding();
mixArrays(file, encoding.GetBytes(format), 0);
MixArrays(file, encoding.GetBytes(opt.format), 0);
// FILE SIZE
mixArrays(file, IntToEndian(fileSize), 2);
MixArrays(file, IntToEndian(opt.fileSize), 2);
// OFFSET
mixArrays(file, IntToEndian(offset), 10);
MixArrays(file, IntToEndian(opt.offset), 10);
#endregion
#region File Info Header
mixArrays(file, IntToEndian(fileInfoHeaderSize), 14);
mixArrays(file, IntToEndian(width), 18);
mixArrays(file, IntToEndian(height), 22);
mixArrays(file, IntToEndian(1), 26); // Number of colors planes
mixArrays(file, IntToEndian(bitsPerPixel), 28);
mixArrays(file, IntToEndian(compressionMethod), 30);
mixArrays(file, IntToEndian(fileSize - offset), 34); // Image size TO CHANGE IF NO MORE BI_RGB
mixArrays(file, IntToEndian(horizontalRes), 38);
mixArrays(file, IntToEndian(VerticalRes), 42);
mixArrays(file, IntToEndian(nbColor), 46);
mixArrays(file, IntToEndian(0), 50); // Number of important colors
MixArrays(file, IntToEndian(opt.fileInfoHeaderSize), 14);
MixArrays(file, IntToEndian(opt.width), 18);
MixArrays(file, IntToEndian(opt.height), 22);
MixArrays(file, IntToEndian(1), 26); // Number of colors planes
MixArrays(file, IntToEndian(opt.bitsPerPixel), 28);
MixArrays(file, IntToEndian(opt.compressionMethod), 30);
MixArrays(file, IntToEndian(opt.fileSize - opt.offset), 34); // Image size TO CHANGE IF NO MORE BI_RGB
MixArrays(file, IntToEndian(opt.horizontalRes), 38);
MixArrays(file, IntToEndian(opt.VerticalRes), 42);
MixArrays(file, IntToEndian(opt.nbColor), 46);
MixArrays(file, IntToEndian(0), 50); // Number of important colors
#endregion
#region Pixel array
for (int i = 0; i < nbPixel; i++)
{
mixArrays(file, Pixels[i % width, i / width].getRGB(), 54 + (i * 3));
MixArrays(file, Pixels[i % opt.width, i / opt.width].getRGB(), 54 + (i * 3));
}
File.WriteAllBytes(output, file);
#endregion
}
public void Save(string output)
{
FromImageToFile(output);
}
#region Rotations
public MyImage 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[y, options.height - 1- x] = Pixels[x, y];
}
return new MyImage(options, PixelArr);
}
public MyImage Rotate180()
{
return Rotate90().Rotate90();
}
public MyImage Rotate270()
{
return Rotate180().Rotate90();
}
#endregion
public MyImage ToGrayScale(byte scale)
{
Options options = opt.Copy();
opt.nbColor = scale;
Pixel[,] PixelArr = new Pixel[opt.width, opt.height];
for (int i = 0; i < opt.width * opt.height; i++)
{
int x = i % opt.width;
int y = i / opt.width;
PixelArr[x, y] = Pixels[x, y].getGrayScale(scale);
}
return new MyImage(options, PixelArr);
}
public static int EndianToInt(byte[] arr, int from, int to)
{
int somme = 0;
......@@ -162,7 +210,7 @@ namespace S04_Projet
return endian;
}
public void mixArrays(byte[] arr, byte[] toAdd, int start)
public static void MixArrays(byte[] arr, byte[] toAdd, int start)
{
for (int i = start; i < start + toAdd.Length; i++)
{
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace S04_Projet
{
public class Options
{
public int fileInfoHeaderSize;
public int width;
public int height;
public int colorPlanesNb;
public int bitsPerPixel;
public int compressionMethod;
public int imgSize;
public int horizontalRes;
public int VerticalRes;
public int nbColor;
public int nbImportantColor;
public string format;
public int fileSize;
public int offset;
public Options() { }
public Options Copy()
{
Options options = new Options();
options.fileInfoHeaderSize = fileInfoHeaderSize;
options.width = width;
options.height = height;
options.colorPlanesNb = colorPlanesNb;
options.bitsPerPixel = bitsPerPixel;
options.compressionMethod = compressionMethod;
options.imgSize = imgSize;
options.horizontalRes = horizontalRes;
options.VerticalRes = VerticalRes;
options.nbColor = nbColor;
options.nbImportantColor = nbImportantColor;
options.format = format;
options.fileSize = fileSize;
options.offset = offset;
return options;
}
}
}
......@@ -19,9 +19,34 @@ namespace S04_Projet
this.b = b;
}
public Pixel(byte[] rgb)
{
r = rgb[0];
g = rgb[1];
b = rgb[2];
}
public byte[] getRGB()
{
return new byte[] { r, g, b };
}
public Pixel getGrayScale(byte scale)
{
byte pix = (byte)((r + g + b) / 3);
pix = (byte)((pix / 255) * (scale-1)); // [0, scale-1]
if (pix == 1) Console.WriteLine("1");
pix = (byte)(pix * 255 * (scale-1));
if (pix == 255) Console.WriteLine("255");
return new Pixel(pix, pix, pix);
}
public Pixel getGrayScaleLuminosity(byte scale)
{
byte pix = (byte)(0.21 * r + 0.72 * g + 0.07 * b);
pix = (byte)(pix / (255 / scale));
pix = (byte)((pix * (255 / scale)) + (255 / scale));
return new Pixel(pix, pix, pix);
}
}
}
......@@ -14,7 +14,21 @@ namespace S04_Projet
static void Main(string[] args)
{
MyImage img = new MyImage("img/flocon.bmp");
/*MyImage imgRotate90 = img.Rotate90();
imgRotate90.Save("90.bmp");
MyImage imgRotate180 = img.Rotate180();
imgRotate180.Save("180.bmp");
MyImage imgRotate270 = img.Rotate270();
imgRotate270.Save("270.bmp");
Console.WriteLine("Rotations terminées");*/
//img.FromImageToFile("test.bmp");
MyImage bw = img.ToGrayScale(4);
bw.Save("bw.bmp");
Console.WriteLine("Done");
Console.Read();
}
}
......
......@@ -44,6 +44,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="MyImage.cs" />
<Compile Include="Options.cs" />
<Compile Include="Pixel.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
......
This image diff could not be displayed because it is too large. You can view the blob instead.
This image diff could not be displayed because it is too large. You can view the blob instead.
This image diff could not be displayed because it is too large. You can view the blob instead.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
</configuration>
\ No newline at end of file
This image diff could not be displayed because it is too large. You can view the blob instead.
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