旋转后

时间:2018-12-22 14:37:40

标签: c# image graphics bitmap rotation

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

    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;
    }

2 个答案:

答案 0 :(得分:1)

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

Graphics与图像相关联,因此绘图会更改图像。

因此,您将需要第二张图像。 创建一个空副本(或精确副本)并不是很慢。

这样想:当您同时更改旧像素时,旧像素可能来自哪里?因此,您需要两个缓冲区。 (但是,是的,在内部,已经有第二个缓冲区,否则结果甚至会变得很奇怪。但是您无法控制它的使用。)

如果您确实需要避免使用第二张图片,则可以创建一个GraphicsPath或一个Polygon来覆盖所有但不包括的图片,并用背景填充颜色。

但是由于旋转图像将需要更多空间来适应旋转的角,所以您可能仍然需要第二张更大的图像。

更新:这是如何清除/裁剪旋转的imgae外部区域的示例。它使用一个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当然可以..

enter image description here

答案 1 :(得分:-1)

您可以使用Graphics Clear()方法