图像旋转后显示在背景中
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
与图像关联,所以绘图会改变图像。
因此,您需要第二张图片。 创建 一个空的(或完全相同的副本)并不那么慢..
这样想:当您同时更改它们时,旧像素从何而来?所以你需要有两个缓冲区。 (但是,是的,在内部,已经有第二个缓冲区,否则结果会更奇怪。但是你无法控制它的使用..)
如果您真的觉得有必要避免使用第二张图片,您可以创建一个 GraphicsPath
或 Polygon
来覆盖 除了 旋转图像之外的所有内容,并且用你的背景颜色填充它..
但是由于旋转图像需要 更多 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+ 不会绘制完全透明的画笔。相反,您需要
- 将
CompositingMode
从默认值 SourceOver
设置为 SourceCopy
;
- 填充一种非常明显的颜色,不是你的图像,可能
Fuchsia
- 使用
MakeTransparent
.
graphics.CompositingMode = CompositingMode.SourceCopy;
..
graphics.FillPath(Brushes.Fuchsia, gp);
((Bitmap)img).MakeTransparent(Color.Fuchsia);
请注意,并非所有应用程序都能很好地显示透明度。Photoshop 当然可以..:[=22=]
我写了一个旋转图像的函数,以使其快速(这对于旋转数百张照片非常重要)我没有在每次旋转图像时都制作新的位图。但是,这导致旧照片出现在背景中,我如何在不创建新位图的情况下解决这个问题,这会减慢一切!
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
与图像关联,所以绘图会改变图像。
因此,您需要第二张图片。 创建 一个空的(或完全相同的副本)并不那么慢..
这样想:当您同时更改它们时,旧像素从何而来?所以你需要有两个缓冲区。 (但是,是的,在内部,已经有第二个缓冲区,否则结果会更奇怪。但是你无法控制它的使用..)
如果您真的觉得有必要避免使用第二张图片,您可以创建一个 GraphicsPath
或 Polygon
来覆盖 除了 旋转图像之外的所有内容,并且用你的背景颜色填充它..
但是由于旋转图像需要 更多 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+ 不会绘制完全透明的画笔。相反,您需要
- 将
CompositingMode
从默认值SourceOver
设置为SourceCopy
; - 填充一种非常明显的颜色,不是你的图像,可能
Fuchsia
- 使用
MakeTransparent
.
graphics.CompositingMode = CompositingMode.SourceCopy;
..
graphics.FillPath(Brushes.Fuchsia, gp);
((Bitmap)img).MakeTransparent(Color.Fuchsia);
请注意,并非所有应用程序都能很好地显示透明度。Photoshop 当然可以..:[=22=]