Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public interface IPair
- {
- IPair Clone();
- int GetResult(int[,] img);
- }
- public class NumericPair : IPair
- {
- private int x1, y1, x2, y2;
- public NumericPair(int ix1, int iy1, int ix2, int iy2)
- {
- x1 = ix1;
- y1 = iy1;
- x2 = ix2;
- y2 = iy2;
- }
- public int GetResult(int[,] img)
- {
- return (int)Math.Round((img[x1, y1] + img[x2, y2]) / 2.0);
- }
- public IPair Clone()
- {
- return new NumericPair(x1, y1, x2, y2);
- }
- }
- public class PairPair : IPair
- {
- private IPair n1, n2;
- public PairPair(IPair num_1, IPair num_2)
- {
- n1 = num_1;
- n2 = num_2;
- }
- public int GetResult(int[,] img)
- {
- return (int)Math.Round((n1.GetResult(img) + n2.GetResult(img)) / 2.0);
- }
- public IPair Clone()
- {
- return new PairPair(n1, n2);
- }
- }
- public class NullPair : IPair
- {
- public NullPair()
- {
- }
- public int GetResult(int[,] img)
- {
- return -1;
- }
- public IPair Clone()
- {
- return new NullPair();
- }
- }
- public class DeformateInfoCreator
- {
- private bool test(Point[] polygon)
- {
- int min_x = int.MaxValue;
- int max_x = int.MinValue;
- int min_y = int.MaxValue;
- int max_y = int.MinValue;
- foreach (Point i in polygon)
- {
- if (i.X < min_x) min_x = i.X;
- if (i.X > max_x) max_x = i.X;
- if (i.Y < min_y) min_y = i.Y;
- if (i.Y > max_y) max_y = i.Y;
- }
- int size_x = max_x - min_x;
- int size_y = max_y - min_y;
- if (size_x == 0 || size_y == 0) return false;
- return true;
- }
- private IPair[,] primary_pairization(Point[] polygon)
- {
- int min_x = int.MaxValue;
- int max_x = int.MinValue;
- int min_y = int.MaxValue;
- int max_y = int.MinValue;
- foreach (Point i in polygon)
- {
- if (i.X < min_x) min_x = i.X;
- if (i.X > max_x) max_x = i.X;
- if (i.Y < min_y) min_y = i.Y;
- if (i.Y > max_y) max_y = i.Y;
- }
- int width = max_x - min_x;
- int height = max_y - min_y;
- IPair[,] res = new IPair[width, height];
- for (int x = 0; x < width; x++)
- {
- for (int y = 0; y < height; y++)
- {
- res[x, y] = new NumericPair(x, y, x, y);
- }
- }
- return res;
- }
- private void left_deformation(int width, int height, IPair[,] img, Point dp, Point tp)
- {
- int delta = Math.Abs(dp.X - tp.X); // Смещение
- if (delta == 0) return;
- double part_size = (double)((double)height / (double)delta);
- if (dp.X > tp.X)
- {
- for (int i = 1; i <= delta; i++)
- {
- for (int y = (int)(i * part_size); y < height; y++)
- {
- for (int x = width - 1; x >= i; x--)
- {
- if (!(img[x, y] is NullPair))
- {
- img[x, y] = new PairPair(img[x, y].Clone(), img[x - 1, y].Clone());
- }
- }
- for (int x = i - 1; x >= 0; x--)
- {
- img[x, y] = new NullPair();
- }
- }
- }
- }
- else
- {
- for (int i = 1; i <= delta; i++)
- {
- for (int y = (int)(i * part_size); y < height; y++)
- {
- for (int x = width - 1; x >= i; x--)
- {
- img[x, height - y - 1] = new PairPair(img[x, height - y - 1].Clone(), img[x - 1, height - y - 1].Clone());
- }
- for (int x = i - 1; x >= 0; x--)
- {
- img[x, height - y - 1] = new NullPair();
- }
- }
- }
- }
- }
- private void right_deformation(int width, int height, IPair[,] img, Point dp, Point tp)
- {
- int delta = Math.Abs(dp.X - tp.X); // Смещение
- if (delta == 0) return;
- double part_size = (double)((double)height / (double)delta);
- if (dp.X < tp.X)
- {
- for (int i = 1; i <= delta; i++)
- {
- for (int y = (int)(i * part_size); y < height; y++)
- {
- for (int x = 0; x < width - i; x++)
- {
- if (!(img[x, y] is NullPair))
- {
- img[x, y] = new PairPair(img[x, y].Clone(), img[x + 1, y].Clone());
- }
- }
- for (int x = width - i; x < width; x++)
- {
- img[x, y] = new NullPair();
- }
- }
- }
- }
- else
- {
- for (int i = 1; i <= delta; i++)
- {
- for (int y = (int)(i * part_size); y < height; y++)
- {
- for (int x = 0; x < width - i; x++)
- {
- if (!(img[x, height - y - 1] is NullPair))
- {
- img[x, height - y - 1] = new PairPair(img[x, height - y - 1].Clone(), img[x + 1, height - y - 1].Clone());
- }
- }
- for (int x = width - i; x < width; x++)
- {
- img[x, height - y - 1] = new NullPair();
- }
- }
- }
- }
- }
- private void top_deformation(int width, int height, IPair[,] img, Point lp, Point rp)
- {
- int delta = Math.Abs(lp.Y - rp.Y); // Смещение
- if (delta == 0) return;
- double part_size = (double)((double)width / (double)delta);
- if (lp.Y < rp.Y)
- {
- for (int i = 1; i <= delta; i++)
- {
- for (int x = (int)(i * part_size); x < width; x++)
- {
- for (int y = height - 1; y >= i; y--)
- {
- if (!(img[x, y] is NullPair))
- {
- img[x, y] = new PairPair(img[x, y].Clone(), img[x, y - 1].Clone());
- }
- }
- for (int y = i; y >= 0; y--)
- {
- img[x, y] = new NullPair();
- }
- }
- }
- }
- else
- {
- for (int i = 1; i <= delta; i++)
- {
- for (int x = (int)(i * part_size); x < width; x++)
- {
- for (int y = height - 1; y >= i; y--)
- {
- if (!(img[width - x - 1, y] is NullPair))
- {
- img[width - x - 1, y] = new PairPair(img[width - x - 1, y].Clone(), img[width - x - 1, y - 1].Clone());
- }
- }
- for (int y = i; y >= 0; y--)
- {
- img[width - x - 1, y] = new NullPair();
- }
- }
- }
- }
- }
- private void down_deformation(int width, int height, IPair[,] img, Point lp, Point rp)
- {
- int delta = Math.Abs(lp.Y - rp.Y); // Смещение
- if (delta == 0) return;
- double part_size = (double)((double)width / (double)delta);
- if (lp.Y > rp.Y)
- {
- for (int i = 1; i <= delta; i++)
- {
- for (int x = (int)(i * part_size); x < width; x++)
- {
- for (int y = 0; y < height - i; y++)
- {
- if (!(img[x, y] is NullPair))
- {
- img[x, y] = new PairPair(img[x, y].Clone(), img[x, y + 1].Clone());
- }
- }
- for (int y = height - i; y < height; y++)
- {
- img[x, y] = new NullPair();
- }
- }
- }
- }
- else
- {
- for (int i = 1; i <= delta; i++)
- {
- for (int x = (int)(i * part_size); x < width; x++)
- {
- for (int y = 0; y < height - i; y++)
- {
- if (!(img[width - x - 1, y] is NullPair))
- {
- img[width - x - 1, y] = new PairPair(img[width - x - 1, y].Clone(), img[width - x - 1, y + 1].Clone());
- }
- }
- for (int y = height - i; y < height; y++)
- {
- img[width - x - 1, y] = new NullPair();
- }
- }
- }
- }
- }
- public IPair[,] GetDeformInfo(Point[] polygon)
- {
- if (!test(polygon)) return null;
- IPair[,] res = primary_pairization(polygon);
- int width = res.GetLength(0);
- int height = res.GetLength(1);
- left_deformation(width, height, res, polygon[0], polygon[1]);
- right_deformation(width, height, res, polygon[3], polygon[2]);
- top_deformation(width, height, res, polygon[1], polygon[2]);
- down_deformation(width, height, res, polygon[0], polygon[3]);
- return res;
- }
- }
- public class TextureDeformator
- {
- private bool test(Point[] polygon)
- {
- int min_x = int.MaxValue;
- int max_x = int.MinValue;
- int min_y = int.MaxValue;
- int max_y = int.MinValue;
- foreach (Point i in polygon)
- {
- if (i.X < min_x) min_x = i.X;
- if (i.X > max_x) max_x = i.X;
- if (i.Y < min_y) min_y = i.Y;
- if (i.Y > max_y) max_y = i.Y;
- }
- int size_x = max_x - min_x;
- int size_y = max_y - min_y;
- if (size_x == 0 || size_y == 0) return false;
- return true;
- }
- private Bitmap primary_fitting(Bitmap texture, Point[] polygon)
- {
- int min_x = int.MaxValue;
- int max_x = int.MinValue;
- int min_y = int.MaxValue;
- int max_y = int.MinValue;
- foreach (Point i in polygon)
- {
- if (i.X < min_x) min_x = i.X;
- if (i.X > max_x) max_x = i.X;
- if (i.Y < min_y) min_y = i.Y;
- if (i.Y > max_y) max_y = i.Y;
- }
- int size_x = max_x - min_x;
- int size_y = max_y - min_y;
- Bitmap res = new Bitmap(size_x, size_y);
- using (Graphics g = Graphics.FromImage(res))
- {
- g.DrawImage(texture, 0, 0, size_x, size_y);
- }
- return res;
- }
- private byte color_to_byte(Color color)
- {
- byte r = color.R;
- byte g = color.G;
- byte b = color.B;
- return (byte)((r + g + b) / 3);
- }
- private int[,] primary_digitization(Bitmap texture)
- {
- int w = texture.Width;
- int h = texture.Height;
- int[,] res = new int[w, h];
- Color c;
- for (int x = 0; x < w; x++)
- {
- for (int y = 0; y < h; y++)
- {
- c = texture.GetPixel(x, y);
- res[x, y] = color_to_byte(c);
- }
- }
- return res;
- }
- private Bitmap final_draw(int width, int height, int[,] img)
- {
- Bitmap res = new Bitmap(width, height);
- for (int x = 0; x < width; x++)
- {
- for (int y = 0; y < height; y++)
- {
- if (img[x, y] < 0) res.SetPixel(x, y, Color.FromArgb(0, 0, 0, 0));
- else res.SetPixel(x, y, Color.FromArgb(img[x, y], img[x, y], img[x, y]));
- }
- }
- return res;
- }
- private int[,] deformation_with_info(int[,] img, IPair[,] info)
- {
- int w = img.GetLength(0);
- int h = img.GetLength(1);
- int[,] res = new int[w, h];
- for (int x = 0; x < w; x++)
- {
- for (int y = 0; y < h; y++)
- {
- res[x, y] = info[x, y].GetResult(img);
- }
- }
- return res;
- }
- public Bitmap Deformate(Bitmap texture, Point[] polygon, IPair[,] deform_info)
- {
- if (!test(polygon)) return new Bitmap(1, 1);
- if (deform_info == null) return new Bitmap(1, 1);
- Bitmap res = primary_fitting(texture, polygon);
- int[,] img = primary_digitization(res);
- img = deformation_with_info(img, deform_info);
- res = final_draw(res.Width, res.Height, img);
- return res;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement