图像旋转后显示在背景中

Image shows in the background after rotating

我写了一个旋转图像的函数,以使其快速(这对于旋转数百张照片非常重要)我没有在每次旋转图像时都制作新的位图。但是,这导致旧照片出现在背景中,我如何在不创建新位图的情况下解决这个问题,这会减慢一切!

    public static Image RotateImage(Image img, float rotationAngle)
    {
        using (Graphics graphics = Graphics.FromImage(img))
        {
            graphics.TranslateTransform((float)img.Width / 2, (float)img.Height / 2);
            graphics.RotateTransform(rotationAngle);
            graphics.TranslateTransform(-(float)img.Width / 2, -(float)img.Height / 2);
            graphics.DrawImage(img, new Point(0, 0));
        }
        return img;
    }

你可以使用Graphics Clear()方法

如果没有额外的代码,我认为这是不可能的。

Graphics与图像关联,所以绘图会改变图像。

因此,您需要第二张图片。 创建 一个空的(或完全相同的副本)并不那么慢..

这样想:当您同时更改它们时,旧像素从何而来?所以你需要有两个缓冲区。 (但是,是的,在内部,已经有第二个缓冲区,否则结果会更奇怪。但是你无法控制它的使用..)

如果您真的觉得有必要避免使用第二张图片,您可以创建一个 GraphicsPathPolygon 来覆盖 除了 旋转图像之外的所有内容,并且用你的背景颜色填充它..

但是由于旋转图像需要 更多 space 来容纳旋转的角,您可能需要第二个 更大的 无论如何图像..

更新: 下面是一个示例,说明如何 clear/crop 旋转图像之外的区域。它使用 GraphicsPath 我首先向其添加一个巨大的然后是目标矩形。这样一个就被切掉了,只有外面的区域被填满了:

public static Image RotateImage(Image img, float rotationAngle)
{
    using (Graphics graphics = Graphics.FromImage(img))
    {
        graphics.TranslateTransform((float)img.Width / 2, (float)img.Height / 2);
        graphics.RotateTransform(rotationAngle);
        graphics.TranslateTransform(-(float)img.Width / 2, -(float)img.Height / 2);
        graphics.DrawImage(img, new Point(0, 0));

        GraphicsPath gp = new GraphicsPath();
        GraphicsUnit gu = GraphicsUnit.Pixel;
        gp.AddRectangle(graphics.ClipBounds);
        gp.AddRectangle(img.GetBounds(ref gu));
        graphics.FillPath(Brushes.White, gp);
    }
    return img;
}

请注意,您不能使用透明 画笔,因为 GDI+ 不会绘制完全透明的画笔。相反,您需要

  1. CompositingMode 从默认值 SourceOver 设置为 SourceCopy
  2. 填充一种非常明显的颜色,不是你的图像,可能 Fuchsia
  3. 使用MakeTransparent.

graphics.CompositingMode = CompositingMode.SourceCopy;
..
graphics.FillPath(Brushes.Fuchsia, gp);
((Bitmap)img).MakeTransparent(Color.Fuchsia);

请注意,并非所有应用程序都能很好地显示透明度。Photoshop 当然可以..:[=​​22=]