locked
Image Rotation problem RRS feed

  • Question

  • User-471142486 posted
    Hi,

    I'm facing the following problem:
    I'm uploading a jpeg image to the server where it's saved in a temporary file.  Then I want to rotate it (say 90°) and save it again.  But all what pops up is a black image, with no content. What am I doing wrong ?  Here's the code:

                Dim origImg As Image = Image.FromFile(Server.MapPath(imageFileName))
                Dim newImg As Image = New Bitmap(1600, 1600)
                Dim gr As Graphics = Graphics.FromImage(newImg)
                Dim mx As New Drawing2D.Matrix
                mx.Rotate(90)
                gr.Transform = mx
                Dim destRect As New Rectangle(0, 0, newImg.Width, newImg.Height)
                Dim srcRect As New Rectangle(0, 0, origImg.Width, origImg.Height)
                gr.DrawImage(origImg, destRect, srcRect, GraphicsUnit.Pixel)
                origImg.Dispose()
                gr.Dispose()
                newImg.Save(Server.MapPath(<somefilename>), ImageFormat.Jpeg)
    Bart

    Thursday, June 23, 2005 10:00 AM

All replies

  • User1152494133 posted

    Think about the rotation that's occurring, and be aware of this when you draw the image.

    When you rotate an image 90 degrees around it's (0,0) point, the entire image is out of frame after the rotation.  Why?  Think of putting a thumbtack at the upper left corner of a piece of paper on a bulletin board, and then turning it 90 degrees.  Now look where the original picture was--no part of the rotated picture occupies the same space as the original.  (This might not be technically correct in the same sense as the System.Drawing coordinate system, but hopefully it illustrates my point).

    To correct this, you need to draw the image displaced so that when it is rotated, it will be in frame.


    Consider this sample code:

      using (System.Drawing.Image origImg = System.Drawing.Image.FromFile(@"c:\test.jpg"))
       {
        using (System.Drawing.Bitmap newImg = new System.Drawing.Bitmap(origImg.Height, origImg.Width))
        {
         using (System.Drawing.Graphics gr = System.Drawing.Graphics.FromImage(newImg))
         {
          System.Drawing.Drawing2D.Matrix mx=new System.Drawing.Drawing2D.Matrix();
          mx.Rotate(90);
          gr.Transform=mx;
          gr.DrawImageUnscaled(origImg, 0, -1*origImg.Height);

          newImg.Save(@"c:\new.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
          
         }
        }
       }

    Here, I'm rotating 90 degrees, but when I draw the original image onto the new image's Graphics, I use the point (0, -1*origImg.Height).  After the transform, the image will be properly located within the newImg's region.

    Here's the rotation displacements:

    0 degrees = (0,0)
    90 degrees = (0, -height)
    180 degrees = (-width, -height)
    270 degrees = (-width, 0)    Note: 270 degrees is same as -90 degrees

    Thursday, June 23, 2005 3:11 PM
  • User-471142486 posted

    Jason, thanks for the quick reply.

    The rotation works fine, but the image is also scaled although we use the DrawImageUnscaled method !  The image occupies only 1/4 of the available space.  The rest is black.

    Any idea ?

    Monday, June 27, 2005 3:12 AM
  • User1152494133 posted

    I'm not clear as to what's going on.  Maybe if you can reply with some pixel dimensions, it will help me to visualize your problem.

    For instance:

    Is it that you have a 400x400 drawing that you're trying to rotate onto a 1600x1600 canvas (per your original post), and need it to scale to fill the new canvas?

    Or do you have a 1600x1600 drawing that after rotating, only occupies a 400x400 section?

    Monday, June 27, 2005 8:51 AM
  • User-471142486 posted

    The dimension actually doesn't really matter.
    Suppose I have a 1600 x 1200 picture.  After rotation it should be 1200 x 1600 pixels in case of a 90° rotation.
    What happens now is that the canvas is ok (it's a new image with the correct dimension) but the image resides in the upper right corner and is only (approx) 1/4 of the size of the canvas. The rest of the canvas is black. I tried to draw it below.

    ***********************
    *         |           *
    *         |           *
    *         |  My Image *
    *         |           *
    *         |           *
    *         |           *
    *         |           *
    *         ------------*
    *                     *
    *   Black Canvas      *
    *                     *
    *                     *
    *                     *
    *                     *
    ***********************

    Monday, June 27, 2005 9:11 AM
  • User1152494133 posted
    The original image--it is indeed 1600x1200 and fills the entire frame?  (My first inclination is that the original image must be smaller somehow)

    After rotating and only occupying the corner: does the whole image exist in that corner, or is it cropped?
    Tuesday, June 28, 2005 6:56 AM
  • User-471142486 posted
    Jason,

    the picture is not cropped, it has been resized.

    I published the original and the rotated image to http://barttest.fotopic.net/c595795.html

    Bart

    Tuesday, June 28, 2005 7:51 AM
  • User1152494133 posted

    Man, that's crazy!  I was able to reproduce it, but I'm still trying to understand why it's happening.  As a workaround, though, use the DrawImage() method and specify a height and width:

    gr.DrawImage(img, 0, -1*img.Height, img.Width, img.Height);

    Tuesday, June 28, 2005 10:18 AM
  • User-471142486 posted
    Sorry I didn't reply earlier, but my priorities were shifted to another project.

    I tried this method also, but no luck. The image is rotated but still only a part of the canvas is filled.
    It seems like the DrawImage method doesn't take the width and height into account when drawing the image.

    Any other suggestions ?

    Wednesday, July 13, 2005 5:57 AM
  • User-1750044441 posted
    I am in the process of writing an image library to tackle those common tasks such as resizing, rotating, cropping, etc.

    Here's what I have for rotating (works fine for me ... so far):

    Image origImg = Image.FromFile(Server.MapPath(imageFileName));
    Bitmap newImage = (Bitmap)origImage.Clone();

    newImage.RotateFlip(RotateFlipType.Rotate90FlipNone);
    newImage.Save(imageFilename);

    You probably don't to clone the image, just cast it to a Bitmap instance and then call the RotateFlip method, but I thought I'd do it anyway.

    Hope that works for you!

    Thursday, July 14, 2005 5:22 PM
  • User-1585994330 posted
    thanks! that helped me out like mad! Si!
    Sunday, June 15, 2008 10:30 AM
  • User627501174 posted

    Hi Jason and Bart,

           Can anyone send me the whole code of image uploading, rotation of it and saving the rotated image into the Database.. Im new to ASP.Net so finding hard to understand the exact picture of wht u people told..

    Thanks in Advance,

    Sakshi

    Monday, August 4, 2008 11:32 AM