Advertisement
xxeell

Untitled

Aug 12th, 2018
123
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 10.34 KB | None | 0 0
  1.     public class TextureDeformator
  2.     {
  3.         private bool test(Point[] polygon)
  4.         {
  5.             int min_x = int.MaxValue;
  6.             int max_x = int.MinValue;
  7.             int min_y = int.MaxValue;
  8.             int max_y = int.MinValue;
  9.  
  10.             foreach (Point i in polygon)
  11.             {
  12.                 if (i.X < min_x) min_x = i.X;
  13.                 if (i.X > max_x) max_x = i.X;
  14.                 if (i.Y < min_y) min_y = i.Y;
  15.                 if (i.Y > max_y) max_y = i.Y;
  16.             }
  17.  
  18.             int size_x = max_x - min_x;
  19.             int size_y = max_y - min_y;
  20.  
  21.             if (size_x == 0 || size_y == 0) return false;
  22.             return true;
  23.         }
  24.  
  25.         private Bitmap primary_fitting(Bitmap texture, Point[] polygon)
  26.         {
  27.             int min_x = int.MaxValue;
  28.             int max_x = int.MinValue;
  29.             int min_y = int.MaxValue;
  30.             int max_y = int.MinValue;
  31.  
  32.             foreach (Point i in polygon)
  33.             {
  34.                 if (i.X < min_x) min_x = i.X;
  35.                 if (i.X > max_x) max_x = i.X;
  36.                 if (i.Y < min_y) min_y = i.Y;
  37.                 if (i.Y > max_y) max_y = i.Y;
  38.             }
  39.  
  40.             int size_x = max_x - min_x;
  41.             int size_y = max_y - min_y;
  42.  
  43.             Bitmap res = new Bitmap(size_x, size_y);
  44.  
  45.             using (Graphics g = Graphics.FromImage(res))
  46.             {
  47.                 g.DrawImage(texture, 0, 0, size_x, size_y);
  48.             }
  49.  
  50.             return res;
  51.         }
  52.  
  53.         private byte color_to_byte(Color color)
  54.         {
  55.             byte r = color.R;
  56.             byte g = color.G;
  57.             byte b = color.B;
  58.  
  59.             return (byte)((r + g + b) / 3);
  60.         }
  61.  
  62.         private int[,] primary_digitization(Bitmap texture)
  63.         {
  64.             int w = texture.Width;
  65.             int h = texture.Height;
  66.  
  67.             int[,] res = new int[w, h];
  68.             Color c;
  69.  
  70.             for (int x = 0; x < w; x++)
  71.             {
  72.                 for (int y = 0; y < h; y++)
  73.                 {
  74.                     c = texture.GetPixel(x, y);
  75.                     res[x, y] = color_to_byte(c);
  76.                 }
  77.             }
  78.  
  79.             return res;
  80.         }
  81.  
  82.         private void left_deformation(int width, int height, int[,] img, Point dp, Point tp)
  83.         {
  84.             int delta = Math.Abs(dp.X - tp.X); // Смещение
  85.             if (delta == 0) return;
  86.  
  87.             double part_size = (double)((double)height / (double)delta);
  88.  
  89.             if (dp.X > tp.X)
  90.             {
  91.                 for (int i = 1; i <= delta; i++)
  92.                 {
  93.                     for (int y = (int)(i * part_size); y < height; y++)
  94.                     {
  95.                         for (int x = width - 1; x >= i; x--)
  96.                         {
  97.                             if (img[x, y] >= 0)
  98.                             {
  99.                                 img[x, y] = (img[x, y] + img[x - 1, y]) / 2;
  100.                             }
  101.                         }
  102.                         for (int x = i - 1; x >= 0; x--)
  103.                         {
  104.                             img[x, y] = -1;
  105.                         }
  106.                     }
  107.                 }
  108.             }
  109.             else
  110.             {
  111.                 for (int i = 1; i <= delta; i++)
  112.                 {
  113.                     for (int y = (int)(i * part_size); y < height; y++)
  114.                     {
  115.                         for (int x = width - 1; x >= i; x--)
  116.                         {
  117.                             img[x, height - y - 1] = (img[x, height - y - 1] + img[x - 1, height - y - 1]) / 2;
  118.                         }
  119.                         for (int x = i - 1; x >= 0; x--)
  120.                         {
  121.                             img[x, height - y - 1] = -1;
  122.                         }
  123.                     }
  124.                 }
  125.             }
  126.         }
  127.  
  128.         private void right_deformation(int width, int height, int[,] img, Point dp, Point tp)
  129.         {
  130.             int delta = Math.Abs(dp.X - tp.X); // Смещение
  131.             if (delta == 0) return;
  132.  
  133.             double part_size = (double)((double)height / (double)delta);
  134.  
  135.             if (dp.X < tp.X)
  136.             {
  137.                 for (int i = 1; i <= delta; i++)
  138.                 {
  139.                     for (int y = (int)(i * part_size); y < height; y++)
  140.                     {
  141.                         for (int x = 0; x < width - i; x++)
  142.                         {
  143.                             if (img[x, y] >= 0)
  144.                             {
  145.                                 img[x, y] = (img[x, y] + img[x + 1, y]) / 2;
  146.                             }
  147.                         }
  148.                         for (int x = width - i; x < width; x++)
  149.                         {
  150.                             img[x, y] = -1;
  151.                         }
  152.                     }
  153.                 }
  154.             }
  155.             else
  156.             {
  157.                 for (int i = 1; i <= delta; i++)
  158.                 {
  159.                     for (int y = (int)(i * part_size); y < height; y++)
  160.                     {
  161.                         for (int x = 0; x < width - i; x++)
  162.                         {
  163.                             if (img[x, height - y - 1] >= 0)
  164.                             {
  165.                                 img[x, height - y - 1] = (img[x, height - y - 1] + img[x + 1, height - y - 1]) / 2;
  166.                             }
  167.                         }
  168.                         for (int x = width - i; x < width; x++)
  169.                         {
  170.                             img[x, height - y - 1] = -1;
  171.                         }
  172.                     }
  173.                 }
  174.             }
  175.         }
  176.  
  177.         private void top_deformation(int width, int height, int[,] img, Point lp, Point rp)
  178.         {
  179.             int delta = Math.Abs(lp.Y - rp.Y); // Смещение
  180.             if (delta == 0) return;
  181.  
  182.             double part_size = (double)((double)width / (double)delta);
  183.  
  184.             if (lp.Y < rp.Y)
  185.             {
  186.                 for (int i = 1; i <= delta; i++)
  187.                 {
  188.                     for (int x = (int)(i * part_size); x < width; x++)
  189.                     {
  190.                         for (int y = height - 1; y >= i ; y--)
  191.                         {
  192.                             if (img[x, y] >= 0)
  193.                             {
  194.                                 img[x, y] = (img[x, y] + img[x, y - 1]) / 2;
  195.                             }
  196.                         }
  197.                         for (int y = i; y >= 0; y--)
  198.                         {
  199.                             img[x, y] = -1;
  200.                         }
  201.                     }
  202.                 }
  203.             }
  204.             else
  205.             {
  206.                 for (int i = 1; i <= delta; i++)
  207.                 {
  208.                     for (int x = (int)(i * part_size); x < width; x++)
  209.                     {
  210.                         for (int y = height - 1; y >= i; y--)
  211.                         {
  212.                             if (img[width - x - 1, y] >= 0)
  213.                             {
  214.                                 img[width - x - 1, y] = (img[width - x - 1, y] + img[width - x - 1, y - 1]) / 2;
  215.                             }
  216.                         }
  217.                         for (int y = i; y >= 0; y--)
  218.                         {
  219.                             img[width - x - 1, y] = -1;
  220.                         }
  221.                     }
  222.                 }
  223.             }
  224.         }
  225.  
  226.         private void down_deformation(int width, int height, int[,] img, Point lp, Point rp)
  227.         {
  228.             int delta = Math.Abs(lp.Y - rp.Y); // Смещение
  229.             if (delta == 0) return;
  230.  
  231.             double part_size = (double)((double)width / (double)delta);
  232.  
  233.             if (lp.Y > rp.Y)
  234.             {
  235.                 for (int i = 1; i <= delta; i++)
  236.                 {
  237.                     for (int x = (int)(i * part_size); x < width; x++)
  238.                     {
  239.                         for (int y = 0; y < height - i; y++)
  240.                         {
  241.                             if (img[x, y] >= 0)
  242.                             {
  243.                                 img[x, y] = (img[x, y] + img[x, y + 1]) / 2;
  244.                             }
  245.                         }
  246.                         for (int y = height - i; y < height; y++)
  247.                         {
  248.                             img[x, y] = -1;
  249.                         }
  250.                     }
  251.                 }
  252.             }
  253.             else
  254.             {
  255.                 for (int i = 1; i <= delta; i++)
  256.                 {
  257.                     for (int x = (int)(i * part_size); x < width; x++)
  258.                     {
  259.                         for (int y = 0; y < height - i; y++)
  260.                         {
  261.                             if (img[width - x - 1, y] >= 0)
  262.                             {
  263.                                 img[width - x - 1, y] = (img[width - x - 1, y] + img[width - x - 1, y + 1]) / 2;
  264.                             }
  265.                         }
  266.                         for (int y = height - i; y < height; y++)
  267.                         {
  268.                             img[width - x - 1, y] = -1;
  269.                         }
  270.                     }
  271.                 }
  272.             }
  273.         }
  274.  
  275.         private Bitmap final_draw(int width, int height, int[,] img)
  276.         {
  277.             Bitmap res = new Bitmap(width, height);
  278.  
  279.             for (int x = 0; x < width; x++)
  280.             {
  281.                 for (int y = 0; y < height; y++)
  282.                 {
  283.                     if (img[x, y] < 0) res.SetPixel(x, y, Color.FromArgb(0, 0, 0, 0));
  284.                     else res.SetPixel(x, y, Color.FromArgb(img[x, y], img[x, y], img[x, y]));
  285.                 }
  286.             }
  287.  
  288.             return res;
  289.         }
  290.  
  291.         public Bitmap Deformate(Bitmap texture, Point[] polygon)
  292.         {
  293.             if (!test(polygon)) return new Bitmap(1, 1);
  294.  
  295.             Bitmap res = primary_fitting(texture, polygon);
  296.             int[,] img = primary_digitization(res);
  297.  
  298.             left_deformation(res.Width, res.Height, img, polygon[0], polygon[1]);
  299.             right_deformation(res.Width, res.Height, img, polygon[3], polygon[2]);
  300.             top_deformation(res.Width, res.Height, img, polygon[1], polygon[2]);
  301.             down_deformation(res.Width, res.Height, img, polygon[0], polygon[3]);
  302.  
  303.             res = final_draw(res.Width, res.Height, img);
  304.  
  305.             return res;
  306.         }
  307.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement