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

📄 effect.extend.cs

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

            // G = |g - b - r| * 3 / 2;
            pixel = G - B - R;
            pixel = pixel * 3 / 2;
            if (pixel < 0) pixel = -pixel;
            if (pixel > 255) pixel = 255;
            p[1] = (byte)pixel;

            // B = |b - r - g| * 3 / 2;
            pixel = B - R - G;
            pixel = pixel * 3 / 2;
            if (pixel < 0) pixel = -pixel;
            if (pixel > 255) pixel = 255;
            p[0] = (byte)pixel;

            p += BPP;
          } // x

          p += offset;
        } // y
      }

      b.UnlockBits(data);

      return b;
    } // end of Ice


    /// <summary>
    /// 熔铸
    /// </summary>
    /// <param name="b">位图流</param>
    /// <returns></returns>
    public Bitmap Molten(Bitmap b)
    {
      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, pixel;

        for (int y = 0; y < height; y++)
        {
          for (int x = 0; x < width; x++)
          {
            R = p[2];
            G = p[1];
            B = p[0];

            pixel = R * 128 / (G + B + 1);
            if (pixel < 0) pixel = 0;
            if (pixel > 255) pixel = 255;
            p[2] = (byte)pixel;

            pixel = G * 128 / (B + R + 1);
            if (pixel < 0) pixel = 0;
            if (pixel > 255) pixel = 255;
            p[1] = (byte)pixel;

            pixel = B * 128 / (R + G + 1);
            if (pixel < 0) pixel = 0;
            if (pixel > 255) pixel = 255;
            p[0] = (byte)pixel;

            p += BPP;
          }  // x

          p += offset;
        } // y
      }

      b.UnlockBits(data);

      return b;
    } // end of Molten


    /// <summary>
    /// 暗调
    /// </summary>
    /// <param name="b">位图流</param>
    /// <returns></returns>
    public Bitmap Darkness(Bitmap b)
    {
      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;

        for (int y = 0; y < height; y++)
        {
          for (int x = 0; x < width; x++)
          {
            R = p[2];
            G = p[1];
            B = p[0];

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

            p += BPP;
          }  // x

          p += offset;
        } // y
      }

      b.UnlockBits(data);

      return b;
    } // end of Darkness


    /// <summary>
    /// 对调
    /// </summary>
    /// <param name="b">位图流</param>
    /// <returns></returns>
    public Bitmap Subtense(Bitmap b)
    {
      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;

        for (int y = 0; y < height; y++)
        {
          for (int x = 0; x < width; x++)
          {
            R = p[2];
            G = p[1];
            B = p[0];

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

            p += BPP;
          }  // x

          p += offset;
        } // y
      }

      b.UnlockBits(data);

      return b;
    } // end of Subtense


    /// <summary>
    /// 怪调
    /// </summary>
    /// <param name="b">位图流</param>
    /// <returns></returns>
    public Bitmap Whim(Bitmap b)
    {
      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;

        double R, G, B, pixel;

        for (int y = 0; y < height; y++)
        {
          for (int x = 0; x < width; x++)
          {
            R = p[2];
            G = p[1];
            B = p[0];

            pixel = Math.Sin(Math.Atan2(G, B)) * 255;
            p[2] = (byte)pixel;

            pixel = Math.Sin(Math.Atan2(B, R)) * 255;
            p[1] = (byte)pixel;

            pixel = Math.Sin(Math.Atan2(R, G)) * 255;
            p[0] = (byte)pixel;

            p += BPP;
          } // x

          p += offset;
        } // y
      }

      b.UnlockBits(data);

      return b;
    } // end of Whim


    /************************************************************
     * 
     * 挤压、球面、漩涡、波浪
     * 摩尔纹
     * 
     ************************************************************/


    /// <summary>
    /// 对图像进行挤压特效处理
    /// </summary>
    /// <param name="b">位图流</param>
    /// <param name="degree">挤压幅度[1, 32]</param>
    /// <returns></returns>
    public Bitmap Pinch(Bitmap b, int degree)
    {
      if (degree < 1) degree = 1;
      if (degree > 32) degree = 32;

      int width = b.Width;
      int height = b.Height;
      int midX = width / 2;
      int midY = height / 2;

      Bitmap dstImage = new Bitmap(width, height);

      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 stride = srcData.Stride;
      System.IntPtr srcScan0 = srcData.Scan0;
      System.IntPtr dstScan0 = dstData.Scan0;
      int offset = stride - width * BPP;

      unsafe
      {
        byte* src = (byte*)srcScan0;
        byte* dst = (byte*)dstScan0;

        int X, Y;
        int offsetX, offsetY;

        // 弧度、半径
        double radian, radius;

        for (int y = 0; y < height; y++)
        {
          for (int x = 0; x < width; x++)
          {
            // 当前点与图像中心点的偏移量
            offsetX = x - midX;
            offsetY = y - midY;

            // 弧度
            radian = Math.Atan2(offsetY, offsetX);

            // 半径
            radius = Math.Sqrt(offsetX * offsetX + offsetY * offsetY);
            radius = Math.Sqrt(radius) * degree;

            // 映射实际像素点
            X = (int)(radius * Math.Cos(radian)) + midX;
            Y = (int)(radius * Math.Sin(radian)) + midY;

            // 边界约束
            if (X < 0) X = 0;
            if (X >= width) X = width - 1;
            if (Y < 0) Y = 0;
            if (Y >= height) Y = height - 1;

            src = (byte*)srcScan0 + Y * stride + X * BPP;

            dst[3] = src[3]; // A
            dst[2] = src[2]; // R
            dst[1] = src[1]; // G
            dst[0] = src[0]; // B

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

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

      b.Dispose();

      return dstImage;
    } // end of Pinch


    /// <summary>
    /// 对图像进行球面特效处理
    /// </summary>
    /// <param name="b">位图流</param>
    /// <returns></returns>
    public Bitmap Spherize(Bitmap b)
    {
      int width = b.Width;
      int height = b.Height;
      int midX = width / 2;
      int midY = height / 2;
      // Max(midX, midY)
      double maxMidXY = (midX > midY ? midX : midY);

      Bitmap dstImage = new Bitmap(width, height);

      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 stride = srcData.Stride;
      System.IntPtr srcScan0 = srcData.Scan0;
      System.IntPtr dstScan0 = dstData.Scan0;
      int offset = stride - width * BPP;

      unsafe
      {
        byte* src = (byte*)srcScan0;
        byte* dst = (byte*)dstScan0;

        int X, Y;
        int offsetX, offsetY;

        // 弧度、半径
        double radian, radius;

        for (int y = 0; y < height; y++)
        {
          for (int x = 0; x < width; x++)
          {
            // 当前点与图像中心点的偏移量
            offsetX = x - midX;
            offsetY = y - midY;

            // 弧度
            radian = Math.Atan2(offsetY, offsetX);

            // 注意,这里并非实际半径
            radius = (offsetX * offsetX + offsetY * offsetY) / maxMidXY;

            // 映射实际像素点
            X = (int)(radius * Math.Cos(radian)) + midX;
            Y = (int)(radius * Math.Sin(radian)) + midY;

            // 边界约束
            if (X < 0) X = 0;
            if (X >= width) X = width - 1;
            if (Y < 0) Y = 0;
            if (Y >= height) Y = height - 1;

            src = (byte*)srcScan0 + Y * stride + X * BPP;

            dst[3] = src[3]; // A
            dst[2] = src[2]; // R
            dst[1] = src[1]; // G
            dst[0] = src[0]; // B

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

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

      b.Dispose();

      return dstImage;
    } // end of Spherize


    /// <summary>
    /// 对图像进行漩涡特效处理
    /// </summary>
    /// <param name="b">位图流</param>
    /// <param name="degree">漩涡幅度[1, 100]</param>
    /// <returns></returns>
    public Bitmap Swirl(Bitmap b, int degree)
    {
      if (degree < 1) degree = 1;
      if (degree > 100) degree = 100;
      double swirlDegree = degree / 1000.0;

      int width = b.Width;
      int height = b.Height;
      int midX = width / 2;
      int midY = height / 2;

      Bitmap dstImage = new Bitmap(width, height);

      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 stride = srcData.Stride;
      System.IntPtr srcScan0 = srcData.Scan0;
      System.IntPtr dstScan0 = dstData.Scan0;
      int offset = stride - width * BPP;

      unsafe
      {
        byte* src = (byte*)srcScan0;
        byte* dst = (byte*)dstScan0;

        int X, Y;
        int offsetX, offsetY;

        // 弧度、半径
        double radian, radius;

        for (int y = 0; y < height; y++)
        {
          for (int x = 0; x < width; x++)
          {
            // 当前点与图像中心点的偏移量
            offsetX = x - midX;
            offsetY = y - midY;

            // 弧度
            radian = Math.Atan2(offsetY, offsetX);

            // 半径,即两点间的距离
            radius = Math.Sqrt(offsetX * offsetX + offsetY * offsetY);

            // 映射实际像素点
            X = (int)(radius * Math.Cos(radian + swirlDegree * radius)) + midX;
            Y = (int)(radius * Math.Sin(radian + swirlDegree * radius)) + midY;

            // 边界约束
            if (X < 0) X = 0;
            if (X >= width) X = width - 1;
            if (Y < 0) Y = 0;
            if (Y >= height) Y = height - 1;

            src = (byte*)srcScan0 + Y * stride + X * BPP;

            dst[3] = src[3]; // A
            dst[2] = src[2]; // R
            dst[1] = src[1]; // G
            dst[0] = src[0]; // B

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

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

      b.Dispose();

      return dstImage;
    } // end of Swirl

⌨️ 快捷键说明

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