zoukankan      html  css  js  c++  java
  • 图片撕纸效果处理

          

      

      /// <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">要处理的图片</param>
        /// <param name="tearOrientation">撕裂方位</param>
        /// <param name="shadowOrientation">撕裂阴影方位</param>
        /// <param name="avulsion">撕纸效果厚度(默认值8)</param>
        /// <param name="shadow">撕纸效果阴影厚度(默认值4)</param>
        /// <param name="interval">撕纸效果间距(默认值4)</param>
        /// <returns></returns>
        public static Bitmap TearIamge(Image img, 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) ^ x;
          return Math.Abs((1.0 - ((x * (x * x * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0));
        }
    
        /// <summary>
        /// 撕裂方位
        /// </summary>
        [Flags]
        [Description("撕裂方位")]
        public enum TearOrientation
        {
          None = 0,
          /// <summary>
          /// 上边
          /// </summary>
          Top = 2,
          /// <summary>
          /// 下边
          /// </summary>
          Bottom = 4,
          /// <summary>
          /// 左边
          /// </summary>
          Left = 8,
          /// <summary>
          /// 右边
          /// </summary>
          Right = 16
        }
    
        /// <summary>
        /// 撕裂阴影方位
        /// </summary>
        [Flags]
        [Description("撕裂阴影方位")]
        public enum ShadowOrientation
        {
          None = 0,
          /// <summary>
          /// 上边
          /// </summary>
          Top = 2,
          /// <summary>
          /// 下边
          /// </summary>
          Bottom = 4,
          /// <summary>
          /// 左边
          /// </summary>
          Left = 8,
          /// <summary>
          /// 右边
          /// </summary>
          Right = 16
        }
      }

    源码下载:撕纸效果.zip

  • 相关阅读:
    leetcode Remove Linked List Elements
    leetcode Word Pattern
    leetcode Isomorphic Strings
    leetcode Valid Parentheses
    leetcode Remove Nth Node From End of List
    leetcode Contains Duplicate II
    leetcode Rectangle Area
    leetcode Length of Last Word
    leetcode Valid Sudoku
    leetcode Reverse Bits
  • 原文地址:https://www.cnblogs.com/tlmbem/p/11562960.html
Copyright © 2011-2022 走看看