您当前的位置: 首页 >  c#

暂无认证

  • 10浏览

    0关注

    94616博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

使用GDI和未经检查的代码在C#中反射图像

发布时间:2022-09-08 20:00:00 ,浏览量:10

目录

代码

如何使用代码

样本结果。

代码

该代码使用不安全代码来加速不透明渐变的创建,因此必须在启用不安全标志的情况下编译代码。

代码大部分是不言自明的。

using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;

namespace BitmapTools
{
  public static class BitmapExtensions
  {
    public struct Pixel
    {
      public byte B;
      public byte G;
      public byte R;
      public byte A;
    }

    ////// Creates a bitmap with the original (bm) image on top and under that
    /// a reflected image. 
    //////original image///Percentage of height of the original image 
    /// that the reflection must be.///Angle that the reflection must shear. 
    /// Positive to the left.///If true then the reflection get a little blur.///public static Bitmap ReflectImage(Bitmap bm, float verticalCompress, 
                                      int offsetAngle, bool colorBlur = true)
    {
      // calculating the size of the resulting bitmap and the reflected image.
      int reflectionHeight = (int)(bm.Height - (bm.Height * verticalCompress / 100));
      int newwidth = bm.Width;
      int newheight = bm.Height + reflectionHeight;
      int offset;

      offset = (int)(Math.Sin(offsetAngle * Math.PI / 180) * reflectionHeight);
      newwidth = bm.Width + Math.Abs(offset);

      Bitmap resultBitmap = new Bitmap(newwidth, newheight, PixelFormat.Format32bppArgb);
      resultBitmap.SetResolution(bm.VerticalResolution, bm.HorizontalResolution);

      // create the bitmap with a positive of the original
      Bitmap reflectionSrc = 
             new Bitmap(bm.Width, reflectionHeight, PixelFormat.Format32bppArgb);
      using (Graphics g = Graphics.FromImage(reflectionSrc))
      {
        g.DrawImage(bm, new Rectangle(0, 0, bm.Width, reflectionHeight), 
                    0, 0, bm.Width, bm.Height, GraphicsUnit.Pixel);
      }

      // now flip the image to get a mirror image.
      reflectionSrc.RotateFlip(RotateFlipType.RotateNoneFlipY);

      // now fade to transparent. Can be done with managed code but too slow.
      // add conditionally add some blur.
      BitmapData bmd = reflectionSrc.LockBits(
          new Rectangle(Point.Empty, reflectionSrc.Size),
          ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);

      unsafe
      {
        unchecked
        {
          Pixel* ps = (Pixel*)bmd.Scan0.ToPointer();
          for (int y = 0; y < reflectionSrc.Height; y++)
          {
            int alpha = (int)((float)(1 - (y / (float)reflectionHeight)) * (float)0xFF);
            for (int x = 0; x < reflectionSrc.Width; x++, ps++)
            {
              ps->A = (byte)alpha;
              if (colorBlur)
              {
                ps->R = (byte)((ps->R * 3 + ps->G * 2 + ps->B * 2) / 7);
                ps->G = (byte)((ps->R * 2 + ps->G * 3 + ps->B * 2) / 7);
                ps->B = (byte)((ps->R * 2 + ps->G * 2 + ps->B * 3) / 7);
              }
            }
          }
        }
      }
      reflectionSrc.UnlockBits(bmd);

      // now create the canvas to draw the original and the flipped image with
      // the shear factor
      using (Graphics gr = Graphics.FromImage(resultBitmap))
      {
        // draw original on top of the result image
        gr.DrawImage(bm, offset <= 0 ? 0 : offset, 0, bm.Width, bm.Height);

        float shearFactor = (float)(offsetAngle * Math.PI / 180);

        if (offsetAngle != 0)
        {
          Matrix matrix = new Matrix();
          matrix.Shear(-shearFactor, 0);
          gr.Transform = matrix;
        }
        // remember shear translates coordinates like x' = x + (Sx * y) and y' = y + (Sy * x)
        // Sy = 0 in this case.

        gr.DrawImage(reflectionSrc,
          new Rectangle((offset <= 0 ? 0 : offset) + (int)(shearFactor * (float)bm.Height),
          bm.Height, newwidth, reflectionHeight),
          0, 0, newwidth, reflectionHeight,
          GraphicsUnit.Pixel);
        gr.ResetTransform();
      }
      reflectionSrc.Dispose();
      return resultBitmap;
    }
  }
}
如何使用代码

这是一个小示例:

private void Form1_Paint(object sender, PaintEventArgs e)
{
  Bitmap loadedImage = new Bitmap(@"Some Image.jpg");
  using (Bitmap bm = BitmapExtensions.ReflectImage(loadedImage, 50, 12, true))
  {
    e.Graphics.DrawImage(bm, 5, 5);
  }
}

可以将生成的图像保存为JPG的透明度,但官方JPG不支持透明度,因此最好保存为PNG。

Bitmap loadedImage = new Bitmap(@"Some Image.jpg");
using (Bitmap bm = BitmapExtensions.ReflectImage(loadedImage, 50, 12, true))
{
  bm.Save(@"Some Image.png", ImageFormat.Png);
}

https://www.codeproject.com/Tips/5329500/Reflected-Image-in-Csharp-with-GDI-and-Unchecked-C

关注
打赏
1655516835
查看更多评论
立即登录/注册

微信扫码登录

0.0925s