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

📄 imagetransform.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 ImageTransform : ImageInfo
  {
    /// <summary>
    /// 未知区域设置模式
    /// </summary>
    public enum AreasMode
    {
      /// <summary>
      /// 透明
      /// </summary>
      Transparent,

      /// <summary>
      /// 重复边缘像素
      /// </summary>
      RepeatEdgePixels,

      /// <summary>
      /// 四周环绕
      /// </summary>
      WrapAround
    }

    /// <summary>
    /// 修整模式
    /// </summary>
    public enum TrimMode : int
    { 
      /// <summary>
      /// 不修整任何边
      /// </summary>
      None = 0,

      /// <summary>
      /// 修整上边
      /// </summary>
      Top = 1,

      /// <summary>
      /// 修整下边
      /// </summary>
      Bottom = 2,

      /// <summary>
      /// 修整左边
      /// </summary>
      Left = 4,

      /// <summary>
      /// 修整右边
      /// </summary>
      Right = 8
    }


    /************************************************************
     * 
     * 平移、尺寸、裁剪
     * 旋转、翻转、转置、倾斜、修整
     * 
     ************************************************************/

    /// <summary>
    /// 图像平移
    /// </summary>
    /// <param name="b">位图流</param>
    /// <param name="horizontal">水平偏移量</param>
    /// <param name="vertical">垂直偏移量</param>
    /// <param name="areaMode">平移后图像留下的未知区域设置方式</param>
    /// <returns></returns>
    public Bitmap Translate(Bitmap b, int horizontal, int vertical, AreasMode areaMode)
    {
      int width = b.Width;
      int height = b.Height;

      horizontal %= width;
      vertical %= height;

      Bitmap dstImage = new Bitmap(width, height);
      System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(dstImage);

      // 图像偏移部分
      Point diagonal = new Point(horizontal, vertical);
      g.DrawImage(b, diagonal);

      switch (areaMode)
      {
        case AreasMode.WrapAround:
          if (horizontal < 0)
            diagonal.X += width;
          else
            diagonal.X -= width;
          // 水平移出部分
          g.DrawImage(b, diagonal);

          if (vertical < 0)
            diagonal.Y += height;
          else
            diagonal.Y -= height;
          // 对角移出部分
          g.DrawImage(b, diagonal);

          // 垂直移出部分
          diagonal.X = horizontal;
          g.DrawImage(b, diagonal);
          break;

        case AreasMode.RepeatEdgePixels:
          // 水平移出部分
          diagonal.X += (horizontal < 0 ? width : -width);
          g.DrawImage(b,
            new Rectangle(diagonal.X, diagonal.Y, width, height),
            new Rectangle(horizontal < 0 ? width - 1 : 0, 0, 1, height),
            GraphicsUnit.Pixel
            );

          // 对角移出部分
          diagonal.Y += (vertical < 0 ? height : -height);
          g.DrawImage(b,
            new Rectangle(diagonal.X, diagonal.Y, width, height),
            new Rectangle(horizontal < 0 ? width - 1 : 0, vertical < 0 ? height - 1 : 0, 1, 1),
            GraphicsUnit.Pixel
            );

          // 垂直移出部分
          diagonal.X = horizontal;
          g.DrawImage(b,
           new Rectangle(diagonal.X, diagonal.Y, width, height),
           new Rectangle(0, vertical < 0 ? height - 1 : 0, width, 1),
           GraphicsUnit.Pixel
           );
          break;

        case AreasMode.Transparent:
          break;
      } // switch


      g.Save();
      g.Dispose();

      b.Dispose();

      return dstImage;
    } // end of Translate


    /// <summary>
    /// 图像尺寸调节
    /// </summary>
    /// <param name="b">原始图像</param>
    /// <param name="dstWidth">目标宽度</param>
    /// <param name="dstHeight">目标高度</param>
    /// <returns></returns>
    public Bitmap Resize(Bitmap b, int dstWidth, int dstHeight)
    {
      Bitmap dstImage = new Bitmap(dstWidth, dstHeight);
      System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(dstImage);

      // 设置插值模式
      g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Bilinear;

      // 设置平滑模式
      g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

      g.DrawImage(b, 
        new System.Drawing.Rectangle(0, 0, dstImage.Width, dstImage.Height), 
        new System.Drawing.Rectangle(0, 0, b.Width, b.Height), 
        System.Drawing.GraphicsUnit.Pixel);
      g.Save();
      g.Dispose();

      return dstImage;
    } // end of Resize


    /// <summary>
    /// 按指定的裁剪路径对图像进行裁剪
    /// </summary>
    /// <param name="b">原始图像</param>
    /// <param name="region">裁剪区域</param>
    /// <returns></returns>
    public Bitmap Crop(Bitmap b, Region region)
    {
      Graphics g = System.Drawing.Graphics.FromImage(b);

      // 获取区域边界
      RectangleF validRect = region.GetBounds(g);

      int x = (int)validRect.X;
      int y = (int)validRect.Y;
      int width = (int)validRect.Width;
      int height = (int)validRect.Height;

      // 对区域进行平移
      Region validRegion = region;
      validRegion.Translate(-x, -y);

      Bitmap dstImage = new Bitmap(width, height);
      Graphics dstGraphics = System.Drawing.Graphics.FromImage(dstImage);

      // 设置剪辑区域
      dstGraphics.SetClip(validRegion, CombineMode.Replace);

      // 绘图
      dstGraphics.DrawImage(b, new Rectangle(0, 0, width, height), 
        validRect, GraphicsUnit.Pixel);

      g.Dispose();
      dstGraphics.Dispose();
      b.Dispose();

      return dstImage;
    } // end of Crop


    /// <summary>
    /// 以逆时针方向为正方向对图像进行旋转
    /// </summary>
    /// <param name="b">位图流</param>
    /// <param name="angle">旋转角度[0, 360]</param>
    /// <returns></returns>
    public Bitmap Rotate(Bitmap b, int angle)
    {
      angle = angle % 360;

      // 弧度转化
      double radian = angle * Math.PI / 180.0;
      double cos = Math.Cos(radian);
      double sin = Math.Sin(radian);

      // 原图宽高
      int w = b.Width;
      int h = b.Height;

      // 新图的宽高
      int W = (int)(Math.Max(Math.Abs(w * cos - h * sin), Math.Abs(w * cos + h * sin)));
      int H = (int)(Math.Max(Math.Abs(w * sin - h * cos), Math.Abs(w * sin + h * cos)));

      // 目标位图,即旋转后的图
      Bitmap dstImage = new Bitmap(W, H);
      System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(dstImage);
      g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Bilinear;
      g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

      // 偏移量
      Point offset = new Point((W - w) / 2, (H - h) / 2);

      // 构造图像显示区域:让图像的中心点与窗口的中心点一致
      Rectangle rect = new Rectangle(offset.X, offset.Y, w, h);
      Point center = new Point(rect.X + rect.Width / 2, rect.Y + rect.Height / 2);

      // 以图像的中心点旋转
      g.TranslateTransform(center.X, center.Y);
      g.RotateTransform(360 - angle);

      // 恢复图像在水平和垂直方向的平移
      g.TranslateTransform(-center.X, -center.Y);

      // 绘制旋转后的结果图
      g.DrawImage(b, rect);

      // 重置绘图的所有变换
      g.ResetTransform();

      g.Save();

      return dstImage;
    } // end of Rotate


    /// <summary>
    /// 对图像进行翻转变换,即镜像
    /// </summary>
    /// <param name="b">原始图像</param>
    /// <param name="isHorz">是否按水平方向进行翻转</param>
    /// <returns></returns>
    public Bitmap Flip(Bitmap b, bool isHorz)
    {
      int width = b.Width;
      int height = b.Height;

      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;

        if (isHorz)
        {
          // 水平翻转
          for (int y = 0; y < height; y++)
          {
            for (int x = 0; x < width; x++)
            {
              dst = (byte*)dstScan0 + (y * stride) + ((width - x - 1) * BPP);

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

              src += BPP;
            } // x

            src += offset;
          } // y
        }

⌨️ 快捷键说明

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