سؤال

I am using the code from the following answer on an old question to set up a thumbnail of an uploaded image.

https://stackoverflow.com/a/2001462/1593395

This works perfectly and pads out the image, keeps aspect ratio etc but if I upload an image from my mobile phone the thumbnail image that is saved from this method is rotated ccw 90 degrees.

Do you know what is causing this? The original image is just saved using AjaxFileUpload1.SaveAs(MapPath("~/catalog/images/" & imageFilename)) (From the AJAX Control toolkit) and is showing in the correct orientation.

Thanks

هل كانت مفيدة؟

المحلول

Maybe it's due to the image being physically stored in a different orientation that which it's displayed in, eg, a 640*480 shot taken with the camera sideways may be stored as 480*640, with an orientation exif data flag.

This is great because explorer/paint/photoshop/just about every viewer will see that exif flag and rotate it before it is rendered. However, .net Image classes dont (which seems reasonable when you know what is happening), so you'll have to either set the exif rotate attrib on the new thumbnail image (which I prefer not to, just because I don't like having any attribs on thumbnails) or check and rotate the thumbnail yourself.

Below is a rough way to do this. Note that I've supplied the code in c# as a modified version of the answer you referenced, as that was also c#. Conversion to vb.net should be pretty straight forward :)

  if (sourceImage.PropertyIdList.Contains(0x112)) //0x112 = Orientation
  {
     var prop = sourceImage.GetPropertyItem(0x112);
     if (prop.Type == 3 && prop.Len == 2)
     {
        UInt16 orientationExif = BitConverter.ToUInt16(sourceImage.GetPropertyItem(0x112).Value, 0);
        if (orientationExif == 8)
        {
           newImage.RotateFlip(RotateFlipType.Rotate270FlipNone);
        }
        else if (orientationExif == 3)
        {
           newImage.RotateFlip(RotateFlipType.Rotate180FlipNone);
        }
        else if (orientationExif == 6)
        {
           newImage.RotateFlip(RotateFlipType.Rotate90FlipNone);
        }
     }
  }

So the updated FixedSize code would be as such:

static Image FixedSize(Image imgPhoto, int Width, int Height)
{
    int sourceWidth = imgPhoto.Width;
    int sourceHeight = imgPhoto.Height;
    int sourceX = 0;
    int sourceY = 0;
    int destX = 0;
    int destY = 0;

    float nPercent = 0;
    float nPercentW = 0;
    float nPercentH = 0;

    nPercentW = ((float)Width / (float)sourceWidth);
    nPercentH = ((float)Height / (float)sourceHeight);
    if (nPercentH < nPercentW)
    {
        nPercent = nPercentH;
        destX = System.Convert.ToInt16((Width -
                      (sourceWidth * nPercent)) / 2);
    }
    else
    {
        nPercent = nPercentW;
        destY = System.Convert.ToInt16((Height -
                      (sourceHeight * nPercent)) / 2);
    }

    int destWidth = (int)(sourceWidth * nPercent);
    int destHeight = (int)(sourceHeight * nPercent);

    Bitmap bmPhoto = new Bitmap(Width, Height,
                      PixelFormat.Format24bppRgb);
    bmPhoto.SetResolution(imgPhoto.HorizontalResolution,
                     imgPhoto.VerticalResolution);

    Graphics grPhoto = Graphics.FromImage(bmPhoto);
    grPhoto.Clear(Color.Red);
    grPhoto.InterpolationMode =
            InterpolationMode.HighQualityBicubic;

    grPhoto.DrawImage(imgPhoto,
        new Rectangle(destX, destY, destWidth, destHeight),
        new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
        GraphicsUnit.Pixel);

    grPhoto.Dispose();

    //Rotate image to what is expected.
    if (imgPhoto.PropertyIdList.Contains(0x112)) //0x112 = Orientation
    {
       var prop = imgPhoto.GetPropertyItem(0x112);
       if (prop.Type == 3 && prop.Len == 2)
       {
          UInt16 orientationExif = BitConverter.ToUInt16(sourceImage.GetPropertyItem(0x112).Value, 0);
          if (orientationExif == 8)
          {
             bmPhoto.RotateFlip(RotateFlipType.Rotate270FlipNone);
          }
          else if (orientationExif == 3)
          {
             bmPhoto.RotateFlip(RotateFlipType.Rotate180FlipNone);
          }
          else if (orientationExif == 6)
          {
             bmPhoto.RotateFlip(RotateFlipType.Rotate90FlipNone);
          }
       }
    }

    return bmPhoto;
}

Note that this doesn't cover EVERY exif orientation, just common ones.

References:

http://www.impulseadventure.com/photo/exif-orientation.html

http://msdn.microsoft.com/en-us/library/xddt0dz7.aspx

p.s: that was my first stack overflow answer, so please go easy on the feedback ;)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top