question

divyadhayalan-4358 avatar image
0 Votes"
divyadhayalan-4358 asked Castorix31 commented

Reduce time consumption with RotateFlip method

Hi,

We are using System.Drawing.Image RotateFlip() method to rotate images and we found more time consumption while rotating an image with large size(17712, 24792). Kindly check the below code snippet and can you please suggest me how to reduce the time consumption?

 private void RotateImage_Click(object sender, RoutedEventArgs e)
 {
 System.Drawing.Image image = new System.Drawing.Bitmap(17712, 24792);
 System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(image);
 graphics.FillRectangle(System.Drawing.Brushes.White, new System.Drawing.Rectangle(0, 0, (int)(image.Width), (int)(image.Height)));
 Stopwatch sw = new Stopwatch();
 sw.Start();
 image.RotateFlip(System.Drawing.RotateFlipType.Rotate90FlipNone);
 System.Drawing.Image img = new System.Drawing.Bitmap(image, new System.Drawing.Size(image.Width, image.Height - 4));
 image = img;
 sw.Stop();
 Debug.WriteLine("Elapsed: " + sw.ElapsedMilliseconds.ToString());
 }

Regards,
Divya


dotnet-csharpwindows-wpf
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

Castorix31 avatar image
0 Votes"
Castorix31 answered Castorix31 commented

Maybe you can test with RotateTransform

I have not enough memory to test big images on my PC, a quick test with a small image (Winforms, some changes maybe needed for WPF) :

 System.Drawing.Image image = new System.Drawing.Bitmap(500, 1000);
 using (Graphics gr = Graphics.FromImage(image))
 {
      gr.FillRectangle(System.Drawing.Brushes.Red, new System.Drawing.Rectangle(0, 0, image.Width, image.Height));
 }
 // draw original image
 using (Graphics gr = Graphics.FromHwnd(IntPtr.Zero))
 {
     gr.DrawImage(image, 100, 100);
 }
    
 RotateImage(ref image, 90);
    
 // Change colors to see the 2 images
 System.Drawing.Imaging.ColorMap[] colorMap = new System.Drawing.Imaging.ColorMap[1];
 colorMap[0] = new System.Drawing.Imaging.ColorMap();
 colorMap[0].OldColor = Color.Red;
 colorMap[0].NewColor = Color.Blue;
 System.Drawing.Imaging.ImageAttributes imgAttr = new System.Drawing.Imaging.ImageAttributes();
 imgAttr.SetRemapTable(colorMap);
 // draw rotated image
 using (Graphics gr = Graphics.FromHwnd(IntPtr.Zero))
 {
     Rectangle rect = new Rectangle(100, 100, image.Width, image.Height);
     gr.DrawImage(image, rect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, imgAttr);
 }   

Function to rotate image :

 // Adapted from MS
 public void RotateImage(ref Image img, float angle)
 {
     float RotatedAngle = 0;
     Size ContentSize = img.Size;
     RectangleF necessaryRectangle = RectangleF.Empty;
    
     using (GraphicsPath path = new GraphicsPath())
     {
         path.AddRectangle(new RectangleF(0f, 0f, ContentSize.Width, ContentSize.Height));
         using (Matrix mtrx = new Matrix())
         {
             float totalAngle = angle;
             while (totalAngle >= 360)
             {
                 totalAngle -= 360;
             }
             RotatedAngle = totalAngle;
             mtrx.Rotate(RotatedAngle);
             necessaryRectangle = path.GetBounds(mtrx);
         }
     }
    
     System.Drawing.Bitmap newImg = null;
     Graphics g = null;
     try
     {
         newImg = new System.Drawing.Bitmap(Convert.ToInt32(necessaryRectangle.Width), Convert.ToInt32(necessaryRectangle.Height));
         g = Graphics.FromImage(newImg);
         g.TranslateTransform(-img.Width / 2, -img.Height / 2);
         g.RotateTransform(angle, MatrixOrder.Append);
         g.TranslateTransform(newImg.Width / 2, newImg.Height / 2, MatrixOrder.Append);
         g.InterpolationMode = InterpolationMode.HighQualityBicubic;
         g.DrawImage(img, 0, 0);
         img.Dispose();
         img = newImg;
     }
     catch
     {
         if (newImg != null)
         {
             newImg.Dispose();
         }
         throw;
     }
     finally
     {
         if (g != null)
         {
             g.Dispose();
         }
     }
 } 


· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi Castorix31,

Thank you for the suggestion, but the time consumption is not reducing with the provided suggestion instead it consume more time than the Image RotateFlip method.

Kindly provide is there any other suggestions which could reduce the time consumption while rotating an image with large size.

Regards,
Divya

0 Votes 0 ·

The fastest method to rotate is with Direct2D : Applying Transforms in Direct2D
I did some tests with P/Invoke, but I cannot load bitmaps > ~10000*10000 on my PC; the rotation is immediate (hardware accelerated), but it needs time to load the image at beginning (I have a slow HD and only 8GB RAM, often full...)

0 Votes 0 ·