What is the fastest way to rotate an image without cropping its edges using GDI +?

There are some looooong and hungry algorithms for this, but so far I have not come up with and found something especially fast.

+3
source share
4 answers

Here's what I did (after extensive research and a useful link provided by TheCodeKing):

public Image RotateImage(Image img, float rotationAngle)
    {
        // When drawing the returned image to a form, modify your points by 
        // (-(img.Width / 2) - 1, -(img.Height / 2) - 1) to draw for actual co-ordinates.

        //create an empty Bitmap image 
        Bitmap bmp = new Bitmap((img.Width * 2), (img.Height *2));

        //turn the Bitmap into a Graphics object
        Graphics gfx = Graphics.FromImage(bmp);

        //set the point system origin to the center of our image
        gfx.TranslateTransform((float)bmp.Width / 2, (float)bmp.Height / 2);

        //now rotate the image
        gfx.RotateTransform(rotationAngle);

        //move the point system origin back to 0,0
        gfx.TranslateTransform(-(float)bmp.Width / 2, -(float)bmp.Height / 2);

        //set the InterpolationMode to HighQualityBicubic so to ensure a high
        //quality image once it is transformed to the specified size
        gfx.InterpolationMode = InterpolationMode.HighQualityBicubic;

        //draw our new image onto the graphics object with its center on the center of rotation
        gfx.DrawImage(img, new PointF((img.Width / 2), (img.Height / 2)));

        //dispose of our Graphics object
        gfx.Dispose();

        //return the image
        return bmp;
    }

Hooray!

+4
source

The fastest way is to use unsafe calls to directly manage image memory with LockBits. It sounds scary, but it's pretty straight forward. If you are looking for LockBits, you will find examples here .

Interesting bit:

BitmapData originalData = originalBitmap.LockBits(
     new Rectangle(0, 0, originalWidth, originalHeight), 
     ImageLockMode.ReadOnly, 
     PixelFormat.Format32bppRgb);

BitmapData, ( LockBits). , API Graphics.

+5
void Graphics.RotateTransform(float angle);

#. ?

GDI+. , .

0

, , , . , , . # # IRC Bloodyaugust.

   public static double NormalizeAngle(double angle)
    {
        double division = angle / (Math.PI / 2);
        double fraction = Math.Ceiling(division) - division;

        return (fraction * Math.PI / 2);
    }


    public static Tuple<Image,Size> RotateImage(Image img, double rotationAngle)
    {

        double normalizedRotationAngle = NormalizeAngle(rotationAngle);

        double widthD = img.Width, heightD = img.Height;
        double newWidthD, newHeightD;



        newWidthD = Math.Cos(normalizedRotationAngle) * widthD + Math.Sin(normalizedRotationAngle) * heightD;
        newHeightD = Math.Cos(normalizedRotationAngle) * heightD + Math.Sin(normalizedRotationAngle) * widthD;

        int newWidth, newHeight;
        newWidth = (int)Math.Ceiling(newWidthD);
        newHeight = (int)Math.Ceiling(newHeightD);

        Size offset = new Size((newWidth - img.Width) / 2,(newHeight - img.Height) / 2);

        Bitmap bmp = new Bitmap(newWidth, newHeight);
        Graphics gfx = Graphics.FromImage(bmp);
        //gfx.Clear(Color.Blue);
        gfx.TranslateTransform((float)bmp.Width / 2, (float)bmp.Height / 2);
        gfx.RotateTransform((float)(rotationAngle / Math.PI * 180));
        gfx.TranslateTransform(-(float)bmp.Width / 2, -(float)bmp.Height / 2);
        gfx.InterpolationMode = InterpolationMode.HighQualityBicubic;
        gfx.DrawImage(img, new PointF((bmp.Width / 2 - img.Width / 2), (bmp.Height / 2 - img.Height / 2)));
        gfx.Dispose();  
        return new Tuple<Image,Size>(bmp,offset);
    }
0

Source: https://habr.com/ru/post/1765743/


All Articles