I wrote a function that rotated an image, to make it fast (which is really important for rotating hundreds of photos) I didn't make a new bitmap every time I rotate the image. But, this resulted the old photo to appear in the background, how could I fix that without creating a new bitmap which will slow down everything!
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;
}
I don't think this is possible without extra code.
Graphics
is associated with the image, so drawing will change the image.
So, you will need to have a 2nd image. Creating an empty one (or an exact copy) is not so slow..
Think of of it this way: Where could the old pixels come from when you are at the same time changing them? So you need to have two buffers. (But yes, internally, there is already a 2nd buffer or else the results would be even a lot weirder. But you can't control the use of it..)
If you really feel the need to avoid a 2nd image you can create a GraphicsPath
or a Polygon
that covers all but the rotated image and fill it with your background color..
But since rotating an image will need more space to accomodate the rotated corners you probably need a 2nd, larger image anyway..
Update: Here is an example of how to clear/crop the area outside the rotated imgae. It uses a GraphicsPath
to which I first add a huge and then the target rectangle. This way a hole is cut and only the outside area is filled:
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;
}
Note that you can't use a transparent brush as GDI+ will not paint full transparency. Instead you would need to
CompositingMode
from its default SourceOver
to SourceCopy
;Fuchsia
MakeTransparent
.graphics.CompositingMode = CompositingMode.SourceCopy;
..
graphics.FillPath(Brushes.Fuchsia, gp);
((Bitmap)img).MakeTransparent(Color.Fuchsia);
Note that not all applications will show transparency well.. Photoshop, of course, does..:
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments