Picture tear effects processing

      

  /// <summary>
  /// 撕纸效果
  /// </summary>
  public class TearHelper
  {
    private static SolidBrush out_sb = new SolidBrush(Color.FromArgb(80, 110, 105, 109));
    private static Pen out_pen = new Pen(Color.FromArgb(220, 128, 128, 128));
    /// <summary>
    /// 撕纸
    /// </summary>
    /// <param name="img">Images to be processed </ param> 
    ///  <param name = "tearOrientation"> tearing position </ param> 
    ///  <param name = "shadowOrientation"> torn shadow position </ param> 
    ///  <param name = "avulsion"> tear results thickness (default. 8) </ param> 
    ///  <param name = "shadow"> (default 4) the thickness of the shadow effect of the tear </ param> 
    ///  <param name = "interval"> tear effect pitch (default. 4) </ param> 
    ///  <Returns> </ Returns> 
    public  static Bitmap TearIamge (IMG Image, tearOrientation tearOrientation = TearOrientation.Bottom | TearOrientation.Right,ShadowOrientation shadowOrientation = ShadowOrientation.Bottom|ShadowOrientation.Right, int avulsion = 8, int shadow = 4, int interval = 4)
    {
      Bitmap bmp = new Bitmap(img.Width, img.Height);
      Graphics bmp_g = Graphics.FromImage(bmp);
      Region r = bmp_g.Clip;
      int x = 0;

      #region 内图大小
      Rectangle bmp_in_rect = new Rectangle(0, 0, img.Width, img.Height);
      if (tearOrientation.HasFlag(TearOrientation.Bottom))
      {
        bmp_in_rect.Height -= avulsion;
        if (shadowOrientation.HasFlag(ShadowOrientation.Bottom))
        {
          bmp_in_rect.Height -= shadow;
        }
      }
      if (tearOrientation.HasFlag(TearOrientation.Right))
      {
        bmp_in_rect.Width -= avulsion;
        if (shadowOrientation.HasFlag(ShadowOrientation.Right))
        {
          bmp_in_rect.Width -= shadow;
        }
      }
      if (tearOrientation.HasFlag(TearOrientation.Left))
      {
        bmp_in_rect.Width -= avulsion;
        bmp_in_rect.X += avulsion;
        if (shadowOrientation.HasFlag(ShadowOrientation.Left))
        {
          bmp_in_rect.Width -= shadow;
          bmp_in_rect.X += shadow;
        }
      }
      if (tearOrientation.HasFlag(TearOrientation.Top))
      {
        bmp_in_rect.Height -= avulsion;
        bmp_in_rect.Y += avulsion;
        if (shadowOrientation.HasFlag(ShadowOrientation.Top))
        {
          bmp_in_rect.Height -= shadow;
          bmp_in_rect.Y += shadow;
        }
      }
      #endregion

      #region 计算撕纸路径
      #region
      int bottom_in_len = 0;
      Point[] bottom_in_point;
      int bottom_out_len = 0;
      Point[] bottom_out_point;
      if (tearOrientation.HasFlag(TearOrientation.Bottom))
      {
        bottom_in_len = (int)Math.Round((double)bmp_in_rect.Width / interval, 0);
        bottom_in_point = new Point[bottom_in_len];
        for (int i = 0; i < bottom_in_len; i++)
        {
          x++;
          bottom_in_point[i] = new Point(bmp_in_rect.X + i * interval, bmp_in_rect.Bottom + (int)(RandomNumber(x * interval) * avulsion));
        }
        if (bottom_in_point[bottom_in_len - 1].X > bmp_in_rect.Right)
        {
          bottom_in_point[bottom_in_len - 1].X = bmp_in_rect.Right;
        }

        if (shadowOrientation.HasFlag(ShadowOrientation.Bottom))
        {
          bottom_out_len = bottom_in_len;
          bottom_out_point = new Point[bottom_out_len];
          for (int i = 0; i < bottom_out_len; i++)
          {
            bottom_out_point[i] = new Point(bottom_in_point[i].X, bottom_in_point[i].Y + shadow);
          }
        }
        else
        {
          bottom_out_len = 2;
          bottom_out_point = new Point[bottom_out_len];
          bottom_out_point[0] = new Point(bmp_in_rect.Left, bmp_in_rect.Bottom);
          bottom_out_point[1] = new Point(bmp_in_rect.Right, bmp_in_rect.Bottom);
        }
      }
      else
      {
        bottom_in_len = 2;
        bottom_in_point = new Point[bottom_in_len];
        bottom_in_point[0] = new Point(bmp_in_rect.Left, bmp_in_rect.Bottom);
        bottom_in_point[1] = new Point(bmp_in_rect.Right, bmp_in_rect.Bottom);
        bottom_out_len = 2;
        bottom_out_point = new Point[bottom_out_len];
        bottom_out_point[0] = new Point(bmp_in_rect.Left, bmp_in_rect.Bottom);
        bottom_out_point[1] = new Point(bmp_in_rect.Right, bmp_in_rect.Bottom);
      }
      #endregion
      #region
      int right_in_len = 0;
      Point[] right_in_point;
      int right_out_len = 0;
      Point[] right_out_point;
      if (tearOrientation.HasFlag(TearOrientation.Right))
      {
        right_in_len = (int)Math.Round((double)bmp_in_rect.Height / interval, 0);
        right_in_point = new Point[right_in_len];
        for (int i = 0; i < right_in_len; i++)
        {
          x++;
          right_in_point[i] = new Point(bmp_in_rect.Right + (int)(RandomNumber(x * interval) * avulsion), bmp_in_rect.Bottom - i * interval);
        }
        if (right_in_point[right_in_len - 1].Y < bmp_in_rect.Top)
        {
          right_in_point[right_in_len - 1].Y = bmp_in_rect.Top;
        }

        if (shadowOrientation.HasFlag(ShadowOrientation.Right))
        {
          right_out_len = right_in_len;
          right_out_point = new Point[right_out_len];
          for (int i = 0; i < right_out_len; i++)
          {
            right_out_point[i] = new Point(right_in_point[i].X + shadow, right_in_point[i].Y);
          }
        }
        else
        {
          right_out_len = 2;
          right_out_point = new Point[right_out_len];
          right_out_point[0] = new Point(bmp_in_rect.Right, bmp_in_rect.Bottom);
          right_out_point[1] = new Point(bmp_in_rect.Right, bmp_in_rect.Top);
        }
      }
      else
      {
        right_in_len = 2;
        right_in_point = new Point[right_in_len];
        right_in_point[0] = new Point(bmp_in_rect.Right, bmp_in_rect.Bottom);
        right_in_point[1] = new Point(bmp_in_rect.Right, bmp_in_rect.Top);
        right_out_len = 2;
        right_out_point = new Point[right_out_len];
        right_out_point[0] = new Point(bmp_in_rect.Right, bmp_in_rect.Bottom);
        right_out_point[1] = new Point(bmp_in_rect.Right, bmp_in_rect.Top);
      }
      #endregion
      #region
      int top_in_len = 0;
      Point[] top_in_point;
      int top_out_len = 0;
      Point[] top_out_point;
      if (tearOrientation.HasFlag(TearOrientation.Top))
      {
        top_in_len = (int)Math.Round((double)bmp_in_rect.Width / interval, 0);
        top_in_point = new Point[top_in_len];
        for (int i = 0; i < top_in_len; i++)
        {
          x++;
          top_in_point[i] = new Point(bmp_in_rect.Right - i * interval, bmp_in_rect.Y - (int)(RandomNumber(x * interval) * avulsion));
        }
        if (top_in_point[top_in_len - 1].X < bmp_in_rect.Left)
        {
          top_in_point[top_in_len - 1].X = bmp_in_rect.Left;
        }

        if (shadowOrientation.HasFlag(ShadowOrientation.Top))
        {
          top_out_len = top_in_len;
          top_out_point = new Point[top_out_len];
          for (int i = 0; i < top_out_len; i++)
          {
            top_out_point[i] = new Point(top_in_point[i].X, top_in_point[i].Y - shadow);
          }
        }
        else
        {
          top_out_len = 2;
          top_out_point = new Point[top_out_len];
          top_out_point[0] = new Point(bmp_in_rect.Right, bmp_in_rect.Top);
          top_out_point[1] = new Point(bmp_in_rect.Left, bmp_in_rect.Top);
        }
      }
      else
      {
        top_in_len = 2;
        top_in_point = new Point[top_in_len];
        top_in_point[0] = new Point(bmp_in_rect.Right, bmp_in_rect.Top);
        top_in_point[1] = new Point(bmp_in_rect.Left, bmp_in_rect.Top);
        top_out_len = 2;
        top_out_point = new Point[top_out_len];
        top_out_point[0] = new Point(bmp_in_rect.Right, bmp_in_rect.Top);
        top_out_point[1] = new Point(bmp_in_rect.Left, bmp_in_rect.Top);
      }
      #endregion
      #region
      int left_in_len = 0;
      Point[] left_in_point;
      int left_out_len = 0;
      Point[] left_out_point;
      if (tearOrientation.HasFlag(TearOrientation.Left))
      {
        left_in_len = (int)Math.Round((double)bmp_in_rect.Height / interval, 0);
        left_in_point = new Point[left_in_len];
        for (int i = 0; i < left_in_len; i++)
        {
          x++;
          left_in_point[i] = new Point(bmp_in_rect.X - (int)(RandomNumber(x * interval) * avulsion), bmp_in_rect.Y + i * interval);
        }
        if (left_in_point[left_in_len - 1].Y > bmp_in_rect.Bottom)
        {
          left_in_point[left_in_len - 1].Y = bmp_in_rect.Bottom;
        }

        if (shadowOrientation.HasFlag(ShadowOrientation.Left))
        {
          left_out_len = left_in_len;
          left_out_point = new Point[left_out_len];
          for (int i = 0; i < left_out_len; i++)
          {
            left_out_point[i] = new Point(left_in_point[i].X - shadow, left_in_point[i].Y);
          }
        }
        else
        {
          left_out_len = 2;
          left_out_point = new Point[left_out_len];
          left_out_point[0] = new Point(bmp_in_rect.Left, bmp_in_rect.Top);
          left_out_point[1] = new Point(bmp_in_rect.Left, bmp_in_rect.Bottom);
        }
      }
      else
      {
        left_in_len = 2;
        left_in_point = new Point[left_in_len];
        left_in_point[0] = new Point(bmp_in_rect.Left, bmp_in_rect.Top);
        left_in_point[1] = new Point(bmp_in_rect.Left, bmp_in_rect.Bottom);
        left_out_len = 2;
        left_out_point = new Point[left_out_len];
        left_out_point[0] = new Point(bmp_in_rect.Left, bmp_in_rect.Top);
        left_out_point[1] = new Point(bmp_in_rect.Left, bmp_in_rect.Bottom);
      }
      #endregion
      #endregion

      #region 撕纸效果阴影
      if (shadowOrientation != ShadowOrientation.None)
      {
        GraphicsPath out_gp = new GraphicsPath();
        out_gp.AddLines(bottom_out_point);
        out_gp.AddLines(right_out_point);
        out_gp.AddLines(top_out_point);
        out_gp.AddLines(left_out_point);
        Region out_r = new System.Drawing.Region(out_gp);
        bmp_g.Clip = out_r;
        bmp_g.FillRegion(out_sb, out_r);
        out_r.Dispose();
        out_gp.Dispose();
      }
      #endregion

      #region 撕纸效果
      GraphicsPath in_gp = new GraphicsPath();
      in_gp.AddLines(bottom_in_point);
      in_gp.AddLines(right_in_point);
      in_gp.AddLines(top_in_point);
      in_gp.AddLines(left_in_point);
      Region in_r = new System.Drawing.Region(in_gp);
      bmp_g.Clip = in_r;
      int in_x = bmp_in_rect.X - (tearOrientation.HasFlag(TearOrientation.Left) ? (shadowOrientation.HasFlag(ShadowOrientation.Left) ? avulsion + shadow : avulsion) : 0);
      int in_y = bmp_in_rect.Y - (tearOrientation.HasFlag(TearOrientation.Top) ? (shadowOrientation.HasFlag(ShadowOrientation.Top) ? avulsion + shadow : avulsion) : 0);
      bmp_g.DrawImage(img, in_x, in_y);
      bmp_g.Clip = r;
      bmp_g.DrawPath(out_pen, in_gp);
      in_gp.Dispose();
      #endregion

      in_r.Dispose();
      bmp_g.Dispose();
      return bmp;
    }

    /// <summary>
    ///返回0.0-1.0的随机数
    /// </summary>
    /// <param name="x"></param>
    /// <returns></returns>
    private static Double RandomNumber ( int X) 
    { 
      X = (X << 13 is ) ^ X;
       return the Math.Abs (( 1.0 - ((X * (X * X * 15731 + 789 221 ) + 1376312589 ) & 0x7FFFFFFF ) / 1073741824.0 )); 
    } 

    ///  <Summary> 
    /// tear orientation
     ///  </ Summary> 
    [the Flags] 
    [the Description ( " tear orientation " )]
     public  enum TearOrientation 
    { 
      None =0,
       ///  <Summary> 
      /// upper
       ///  </ Summary> 
      Top = 2 ,
       ///  <Summary> 
      /// lower
       ///  </ Summary> 
      Bottom = . 4 ,
       ///  <Summary> 
      / // left
       ///  </ Summary> 
      left = . 8 ,
       ///  <Summary> 
      /// the right
       ///  </ Summary> 
      Right = 16 
    } 

    ///  <Summary> 
    /// tear shadow orientation
     @ /  </ Summary>
    [The Flags] 
    [the Description ( " Tear hatched orientation " )]
     public  enum ShadowOrientation 
    { 
      None = 0 ,
       ///  <Summary> 
      /// upper
       ///  </ Summary> 
      Top = 2 ,
       ///  <Summary> 
      / // lower
       ///  </ Summary> 
      Bottom = . 4 ,
       ///  <Summary> 
      /// left
       ///  </ Summary> 
      left = . 8 ,
       ///  <Summary>
      /// the right
       ///  </ Summary> 
      Right = 16 
    } 
  }

Download Source: Tear-off effect .zip

Guess you like

Origin www.cnblogs.com/tlmbem/p/11562960.html