⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 function.cs

📁 一个C#开发的类似PHOTOSHOP的软件,用到了很多图形算法.
💻 CS
字号:
using System;
using System.Drawing;
using System.Text.RegularExpressions;

namespace PhotoSprite.ImageProcessing
{
  /// <summary>
  /// PhotoSprite 常用函数类
  /// </summary>
  public class Function
  {
    /**************************************************
     * 
     * 自定义枚举类型  
     * 
     * 对齐方式、适应模式
     * 
     **************************************************/

    /// <summary>
    /// 对齐方式
    /// </summary>
    public enum AlignMode
    {
      /// <summary>
      /// 左上
      /// </summary>
      TopLeft,

      /// <summary>
      /// 左
      /// </summary>
      MidLeft,

      /// <summary>
      /// 左下
      /// </summary>
      BottomLeft,

      /// <summary>
      /// 上
      /// </summary>
      TopMid,

      /// <summary>
      /// 居中
      /// </summary>
      Center,

      /// <summary>
      /// 下
      /// </summary>
      BottomMid,

      /// <summary>
      /// 右上
      /// </summary>
      TopRight,

      /// <summary>
      /// 右
      /// </summary>
      MidRight,

      /// <summary>
      /// 右下
      /// </summary>
      BottomRight
    }


    /// <summary>
    /// 适应模式
    /// </summary>
    public enum FitMode
    {
      /// <summary>
      /// 适应指定宽度
      /// </summary>
      Width,

      /// <summary>
      /// 适应指定高度
      /// </summary>
      Height,

      /// <summary>
      /// 按指定宽高进行自适应,即约束宽高比
      /// </summary>
      WidthHeight,

      /// <summary>
      /// 适应指定百分率
      /// </summary>
      Percent,

      /// <summary>
      /// 不适应,即采用用户指定宽高
      /// </summary>
      None
    }


    /************************************************************
     * 
     * 拉伸图像、定位对象、颜色转换
     * 
     ************************************************************/

    /// <summary>
    /// 按照指定适应模式计算图像目标尺寸
    /// </summary>
    /// <param name="bgSize">背景尺寸</param>
    /// <param name="fgSize">前景尺寸</param>
    /// <param name="percent">如果指定了百分率适应模式,则此参数有效</param>
    /// <param name="fit">适应模式</param>
    /// <returns></returns>
    public Size ScaleToFit(Size bgSize,Size fgSize, double percent, FitMode fit)
    {
      Size dstSize = fgSize;

      switch (fit)
      {
        case FitMode.Width:
          dstSize.Height = fgSize.Width * bgSize.Height / bgSize.Width;
          break;

        case FitMode.Height:
          dstSize.Width = fgSize.Height * bgSize.Width / bgSize.Height;
          break;

        case FitMode.Percent:
          dstSize.Width = Convert.ToInt32(bgSize.Width * percent);
          dstSize.Height = Convert.ToInt32(bgSize.Height * percent);
          break;

        case FitMode.WidthHeight:
          if ((fgSize.Width * bgSize.Height) < (bgSize.Width * fgSize.Height))   // 等同于 ( (fgSize.Width/fgSize.Height) < (bgSize.Width/bgSize.Height) )
          {
            dstSize.Height = fgSize.Width * bgSize.Height / bgSize.Width;
          }
          else
          {
            dstSize.Width = fgSize.Height * bgSize.Width / bgSize.Height;
          }
          break;

        default: // FitMode.None
          break;
      }

      return dstSize;
    } // end of ScaleToFit


    /// <summary>
    /// 根据用户指定的对齐模式,将前景图像定位到背景图像上
    /// </summary>
    /// <param name="W">背景图像宽度</param>
    /// <param name="H">背景图像高度</param>
    /// <param name="w">前景图像宽度</param>
    /// <param name="h">前景图像高度</param>
    /// <param name="align">对齐模式</param>
    /// <returns></returns>
    public Point Locate(int W, int H, int w, int h, AlignMode align)
    {
      int x = 0;
      int y = 0;

      switch (align)
      {
        case AlignMode.TopLeft:
          x = 0;
          y = 0;
          break;

        case AlignMode.MidLeft:
          x = 0;
          y = (H - h) / 2;
          break;

        case AlignMode.BottomLeft:
          x = 0;
          y = H - h;
          break;

        case AlignMode.TopMid:
          x = (W - w) / 2;
          y = 0;
          break;

        case AlignMode.Center:
          x = (W - w) / 2;
          y = (H - h) / 2;
          break;

        case AlignMode.BottomMid:
          x = (W - w) / 2;
          y = H - h;
          break;

        case AlignMode.TopRight:
          x = W - w;
          y = 0;
          break;

        case AlignMode.MidRight:
          x = W - w;
          y = (H - h) / 2;
          break;

        case AlignMode.BottomRight:
          x = W - w;
          y = H - h;
          break;
      } // align

      return new Point(x, y);
    } // end of Locate


    /// <summary>
    /// 将十六进制颜色字符串转换成标准颜色结构体
    /// </summary>
    /// <param name="color">十六进制颜色字符串,如 "#FF0000", "#FFFF0000"</param>
    /// <returns></returns>
    public static System.Drawing.Color HexString2Color(string color)
    {
      color = color.ToLower();

      Color returnColor = new Color();

      Regex regexColor = new Regex(@"^#([0-9a-fA-F]{6})|([0-9a-fA-F]{8})$");
      if (regexColor.IsMatch(color))
      {
        int A, R, G, B;
        if (color.Length == 7)
        {
          R = Convert.ToInt32(color.Substring(1, 2), 16);
          G = Convert.ToInt32(color.Substring(3, 2), 16);
          B = Convert.ToInt32(color.Substring(5, 2), 16);
          returnColor = Color.FromArgb(R, G, B);
        }
        else
        {
          A = Convert.ToInt32(color.Substring(1, 2), 16);
          R = Convert.ToInt32(color.Substring(3, 2), 16);
          G = Convert.ToInt32(color.Substring(5, 2), 16);
          B = Convert.ToInt32(color.Substring(7, 2), 16);
          returnColor = Color.FromArgb(A, R, G, B);
        }
      }

      return returnColor;
    } // end of HexString2Color


    /// <summary>
    /// 将标准颜色结构体转换成十六进制颜色字符串
    /// </summary>
    /// <param name="color">标准颜色结构体</param>
    /// <returns></returns>
    public static string Color2HexString(Color color)
    {
      string a = "0" + Convert.ToString(color.A, 16);
      string r = "0" + Convert.ToString(color.R, 16);
      string g = "0" + Convert.ToString(color.G, 16);
      string b = "0" + Convert.ToString(color.B, 16);

      a = a.Substring(a.Length - 2).ToUpper();
      r = r.Substring(r.Length - 2).ToUpper();
      g = g.Substring(g.Length - 2).ToUpper();
      b = b.Substring(b.Length - 2).ToUpper();

      return a + r + g + b;
    } // end of Color2HexString


    /// <summary>
    /// 根据折线段的端点集建立256级亮度映射表
    /// </summary>
    /// <param name="Points">折线段端点集</param>
    /// <returns></returns>
    public byte[] GetMap(Point[] Points)
    {
      byte[] Map = new byte[256];
      for (int i = 0; i < 256; i++)
      {
        Map[i] = (byte)i;
      } // i

      int count = Points.Length;
      // 亮度曲线至少有两点
      if (count < 2)
        return Map;

      for (int i = 0; i < count - 1; i++)
      {
        Point point = Points[i];
        Point next = Points[i + 1];

        if (point.X == next.X)
        {
          Map[point.X] = (byte)next.Y;
          continue;
        }

        // 斜率: k = ( y2 - y1 ) / ( x2 - x1 );
        // y = k * x - k * x1 + y1;
        double k = (double)(next.Y - point.Y) / (double)(next.X - point.X);
        double c = point.Y - k * point.X;
        for (int x = point.X; x <= next.X; x++)
        {
          int y = (int)(k * x + c);
          Map[x] = (byte)y;
        } // x
      } // i

      return Map;
    } // end of GetMap


    /// <summary>
    /// 根据指定的首点和尾点返回由这两点所确定直线中的一系列点集
    /// </summary>
    /// <param name="start">首点</param>
    /// <param name="end">尾点</param>
    /// <returns></returns>
    public static Point[] GetLinePoints(Point start, Point end)
    {
      Point[] coords = null;

      int x1 = start.X;
      int y1 = start.Y;

      int x2 = end.X;
      int y2 = end.Y;

      int dx = x2 - x1;
      int dy = y2 - y1;

      int dxAbs = Math.Abs(dx);
      int dyAbs = Math.Abs(dy);

      int px = x1;
      int py = y1;

      int sdx = Math.Sign(dx);
      int sdy = Math.Sign(dy);

      int x = 0;
      int y = 0;

      if (dxAbs == dyAbs)
      {
        coords = new Point[dxAbs + 1];

        for (int i = 0; i <= dxAbs; i++)
        {
          coords[i] = new Point(px, py);
          px += sdx;
          py += sdy;
        }
      }

      if (dxAbs > dyAbs)
      {
        coords = new Point[dxAbs + 1];

        for (int i = 0; i <= dxAbs; i++)
        {
          y += dyAbs;

          if (y >= dxAbs)
          {
            y -= dxAbs;
            py += sdy;
          }

          coords[i] = new Point(px, py);
          px += sdx;
        } // i
      }

      if (dxAbs < dyAbs)
      {
        coords = new Point[dyAbs + 1];

        for (int i = 0; i <= dyAbs; i++)
        {
          x += dxAbs;

          if (x >= dyAbs)
          {
            x -= dyAbs;
            px += sdx;
          }

          coords[i] = new Point(px, py);
          py += sdy;
        } // i
      }

      return coords;
    } // end of GetLinePoints


    /// <summary>
    /// 根据两个点建立起一个基于它们的矩形
    /// </summary>
    /// <param name="a">矩形的一个顶点</param>
    /// <param name="b">矩形的另一个顶点</param>
    /// <returns></returns>
    public static Rectangle PointsToRectangle(Point a, Point b)
    {
      int x = Math.Min(a.X, b.X);
      int y = Math.Min(a.Y, b.Y);
      int width = Math.Abs(a.X - b.X) + 1;
      int height = Math.Abs(a.Y - b.Y) + 1;

      return new Rectangle(x, y, width, height);
    }


    /// <summary>
    /// 判断一个点是否在矩形内
    /// </summary>
    /// <param name="p">点</param>
    /// <param name="r">矩形</param>
    /// <returns></returns>
    public static bool IsPointInRectangle(Point p, Rectangle r)
    {
      if ((p.X < r.X) || (p.Y < r.Y) || (p.X >= r.Right) || (p.Y >= r.Bottom))
      {
        return false;
      }
      else
      {
        return true;
      }
    }


    /// <summary>
    /// 判断一个点是否在矩形内,如果不在,则将其置到矩形内
    /// </summary>
    /// <param name="point">点</param>
    /// <param name="rect">矩形</param>
    /// <returns></returns>
    public static Point PointInRectangle(Point point, Rectangle rect)
    {
      if (point.X < 0) point.X = 0;
      if (point.Y < 0) point.Y = 0;
      if (point.X >= rect.Width) point.X = rect.Width - 1;
      if (point.Y >= rect.Height) point.Y = rect.Height - 1;

      return point;
    }


    /// <summary>
    /// 根据指定的颜色容差来判定两种颜色是否相同
    /// </summary>
    /// <param name="destination">目标颜色</param>
    /// <param name="standard">标准颜色</param>
    /// <param name="tolerance">容差</param>
    /// <returns></returns>
    public static bool CheckColor(Color destination, Color standard, int tolerance)
    {
      int ds = 0;

      int red = destination.R - standard.R;
      ds += red * red;

      int green = destination.G - standard.G;
      ds += green * green;

      int blue = destination.B - standard.B;
      ds += blue * blue;

      return (ds < tolerance * tolerance);
    }


    /// <summary>
    /// 根据指定的四个点进行重组,使得这四个点朝一个方向
    /// </summary>
    /// <param name="a">点 A 坐标</param>
    /// <param name="b">点 B 坐标</param>
    /// <param name="c">点 C 坐标</param>
    /// <param name="d">点 D 坐标</param>
    /// <returns></returns>
    public static PointF[] MakePolygon(PointF a, PointF b, PointF c, PointF d)
    {
      PointF dirA = new PointF(a.X - b.X, a.Y - b.Y);
      PointF dirB = new PointF(c.X - d.X, c.Y - d.Y);

      if (dirA.X * dirB.X + dirA.Y * dirB.Y > 0)
      {
        return new PointF[] { a, b, d, c };
      }
      else
      {
        return new PointF[] { a, b, c, d };
      }
    }


  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -