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

📄 adjustment.cs

📁 一个C#开发的类似PHOTOSHOP的软件,用到了很多图形算法.
💻 CS
📖 第 1 页 / 共 2 页
字号:
        for (int y = 0; y < height; y++)
        {
          for (int x = 0; x < width; x++)
          {
            // 因为已经是灰度色,
            // 这里只取蓝色分量作为灰度进行运算
            gray = p[0];

            // 伪彩色处理
            switch (gray / 64)
            {
              case 0:
                R = 0;
                G = 4 * gray;
                B = 255;
                break;

              case 1:
                R = 0;
                G = 255;
                B = 511 - 4 * gray;
                break;

              case 2:
                R = 4 * gray - 511;
                G = 255;
                B = 0;
                break;

              case 3:
                R = 255;
                G = 1023 - 4 * gray;
                B = 0;
                break;
            }

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

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

      b.UnlockBits(data);

      return b;
    } // end of PseudoColor


    /// <summary>
    /// 按色彩表形式映射伪彩色
    /// </summary>
    /// <param name="b">灰度位图流</param>
    /// <param name="colorTable">色彩映射表</param>
    /// <returns></returns>
    public Bitmap PseudoColor(Bitmap b, Color[] colorTable)
    {
      int width = b.Width;
      int height = b.Height;

      // 颜色对照表
      int lenColorTable = colorTable.Length;
      uint[] ColorTable = new uint[lenColorTable];

      // 将颜色转换为数字
      for (int i = 0; i < lenColorTable; i++)
      {
        ColorTable[i] = (uint)((colorTable[i].A << 24) |
          (colorTable[i].R << 16) |
          (colorTable[i].G << 8) |
          (colorTable[i].B << 0));
      } // i

      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 gray = 0;
        uint color = 0;

        // 避免在下面的循环中,出现色彩表索引越界
        lenColorTable--;

        for (int y = 0; y < height; y++)
        {
          for (int x = 0; x < width; x++)
          {
            // 因为已经是灰度色,
            // 这里只取蓝色分量作为灰度进行运算
            gray = p[0];

            // 转化灰度级,并映射到色彩表
            color = ColorTable[lenColorTable * gray / 255];

            p[3] = (byte)(color >> 24); // A
            p[2] = (byte)(color >> 16); // R
            p[1] = (byte)(color >> 8);  // G
            p[0] = (byte)(color);       // B

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

      b.UnlockBits(data);

      return b;
    } // end of PseudoColor


    /************************************************************
     * 
     * 轮换通道、提取通道、过滤通道
     * 
     ************************************************************/


    /// <summary>
    /// 轮换通道
    /// </summary>
    /// <param name="b">位图流</param>
    /// <returns></returns>
    public Bitmap RotateChannel(Bitmap b)
    {
      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);

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

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

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

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

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

      b.Dispose();

      return dstImage;
    } // end of RotateChannel


    /// <summary>
    /// 通道模式
    /// </summary>
    public enum ChannelMode : int
    { 
      /// <summary>
      /// 蓝色通道
      /// </summary>
      Blue = 1,

      /// <summary>
      /// 绿色通道
      /// </summary>
      Green = 2,

      /// <summary>
      /// 红色通道
      /// </summary>
      Red = 4,

      /// <summary>
      /// Alpha 通道
      /// </summary>
      Alpha = 8,

      /// <summary>
      /// 青色 = 绿色 + 蓝色
      /// </summary>
      Cyan = 3,

      /// <summary>
      /// 品红 = 红色 + 蓝色
      /// </summary>
      Megenta = 5,

      /// <summary>
      /// 黄色 = 红色 + 绿色
      /// </summary>
      Yellow = 6,

      /// <summary>
      /// 白色 = 红色 + 绿色 + 蓝色
      /// </summary>
      White = 7
    }
    

    /// <summary>
    /// 提取通道
    /// </summary>
    /// <param name="b">位图流</param>
    /// <param name="channelMode">通道模式[A, R, G, B]</param>
    /// <returns></returns>
    public Bitmap ExtractChannel(Bitmap b, ChannelMode channelMode)
    {
      int channel = (int)Math.Log((double)channelMode,2.0);
       
      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);

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

        for (int y = 0; y < height; y++)
        {
          for (int x = 0; x < width; x++)
          {
            dst[0] = dst[1] = dst[2] = src[channel];

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

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

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

      b.Dispose();

      return dstImage;
    } // end of ExtractChannel


    /// <summary>
    /// 过滤通道
    /// </summary>
    /// <param name="b">位图流</param>
    /// <param name="channelMode">通道模式</param>
    /// <returns></returns>
    public Bitmap FilterChannel(Bitmap b, ChannelMode channelMode)
    {
      int channel = (int)channelMode;

      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;

        for (int i = 0; i < 3; i++)
        {
          if (((int)Math.Pow(2, i) & channel) > 0)
            continue;

          p = (byte*)data.Scan0;
          for (int y = 0; y < height; y++)
          {
            for (int x = 0; x < width; x++)
            {
              p[i] = 0;

              p += BPP;
            } // x

            p += offset;
          } // y
        } // i
      }

      b.UnlockBits(data);

      return b;
    } // end of FilterChannel


    /************************************************************
     * 
     * 映射
     * 
     ************************************************************/


    /// <summary>
    /// 图像色彩映射
    /// </summary>
    /// <param name="b">位图流</param>
    /// <param name="Map">映射表</param>
    /// <param name="channelMode">通道模式</param>
    /// <returns></returns>
    public Bitmap Mapping(Bitmap b, byte[] Map, ChannelMode channelMode)
    {
      int channel = (int)channelMode;

      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;

        for (int i = 0; i < 3; i++)
        {
          if (((int)Math.Pow(2, i) & channel) == 0)
            continue;

          p = (byte*)data.Scan0;
          for (int y = 0; y < height; y++)
          {
            for (int x = 0; x < width; x++)
            {
              p[i] = Map[p[i]];

              p += BPP;
            } // x

            p += offset;
          } // y
        } // i
      }

      b.UnlockBits(data);

      return b;
    } // end of Mapping


  }
}

⌨️ 快捷键说明

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