2013-10-25 78 views
3

我正在使用旧问题的以下答案中的代码来设置上传图像的缩略图。.Net缩略图正在从手机创建时旋转图像

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

这工作完全和垫出来的图像,保持宽高比等,但如果我从我的手机上传图片是从这种方法节约了缩略图CCW旋转90度。

你知道是什么原因造成的吗?原始图像仅使用AjaxFileUpload1.SaveAs(MapPath(“〜/ catalog/images /”& imageFilename))(从AJAX Control工具包)保存,并以正确的方向显示。

由于

回答

6

也许这是由于图像被物理地存储在一个不同的取向,其它显示在,例如,与相机侧身截取的640 * 480拍摄可以被存储为480 * 640,用方向exif数据标志。

这很棒,因为explorer/paint/photoshop /几乎每个浏览器都会看到exif标志并在渲染之前将其旋转。然而,.net图像类不会(当你知道发生了什么时,这似乎是合理的),所以你必须在新的缩略图图像上设置exif rotate attrib(我不喜欢,因为我不喜欢在缩略图上有任何属性)或自己检查并旋转缩略图。

下面是执行此操作的粗略方法。请注意,我已经在c#中提供了代码作为您引用的答案的修改版本,因为这也是c#。转换为vb.net应该是相当直截了当:)

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); 
     } 
    } 
    } 

所以更新的固定大小的代码将是这样:

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; 
} 

请注意,这并不涵盖所有EXIF的方向,只要常见的。

参考文献:

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

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

PS:这是我的第一个堆栈溢出的答案,所以请去容易反馈;)

+0

感谢这个,我没有得到一个类似的答案从另一个Stackoverflow问题已经很好,但你的是一样好,所以接受它。感谢您对我的看法 –

+0

FYI,要使用'PropertyIdList.Contains()',您必须包含'using System.Linq'。 –