也许这是由于图像被物理地存储在一个不同的取向,其它显示在,例如,与相机侧身截取的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:这是我的第一个堆栈溢出的答案,所以请去容易反馈;)
感谢这个,我没有得到一个类似的答案从另一个Stackoverflow问题已经很好,但你的是一样好,所以接受它。感谢您对我的看法 –
FYI,要使用'PropertyIdList.Contains()',您必须包含'using System.Linq'。 –