using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace first_pr
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void exit()
{
DialogResult rsl = MessageBox.Show("Are you sure that you want to exit?", "Warning!", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (rsl == DialogResult.Yes)
{
Application.Exit();
}
}
private void button3_Click(object sender, EventArgs e)
{
exit();
}
public Image currImage;
static public Image Mem;
private void Load_Image()
{
openFileDialog1.InitialDirectory = "c:";
openFileDialog1.Filter = "image (JPEG) files (*.jpg)|*.jpg|All files (*.*)|*.*|image (BMP) files (*.bmp)|*.bmp|image (PNG) files (*.png)|*.png";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
try
{
currImage = Image.FromFile(openFileDialog1.FileName);
Mem = Image.FromFile(openFileDialog1.FileName);
button6.Enabled = true;
if ((currImage.Height <= 256) && (currImage.Width <= 256))
{
pictureBox1.Image = currImage;
}
else
{
DialogResult rsl = MessageBox.Show("Wrong size of picture! Press 'Yes' if you want to continue. Press 'No' if you want to reload image.", "Warning!", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (rsl == DialogResult.Yes)
{
pictureBox1.Image = currImage;
}
}
}
catch (Exception e)
{
MessageBox.Show("Can't load file.\n" + e.StackTrace, "Warning!",MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
}
private void Open_Click(object sender, EventArgs e)
{
Load_Image();
}
private void button2_Click(object sender, EventArgs e)
{
try
{
var bmp = (Bitmap)Mem;
for (int x = 0; x < bmp.Width; ++x)
for (int y = 0; y < bmp.Height; ++y)
{
Color curr = bmp.GetPixel(x, y);
Color next = Color.FromArgb((byte)(1 - curr.R), (byte)(1 - curr.G), (byte)(1 - curr.B)); // RGB -> CMY
bmp.SetPixel(x, y, next);
}
pictureBox2.Image = bmp;
pictureBox3.Image = Mem;
}
catch (Exception ex)
{
MessageBox.Show("Forgot to open file: load it first.", "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
private void Save_image()
{
if (pictureBox3.Image != null)
{
Bitmap bt = (Bitmap)pictureBox3.Image;
SaveFileDialog sfd = new SaveFileDialog();
sfd.DefaultExt = "bmp";
sfd.Filter = "Image files (*.bmp)|*.bmp|All files (*.*)|*.*";
if (sfd.ShowDialog() == DialogResult.OK)
{
bt.Save(sfd.FileName);
}
}
else
{
throw new Exception("No image");
}
}
private void button1_Click(object sender, EventArgs e)
{
try
{
Save_image();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
private void button4_Click(object sender, EventArgs e)
{
try
{
Bitmap bmp = (Bitmap)Mem;
for (int x = 0; x < bmp.Width; ++x)
for (int y = 0; y < bmp.Height; ++y)
{
Color curr = bmp.GetPixel(x, y);
float r = (11*curr.B + 30*curr.R + 59*curr.G )/100;
Color next = Color.FromArgb((byte) r, (byte) r, (byte) r); // RGB -> BW
bmp.SetPixel(x, y, next);
}
pictureBox2.Image = bmp;
pictureBox3.Image = Mem;
}
catch (Exception ex)
{
MessageBox.Show("Forgot to open file: load it first.", "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
private void button5_Click(object sender, EventArgs e)
{
try
{
Bitmap bmp = (Bitmap)Mem;
for (int x = 0; x < (bmp.Width); ++x)
for (int y = 0; y < (bmp.Height); ++y)
{
Color curr = bmp.GetPixel(x, y);
float r = (11 * curr.B + 30 * curr.R + 59 * curr.G) / 100;
Color next = Color.FromArgb((byte)r, (byte)r, (byte)r); // RGB -> BW
bmp.SetPixel(x, y, next);
}
pictureBox2.Image = bmp;
pictureBox2.Refresh();
for (int x = 1; x < (bmp.Width - 1); ++x)
for (int y = 1; y < (bmp.Height - 1); ++y)
{
int B1 = bmp.GetPixel(x - 1, y).R + bmp.GetPixel(x + 1, y).R
+ bmp.GetPixel(x, y - 1).R + bmp.GetPixel(x, y + 1).R + bmp.GetPixel(x, y).R;
float r = B1 / 5;
Color next = Color.FromArgb((byte)r, (byte)r, (byte)r); // Smooth
bmp.SetPixel(x, y, next);
}
pictureBox3.Image = bmp;
}
catch (Exception ex)
{
MessageBox.Show("Forgot to open file: load it first.", "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
private void button6_Click(object sender, EventArgs e)
{
Mem = Image.FromFile(openFileDialog1.FileName);
pictureBox2.Image = null;
pictureBox3.Image = null;
pictureBox4.Image = null;
}
public static List<vertex> vertexes = new List<vertex>();
public class vertex
{
public int x;
public int y;
public Color currColor;
public bool free;
public vertex(int _x, int _y, Color _curr)
{
x = _x;
y = _y;
currColor = _curr;
free = true;
}
public bool Equals(vertex other)
{
return ((this.x == other.x) && (this.y == other.y));
}
public override int GetHashCode()
{
return x.GetHashCode() ^ y.GetHashCode();
}
};
public class Triangle
{
public vertex v1;
public vertex v2;
public vertex v3;
public Triangle(vertex _v1, vertex _v2, vertex _v3)
{
v1 = _v1;
v2 = _v2;
v3 = _v3;
}
};
public List<Triangle> triangles = new List<Triangle>();
public static Bitmap bmpLines = new Bitmap(256,256);
public static Graphics graphics = Graphics.FromImage(bmpLines);
public static void initBitmap()
{
for (var i = 0; i < 256; i++)
{
for(var j = 0; j < 256; j++)
{
bmpLines.SetPixel(i, j, Color.White);
}
}
}
public void showTops()
{
Form1.initBitmap();
for (int i = 0; i < vertexes.Count; i++)
{
Form1.bmpLines.SetPixel(vertexes[i].x, vertexes[i].y, vertexes[i].currColor);
}
this.pictureBox4.Image = Form1.bmpLines;
}
/* public static void markRed(int x, int y)
{
bmpLines.SetPixel(x, y, Color.Red);
}*/
abstract class DivideFigure
{
public static int fullSize = 256;
protected int currHight; /// Store hight(Y) of current figure
protected int currWidth; /// Store wigth(X) of current figure
protected int x; /// X coord for upper left point of current figure.
protected int y; /// Y coord for upper left point of current figure.
public Bitmap bmp;
abstract public void divideImage(int bright); /// Divide figure to smaller figures.
public void drawLine(int _x, int _y, int _currWidth, int _currHight, bool vert) ///
{
bmp = (Bitmap)Form1.Mem;
if (vert)
{
for (int i = _y; i < _currHight + y; i++)
{
Form1.bmpLines.SetPixel((_currWidth + x), i, Color.Black);
if ((_currHight == 1 || _currHight == 2) && (_currWidth == 1 || _currWidth == 2))
{
Color curr = bmp.GetPixel((_currWidth + x), i);
vertex M1 = new vertex((_currWidth + x), i, curr);
Form1.vertexes.Add(M1);
//if (_currWidth + x != 256 && _currWidth + x + 1 != 256 && (i + 1) != 256 && (i - 1) >= 0 && (_currWidth + x - 1) >= 0) {
// curr = bmp.GetPixel((_currWidth + x), i + 1);
// Form1.vertexes.Add(new vertex((_currWidth + x), i + 1, curr));
// curr = bmp.GetPixel((_currWidth + x + 1), i + 1);
// Form1.vertexes.Add(new vertex((_currWidth + x + 1), i + 1, curr));
// curr = bmp.GetPixel((_currWidth + x), i - 1);
// Form1.vertexes.Add(new vertex((_currWidth + x), i - 1, curr));
// curr = bmp.GetPixel((_currWidth + x - 1), i - 1);
// Form1.vertexes.Add(new vertex((_currWidth + x - 1), i - 1, curr));
// Form1.bmpLines.SetPixel((_currWidth + x), i, Color.Red);
//}
}
}
}
else
{
for (int i = _x; i < _currWidth + x; i++)
{
Form1.bmpLines.SetPixel(i, _currHight + y, Color.Black);
if ((_currHight == 1 || _currHight == 2) && (_currWidth == 1 || _currWidth == 2))
{
Color curr = Form1.bmpLines.GetPixel(i, _currHight + y);
vertex M1 = new vertex(i, _currHight + y, curr);
Form1.vertexes.Add(M1);
Form1.bmpLines.SetPixel(i, _currHight + y, Color.Red);
if (_currHight + y != 256 && _currHight + y + 1 != 256 && (i + 1) != 256 && (i - 1) >= 0 && (_currHight + y - 1) >= 0)
{
curr = bmp.GetPixel(i + 1, _currHight + y);
Form1.vertexes.Add(new vertex(i + 1, _currHight + y, curr));
curr = bmp.GetPixel((i + 1), _currHight + y + 1);
Form1.vertexes.Add(new vertex((i + 1), _currHight + y + 1, curr));
curr = bmp.GetPixel(i - 1, _currHight + y);
Form1.vertexes.Add(new vertex(i - 1, _currHight + y, curr));
curr = bmp.GetPixel(i - 1, (_currHight + y - 1));
Form1.vertexes.Add(new vertex(i - 1, (_currHight + y - 1), curr));
Form1.bmpLines.SetPixel(i,(_currHight + y), Color.Red);
}
}
}
}
}
public bool checkBrightnes(int x, int y, int currWidth, int currHight, int bright) /// Method that finds two points in figure, that have difference in brightness more than needed.
{
float r = (11 * bmp.GetPixel(x, y).B + 30 * bmp.GetPixel(x, y).R + 59 * bmp.GetPixel(x, y).G) / 100;
for (var i = x; i < (currWidth + x); i++)
{
for (var j = y; j < (currHight + y); j++)
{
Color curr = bmp.GetPixel(i, j);
float r1 = (11 * curr.B + 30 * curr.R + 59 * curr.G) / 100;
if ((r - r1) >= bright)
{
return true;
}
if (r1 > r)
{
r = r1;
}
}
}
return false;
}
};
class Rectangle : DivideFigure
{
private Form1 parent;
private bool lineVert; /// Store if this figure need to divide horisontal or vertical line
public Rectangle(Form1 _parent, int _x, int _y, int _currWidth, int _currHight, bool _lineVert)
{
this.parent = _parent;
this.x = _x;
this.y = _y;
this.currHight = _currHight;
this.currWidth = _currWidth;
this.lineVert = _lineVert;
this.bmp = (Bitmap)Form1.Mem;
}
public override void divideImage(int bright)
{
if (lineVert)
{
currWidth = currWidth / 2;
var R = new Rectangle(parent, x, y, currWidth, currHight, false);
if (R.checkBrightnes(x, y, currWidth, currHight, bright))
{
drawLine(currWidth, y, currWidth, currHight, true);
parent.pictureBox2.Image = Form1.bmpLines;
parent.pictureBox2.Refresh();
R.divideImage(bright);
}
var R1 = new Rectangle(parent, x + currWidth, y, currWidth, currHight, false);
if (R1.checkBrightnes ((x + currWidth), y, currWidth, currHight, bright))
{
drawLine(currWidth, y, currWidth, currHight, true);
// Form1.markRed(x + currWidth, y);
parent.pictureBox2.Refresh();
R1.divideImage(bright);
}
}
else
{
currHight = currHight / 2;
var R = new Rectangle(parent, x, y, currWidth, currHight, true);
if (R.checkBrightnes(x, y, currWidth, currHight, bright))
{
drawLine(x, currHight, currWidth, currHight, false);
parent.pictureBox2.Image = Form1.bmpLines;
parent.pictureBox2.Refresh();
R.divideImage(bright);
}
var R1 = new Rectangle(parent, x, y + currHight, currWidth, currHight, true);
if (R1.checkBrightnes(x, (y + currHight), currWidth, currHight, bright))
{
drawLine(x, currHight + y, currWidth, currHight, false);
//Form1.markRed(x, y + currHight);
parent.pictureBox2.Refresh();
R1.divideImage(bright);
}
}
}
};
private void DivImage_Click(object sender, EventArgs e)
{
Rectangle Rect = new Rectangle(this, 0, 0, 256, 256, true);
initBitmap();
int brightness = (int)numericUpDown1.Value;
if (Rect.checkBrightnes(0, 0, 256, 256, brightness))
{
Rect.divideImage(brightness);
}
vertexes.Add(new vertex(0, 0, ((Bitmap)Mem).GetPixel(0, 0)));
vertexes.Add(new vertex(pictureBox2.Size.Width - 1, 0, ((Bitmap)Mem).GetPixel(pictureBox2.Size.Width - 1, 0)));
vertexes.Add(new vertex(0, pictureBox2.Size.Height - 1, ((Bitmap)Mem).GetPixel(0, pictureBox2.Size.Height - 1)));
vertexes.Add(new vertex(pictureBox2.Size.Width - 1, pictureBox2.Size.Height - 1, ((Bitmap)Mem).GetPixel(pictureBox2.Size.Width - 1, pictureBox2.Size.Height - 1)));
//vertexes.Add(new vertex(100, 100, Color.Black));
//vertexes.Add(new vertex(160, 40, Color.Blue));
//vertexes.Add(new vertex(40, 20, Color.Red));
//vertexes.Add(new vertex(80, 80, Color.Red));
//vertexes.Add(new vertex(60, 130, Color.Black));
//vertexes.Add(new vertex(180, 100, Color.Black));
foreach (vertex v in vertexes)
{
bmpLines.SetPixel(v.x, v.y, v.currColor);
}
pictureBox2.Image = bmpLines;
pictureBox2.Refresh();
showTops();
}
public void drawSide( vertex begin, vertex end)
{
//int k = (begin.y - end.y) / (begin.x - end.x);
//int b = end.y - k * end.x;
//for (int i = begin.x; i < end.x; i++)
//{
// bmpLines.SetPixel(i, k*end.x + b, Color.Black);
//}
int m = vertexes.Count;
graphics.DrawLine(new Pen(Color.Black), new Point(begin.x, begin.y), new Point(end.x, end.y));
this.pictureBox2.Refresh();
}
private int getVertexDir(vertex first, vertex second, vertex third)
{
int turn = (third.x - first.x) * (second.y - first.y) - (third.y - first.y) * (second.x - first.x);
if (turn > 0)
{
return 1;
}
if (turn < 0)
{
return -1;
}
return 0;
}
/// <summary>
/// Choose two points of triangle and add
/// dir: a forbidden one (0 stands for "both allowed")
/// </summary>
public void triangulate(int f, int s, int dir, List<HashSet<int>> matrix)
{
vertex first = vertexes[f];
vertex second = vertexes[s];
first.free = false;
second.free = false;
drawSide(first, second);
bool checkVert = false;
double min = 2;
int n = 0;
for (int m = 0; m < vertexes.Count; m++)
{
if ((dir != 0 && getVertexDir(first, second, vertexes[m]) == dir))
{
continue;
}
if (matrix[f].Contains(m) && matrix[s].Contains(m))
{
triangles.Add(new Triangle(first, second, vertexes[m]));
return;
}
double fs = Math.Pow(first.x - second.x, 2) + Math.Pow(first.y - second.y, 2);
double fm = Math.Pow(first.x - vertexes[m].x, 2) + Math.Pow(first.y - vertexes[m].y, 2);
double ms = Math.Pow(vertexes[m].x - second.x, 2) + Math.Pow(vertexes[m].y - second.y, 2);
double curr = (-fs + fm + ms) / (2 * Math.Sqrt(fm * ms));
if (curr < min)
{
min = curr;
checkVert = true;
n = m;
}
}
if (checkVert)
{
triangles.Add(new Triangle(first, second, vertexes[n]));
matrix[f].Add(n);
matrix[s].Add(n);
matrix[n].Add(f);
matrix[n].Add(s);
drawSide(first, vertexes[n]);
drawSide(second, vertexes[n]);
triangulate(f, n, -getVertexDir(first, second, vertexes[n]), matrix);
triangulate(n, s, -getVertexDir(first, second, vertexes[n]), matrix);
}
}
//void getTriangles(List<HashSet<int>> matrix)
//{
// for (int i = 0; i < matrix.Count ; i++)
// {
// for (int j = 0; j < matrix[i].Count; j++)
// {
// int curr = matrix[i].ElementAt(j);
// if (curr >= i)
// {
// foreach (int elem in matrix[curr])
// {
// for (int m = 0; m < matrix[i].Count ; i++)
// {
// int elem2 = matrix[i].ElementAt(m);
// if (elem == elem2)
// {
// if () // check that we have elem and elem1 in row with number of their common value
// {
// triangles.Add(new Triangle( ))
// }
// }
// }
// }
// }
// }
// }
//}
private bool checkRule()
{
throw new NotImplementedException();
}
public void gradient(Triangle tre)
{
Point[] points = {
new Point(tre.v1.x, tre.v1.y),
new Point(tre.v2.x, tre.v2.y),
new Point(tre.v3.x, tre.v3.y)
};
PathGradientBrush pgbrush = new PathGradientBrush(points);
Color[] mySurroundColor = { tre.v1.currColor, tre.v2.currColor, tre.v3.currColor};
pgbrush.SurroundColors = mySurroundColor;
int averageR = (tre.v1.currColor.R + tre.v2.currColor.R + tre.v3.currColor.R) / 3;
int averageG = (tre.v1.currColor.G + tre.v2.currColor.G + tre.v3.currColor.G) / 3;
int averageB = (tre.v1.currColor.B + tre.v2.currColor.B + tre.v3.currColor.B) / 3;
Color centerCol = Color.FromArgb((byte) averageR, (byte)averageG, (byte)averageB);
pgbrush.CenterColor = centerCol;
pgbrush.SetBlendTriangularShape(1.0f, 1.0f);
graphics.FillPolygon(pgbrush, points);
}
private void Treangulation_Click(object sender, EventArgs e)
{
Bitmap bmpTre = bmpLines;
vertexes = vertexes.Distinct().ToList();
List<HashSet<int>> matrix = new List<HashSet<int>>();
for (int k = 0; k < vertexes.Count; k++)
{
matrix.Add(new HashSet<int>());
}
this.Text = "Triangulation in progress...";
int i = 0, j = 1;
if (vertexes[i].x < vertexes[j].x)
{
int temp = i;
i = j;
j = temp;
}
for (int k = 2; k < vertexes.Count; k++)
{
if (vertexes[k].x > vertexes[i].x)
{
j = i;
i = k;
}
else
{
if (vertexes[k].x > vertexes[j].x)
{
j = k;
}
}
}
triangulate(i, j, 0, matrix);
this.Text = "ImageChanger";
//showTops();
foreach (Triangle curr in triangles)
{
gradient(curr);
pictureBox2.Refresh();
}
}
}
}