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

📄 algebra.cs

📁 一个C#开发的类似PHOTOSHOP的软件,用到了很多图形算法.
💻 CS
📖 第 1 页 / 共 2 页
字号:
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;

namespace PhotoSprite.ImageProcessing
{
  /// <summary>
  /// 图像代数运算类
  /// </summary>
  public class Algebra : ImageInfo
  {
    /// <summary>
    /// 代数运算方法
    /// </summary>
    public enum AlgebraMethod
    {
      /// <summary>
      /// 加法运算,结果取两数之和
      /// </summary>
      Add,

      /// <summary>
      /// 减法运算,结果取两数之差
      /// </summary>
      Subtract,

      /// <summary>
      /// 乘法运算,结果取两数之积
      /// </summary>
      Multiply,

      /// <summary>
      /// 除法运算,结果取两数之商
      /// </summary>
      Divide,

      /// <summary>
      /// 平均运算,结果取两数之平均值
      /// </summary>
      Average,

      /// <summary>
      /// 求异运算,找出两幅图像中的不同部分
      /// </summary>
      Differ,

      /// <summary>
      /// Max 运算,结果取两数之最大值
      /// </summary>
      Maximize,

      /// <summary>
      /// Min 运算,结果取两数之最小值
      /// </summary>
      Minimum
    }

    /// <summary>
    /// 获取或设置背景区域
    /// </summary>
    public Region BackgroundRegion
    {
      get
      {
        return bgRegion;
      }
      set
      {
        bgRegion = value;
      }
    }
    private Region bgRegion = new Region();

    /// <summary>
    /// 获取或设置前景区域
    /// </summary>
    public Region ForegroundRegion
    {
      get
      {
        return fgRegion;
      }
      set
      {
        fgRegion = value;
      }
    }
    private Region fgRegion = new Region();

    /// <summary>
    /// 图像代数运算
    /// </summary>
    /// <param name="bgImage">背景</param>
    /// <param name="fgImage">前景</param>
    /// <param name="algebraMethod">代数运算方法</param>
    /// <returns></returns>
    public Bitmap AlgebraOperate(Bitmap bgImage, Bitmap fgImage, AlgebraMethod algebraMethod)
    {
      // 计算有效区域
      Region validRegion = bgRegion;
      validRegion.Intersect(fgRegion);

      RegionClip rc = new RegionClip(validRegion);
      Bitmap background = rc.Hold((Bitmap)bgImage.Clone());

      Bitmap dstImage = rc.Remove((Bitmap)bgImage.Clone());
      Graphics g = System.Drawing.Graphics.FromImage(dstImage);

      RectangleF validRect = validRegion.GetBounds(g);
      RectangleF fgRect = fgRegion.GetBounds(g);

      validRegion.Translate(-fgRect.X, -fgRect.Y);
      Bitmap foreground = rc.Hold((Bitmap)fgImage.Clone());
      validRegion.Translate(fgRect.X, fgRect.Y);

      Bitmap validImage = null;
      switch (algebraMethod)
      {
        case AlgebraMethod.Add:
          validImage = Add(background, foreground);
          break;

        case AlgebraMethod.Subtract:
          validImage = Subtract(background, foreground);
          break;

        case AlgebraMethod.Multiply:
          validImage = Multiply(background, foreground);
          break;

        case AlgebraMethod.Divide:
          validImage = Divide(background, foreground);
          break;

        case AlgebraMethod.Average:
          validImage = Average(background, foreground);
          break;

        case AlgebraMethod.Differ:
          validImage = Differ(background, foreground);
          break;

        case AlgebraMethod.Maximize:
          validImage = Maximize(background, foreground);
          break;

        case AlgebraMethod.Minimum:
          validImage = Minimum(background, foreground);
          break;
      }

      g.DrawImage(validImage, validRect,
        new Rectangle(0, 0, (int)validRect.Width, (int)validRect.Height), GraphicsUnit.Pixel);

      bgImage.Dispose();
      fgImage.Dispose();

      return dstImage;
    } // end of AlgebraOperate


    /// <summary>
    /// 图像加法运算
    /// </summary>
    /// <param name="bgImage">背景</param>
    /// <param name="fgImage">前景</param>
    /// <returns></returns>
    private Bitmap Add(Bitmap bgImage, Bitmap fgImage)
    {
      int width = bgImage.Width;
      int height = bgImage.Height;

      BitmapData bgData = bgImage.LockBits(new Rectangle(0, 0, width, height),
        ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
      BitmapData fgData = fgImage.LockBits(new Rectangle(0, 0, width, height),
        ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

      unsafe
      {
        byte* bg = (byte*)bgData.Scan0;
        byte* fg = (byte*)fgData.Scan0;

        int offset = bgData.Stride - width * BPP;

        int pixel = 0;

        for (int y = 0; y < height; y++)
        {
          for (int x = 0; x < width; x++)
          {
            for (int i = 0; i < 3; i++)
            {
              pixel = bg[i] + fg[i];
              if (pixel > 255) pixel = 255;

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

            bg += BPP;
            fg += BPP;
          } // x

          bg += offset;
          fg += offset;
        } // y
      }

      bgImage.UnlockBits(bgData);
      fgImage.UnlockBits(fgData);

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

      bgImage.Dispose();
      fgImage.Dispose();

      return dstImage;
    } // end of Add


    /// <summary>
    /// 图像减法运算
    /// </summary>
    /// <param name="bgImage">背景</param>
    /// <param name="fgImage">前景</param>
    /// <returns></returns>
    private Bitmap Subtract(Bitmap bgImage, Bitmap fgImage)
    {
      int width = bgImage.Width;
      int height = bgImage.Height;

      BitmapData bgData = bgImage.LockBits(new Rectangle(0, 0, width, height),
        ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
      BitmapData fgData = fgImage.LockBits(new Rectangle(0, 0, width, height),
        ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

      unsafe
      {
        byte* bg = (byte*)bgData.Scan0;
        byte* fg = (byte*)fgData.Scan0;

        int offset = bgData.Stride - width * BPP;

        int pixel = 0;

        for (int y = 0; y < height; y++)
        {
          for (int x = 0; x < width; x++)
          {
            for (int i = 0; i < 3; i++)
            {
              pixel = bg[i] - fg[i];
              if (pixel < 0) pixel = -pixel;

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

            bg += BPP;
            fg += BPP;
          } // x

          bg += offset;
          fg += offset;
        } // y
      }

      bgImage.UnlockBits(bgData);
      fgImage.UnlockBits(fgData);

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

      bgImage.Dispose();
      fgImage.Dispose();

      return dstImage;
    } // end of Subtract


    /// <summary>
    /// 图像乘法运算
    /// </summary>
    /// <param name="bgImage">背景</param>
    /// <param name="fgImage">前景</param>
    /// <returns></returns>
    private Bitmap Multiply(Bitmap bgImage, Bitmap fgImage)
    {
      int width = bgImage.Width;
      int height = bgImage.Height;

      BitmapData bgData = bgImage.LockBits(new Rectangle(0, 0, width, height),
        ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
      BitmapData fgData = fgImage.LockBits(new Rectangle(0, 0, width, height),
        ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

      unsafe
      {
        byte* bg = (byte*)bgData.Scan0;
        byte* fg = (byte*)fgData.Scan0;

        int offset = bgData.Stride - width * BPP;

        int pixel = 0;

        for (int y = 0; y < height; y++)
        {
          for (int x = 0; x < width; x++)
          {
            for (int i = 0; i < 3; i++)

⌨️ 快捷键说明

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