我编写了一个旋转图像的功能,以使其快速旋转(这对于旋转数百张照片非常重要),我每次旋转图像时都没有创建新的位图。但是,这导致了旧照片出现在背景中,如何解决这个问题而不创建新的位图,而这会减慢一切!
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;
}
答案 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 +不会绘制完整的透明度。相反,您将需要
CompositingMode
从默认的SourceOver
设置为SourceCopy
; Fuchsia
MakeTransparent
。graphics.CompositingMode = CompositingMode.SourceCopy;
..
graphics.FillPath(Brushes.Fuchsia, gp);
((Bitmap)img).MakeTransparent(Color.Fuchsia);
请注意,并非所有应用程序都能很好地显示透明度。.Photoshop当然可以..
答案 1 :(得分:-1)
您可以使用Graphics Clear()方法