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

📄 effect.common.cs

📁 一个C#开发的类似PHOTOSHOP的软件,用到了很多图形算法.
💻 CS
📖 第 1 页 / 共 2 页
字号:
              if (pixel > 255) pixel = 255;

              dst[i] = (byte)pixel;
            } // i

            src += BPP;
            dst += BPP;
          } // x
          src += offset;
          dst += offset;
        } // y
      }

      b.UnlockBits(srcData);
      dstImage.UnlockBits(dstData);

      b.Dispose();

      return dstImage;
    } // end of Sharpen


    /// <summary>
    /// 对图像进行钝化蒙板处理
    /// </summary>
    /// <param name="b">位图流</param>
    /// <param name="degree">钝化度[1, 100]</param>
    /// <returns></returns>
    public Bitmap UnsharpMask(Bitmap b, int degree)
    {
      if (degree < 1) degree = 1;
      if (degree > 100) degree = 100;

      int width = b.Width;
      int height = b.Height;

      Bitmap dstImage = (Bitmap)b.Clone();
      for (int i = 0; i < degree; i++)
      {
        // 进行高斯模糊处理
        dstImage = GaussBlur(dstImage);
      } // i

      BitmapData srcData = b.LockBits(new Rectangle(0, 0, width, height),
        ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
      BitmapData dstData = dstImage.LockBits(new Rectangle(0, 0, width, height),
        ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);

      unsafe
      {
        byte* src = (byte*)srcData.Scan0;
        byte* dst = (byte*)dstData.Scan0;
        int offset = srcData.Stride - width * BPP;

        int pixel = 0;

        for (int y = 0; y < height; y++)
        {
          for (int x = 0; x < width; x++)
          {
            // 处理 B, G, R 三分量,不考虑 A 分量
            for (int i = 0; i < 3; i++)
            {
              pixel = src[i] * 2 - dst[i];

              if (pixel < 0) pixel = 0;
              if (pixel > 255) pixel = 255;

              dst[i] = (byte)pixel;
            } // i

            src += BPP;
            dst += BPP;
          } // x
          src += offset;
          dst += offset;
        } // y
      }

      b.UnlockBits(srcData);
      dstImage.UnlockBits(dstData);

      b.Dispose();

      return dstImage;
    } // end of UnsharpMask


    /// <summary>
    /// 对图像进行浮雕模板处理
    /// </summary>
    /// <param name="b">位图流</param>
    /// <returns></returns>
    public Bitmap Emboss(Bitmap b)
    {
      // -1 0 -1
      //  0 4  0
      // -1 0 -1 / 1 + 127
      Matrix3x3 m = new Matrix3x3();
      m.Init(-1);
      m.TopMid = m.MidLeft = m.MidRight = m.BottomMid = 0;
      m.Center = 4;
      m.Offset = 127;

      return m.Convolute(b);
    } // end of Emboss


    /// <summary>
    /// 对图像进行八方向浮雕处理
    /// </summary>
    /// <param name="b">位图流</param>
    /// <param name="direction">雕刻方向</param>
    /// <returns></returns>
    public Bitmap Emboss(Bitmap b, Direction direction)
    {
      int width = b.Width;
      int height = b.Height;

      Bitmap dstImage = (Bitmap)b.Clone();

      BitmapData srcData = b.LockBits(new Rectangle(0, 0, width, height),
        ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
      BitmapData dstData = dstImage.LockBits(new Rectangle(0, 0, width, height),
        ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);

      // 图像实际处理区域
      // 注意:图像最外围一圈不处理
      int rectTop = 1;
      int rectBottom = height - 1;
      int rectLeft = 1;
      int rectRight = width - 1;

      unsafe
      {
        byte* src = (byte*)srcData.Scan0;
        byte* dst = (byte*)dstData.Scan0;

        int stride = srcData.Stride;
        int offset = stride - width * BPP;

        int pixel = 0;

        // 移向第一行
        src += stride;
        dst += stride;

        byte* reference = src;

        // 方向选择
        switch (direction)
        {
          case Direction.N:
            reference -= stride;
            break;

          case Direction.NE:
            reference -= stride;
            reference += BPP;
            break;

          case Direction.E:
            reference += BPP;
            break;

          case Direction.SE:
            reference += stride;
            reference += BPP;
            break;

          case Direction.S:
            reference += stride;
            break;

          case Direction.SW:
            reference += stride;
            reference -= BPP;
            break;

          case Direction.W:
            reference -= BPP;
            break;

          case Direction.NW:
            reference -= stride;
            reference -= BPP;
            break;
        } // switch

        for (int y = rectTop; y < rectBottom; y++)
        {
          // 移向每行第一列
          src += BPP;
          reference += BPP;
          dst += BPP;

          for (int x = rectLeft; x < rectRight; x++)
          {
            // 当前点与周围八点中用户选定方向处的像素差值
            for (int i = 0; i < 3; i++)
            {
              pixel = src[i] - reference[i] + 128;
              if (pixel < 0) pixel = -pixel;
              if (pixel < 64) pixel = 64;
              if (pixel > 255) pixel = 255;

              dst[i] = (byte)pixel;
            } // i
            dst[3] = src[3];

            // 向后移一像素
            src += BPP;
            reference += BPP;
            dst += BPP;
          } // x

          // 移向下一行
          // 这里得注意要多移 1 列,因最右边不必处理
          src += (offset + BPP);
          reference += (offset + BPP);
          dst += (offset + BPP);
        } // y
      }

      b.UnlockBits(srcData);
      dstImage.UnlockBits(dstData);

      b.Dispose();

      return dstImage;
    } // end of Emboss


    /// <summary>
    /// 对图像进行彩色浮雕处理
    /// </summary>
    /// <param name="b">位图流</param>
    /// <param name="angle">角度[0, 360]</param>
    /// <returns></returns>
    public Bitmap Relief(Bitmap b, int angle)
    {
      // 角度转弧度
      double radian = (double)angle * Math.PI / 180.0;

      // 每一权的弧度间隔
      double pi4 = Math.PI / 4.0;

      // 对图像进行卷积变换
      Matrix3x3 m = new Matrix3x3();

      m.TopLeft = Convert.ToInt32(Math.Cos(radian + pi4) * 256);
      m.TopMid = Convert.ToInt32(Math.Cos(radian + 2.0 * pi4) * 256);
      m.TopRight = Convert.ToInt32(Math.Cos(radian + 3.0 * pi4) * 256);

      m.MidLeft = Convert.ToInt32(Math.Cos(radian) * 256);
      m.Center = 256;
      m.MidRight = Convert.ToInt32(Math.Cos(radian + 4.0 * pi4) * 256);

      m.BottomLeft = Convert.ToInt32(Math.Cos(radian - pi4) * 256);
      m.BottomMid = Convert.ToInt32(Math.Cos(radian - 2.0 * pi4) * 256);
      m.BottomRight = Convert.ToInt32(Math.Cos(radian - 3.0 * pi4) * 256);

      m.Scale = 256;

      return m.Convolute(b);
    } // end of Relief


    /// <summary>
    /// 对图像进行灰度浮雕处理
    /// </summary>
    /// <param name="b">位图流</param>
    /// <param name="angle">角度[0, 360]</param>
    /// <returns></returns>
    public Bitmap Emboss(Bitmap b, int angle)
    {
      // 角度转弧度
      double radian = (double)angle * Math.PI / 180.0;

      // 每一权的弧度间隔
      double pi4 = Math.PI / 4.0;

      // 对图像进行卷积变换
      Matrix3x3 m = new Matrix3x3();

      m.TopLeft = Convert.ToInt32(Math.Cos(radian + pi4) * 256);
      m.TopMid = Convert.ToInt32(Math.Cos(radian + 2.0 * pi4) * 256);
      m.TopRight = Convert.ToInt32(Math.Cos(radian + 3.0 * pi4) * 256);

      m.MidLeft = Convert.ToInt32(Math.Cos(radian) * 256);
      m.Center = 0;
      m.MidRight = Convert.ToInt32(Math.Cos(radian + 4.0 * pi4) * 256);

      m.BottomLeft = Convert.ToInt32(Math.Cos(radian - pi4) * 256);
      m.BottomMid = Convert.ToInt32(Math.Cos(radian - 2.0 * pi4) * 256);
      m.BottomRight = Convert.ToInt32(Math.Cos(radian - 3.0 * pi4) * 256);

      m.Scale = 256;
      m.Offset = 128;

      b = m.Convolute(b);

      // 对图像进行灰度变换
      GrayProcessing gp = new GrayProcessing();
      b = gp.Gray(b, GrayProcessing.GrayMethod.WeightAveraging);

      return b;
    } // end of Emboss


    /// <summary>
    /// 新增杂点
    /// </summary>
    /// <param name="b">位图</param>
    /// <param name="degree">杂点幅度[0, 255]</param>
    /// <returns></returns>
    public Bitmap AddNoise(Bitmap b, int degree)
    {
      if (degree < 0) degree = 0;
      if (degree > 255) degree = 255;

      int width = b.Width;
      int height = b.Height;

      BitmapData data = b.LockBits(new Rectangle(0, 0, width, height),
        ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);

      unsafe
      {
        byte* p = (byte*)data.Scan0;
        int offset = data.Stride - width * BPP;

        int R, G, B, noise;
        Random myRand = new Random();

        for (int y = 0; y < height; y++)
        {
          for (int x = 0; x < width; x++)
          {
            noise = myRand.Next(-degree, degree);
            R = p[2] + noise;
            G = p[1] + noise;
            B = p[0] + noise;

            if (R < 0) R = 0;
            if (R > 255) R = 255;

            if (G < 0) G = 0;
            if (G > 255) G = 255;

            if (B < 0) B = 0;
            if (B > 255) B = 255;

            p[2] = (byte)R;
            p[1] = (byte)G;
            p[0] = (byte)B;

            p += BPP;
          }
          p += offset;
        }
      }
      b.UnlockBits(data);

      return b;
    } // end of AddNoise


    /// <summary>
    /// 撒雪花,椒盐噪声
    /// </summary>
    /// <param name="b">位图流</param>
    /// <param name="degree">抛撒概率[0, 100]</param>
    /// <returns></returns>
    public Bitmap Sprinkle(Bitmap b, int degree)
    {
      if (degree < 0) degree = 0;
      if (degree > 100) degree = 100;

      int width = b.Width;
      int height = b.Height;

      BitmapData data = b.LockBits(new Rectangle(0, 0, width, height),
        ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);

      unsafe
      {
        byte* p = (byte*)data.Scan0;
        int offset = data.Stride - width * BPP;

        Random myRand = new Random();

        for (int y = 0; y < height; y++)
        {
          for (int x = 0; x < width; x++)
          {
            if (myRand.Next(0, 100) < degree)
            {
              p[2] = (byte)myRand.Next(0, 255);
              p[1] = (byte)myRand.Next(0, 255);
              p[0] = (byte)myRand.Next(0, 255);
            }

            p += BPP;
          } // x
          p += offset;
        } // y
      }

      b.UnlockBits(data);

      return b;
    } // end of Sprinkle


  } // end of class Effect


}

⌨️ 快捷键说明

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