2017-03-23 59 views
3

我有一個簡單的問題:當我將圖像加載到Windows窗體PictureBox某些圖片旋轉而其他圖片不旋轉。獲取正確圖像旋轉

基本上,用戶選擇與一個OpenFileDialog和圖像時,選擇的畫面:

private void OpenFD_FileOk(object sender, CancelEventArgs e) 
{ 
    Image image = Image.FromFile(openFD.FileName); 
    PB_profile.Image = image; 
} 

是的,我檢查了原始圖像旋轉

編輯:
我改變PictureBox屬性SizeModeStretchImage

+0

您的意思是上傳的圖像(例如從原始的旋轉位置旋轉90度)旋轉時的一些圖片(不更改原始圖像旋轉)? –

+0

@ P.Pat是的,有時甚至180° –

回答

4

如果圖片包含exif dataPropertyItems應包括方向標籤。

它編碼旋轉/翻轉要正確顯示圖像:

PropertyTagOrientation以行和列的條件觀察

圖像方向。

標籤0x0112

1 - 第0行是在 可視圖像的頂部,和第0列是視覺左側。
2 - 第0行 行位於圖像的視覺上方,第0列位於右側視覺方位 。
3 - 第0行在 圖像的視覺底部,第0列是視覺右側。
4 - 第0行 位於圖像的視覺底部,第0列是視覺左側。
5 - 第0行是圖像的視覺左側,並且第0列是視覺頂部。
6 - 第0行是圖像的右側 ,第0列是視覺頂部。
7 - 第0行 行是圖像的右側,第0行是 可視底部。
8 - 第0行是圖像的視覺左側, ,第0列是視覺底部。

這裏是檢索的功能的PropertyItem

PropertyItem getPropertyItemByID(Image img, int Id) 
{ 
    return img.PropertyItems.Select(x => x).FirstOrDefault(x => x.Id == Id); 
} 

下面是使用GDI + RotateFlip方法來調整上飛的圖像的一個例子:

void Rotate(Bitmap bmp) 
{ 
    PropertyItem pi = bmp.PropertyItems.Select(x => x) 
             .FirstOrDefault(x => x.Id == 0x0112); 
    if (pi == null) return; 

    byte o = pi.Value[0]; 

    if (o==2) bmp.RotateFlip(RotateFlipType.RotateNoneFlipX); 
    if (o==3) bmp.RotateFlip(RotateFlipType.RotateNoneFlipXY); 
    if (o==4) bmp.RotateFlip(RotateFlipType.RotateNoneFlipY); 
    if (o==5) bmp.RotateFlip(RotateFlipType.Rotate90FlipX); 
    if (o==6) bmp.RotateFlip(RotateFlipType.Rotate90FlipNone); 
    if (o==7) bmp.RotateFlip(RotateFlipType.Rotate90FlipY); 
    if (o==8) bmp.RotateFlip(RotateFlipType.Rotate90FlipXY); 
} 

它返回旋轉版本..

我已經測試的值爲this nice set of sample images

注意:代碼只有在圖像實際上包含方向標籤時才起作用。如果他們沒有,也許是因爲他們是掃描,那麼它會做沒有什麼

注2您寫了我檢查了原始圖像的旋轉。這並非如此簡單:資源管理器將顯示已經旋轉的圖像,所以在這裏他們都看起來不錯,甚至檢查屬性不會顯示方向!

通常情況下,當沒有EXIF數據都存在,PropertyTagOrientation標籤存在,但只有擁有1默認值..

更新: 如果圖像PropertyTagOrientation這裏是你如何可以添加一個:

using System.Runtime.Serialization; 
    .. 

    pi = (PropertyItem)FormatterServices 
     .GetUninitializedObject(typeof(PropertyItem)); 

    pi.Id = 0x0112; // orientation 
    pi.Len = 2; 
    pi.Type = 3; 
    pi.Value = new byte[2] { 1, 0 }; 

    pi.Value[0] = yourOrientationByte; 

    yourImage.SetPropertyItem(pi); 

榮譽對@ ne1410s的優秀answer here!

請注意,將PropertyItems添加到圖像不會添加exif數據;這兩個是不同的標籤集!

+0

對於遲到的回答感到抱歉,不得不找到一些關於EXIF數據的文檔。嘗試了幾張照片,它效果很好!非常感謝:) –

+0

今天申請。效果很好。只是兩個說法:1)對於'旋轉',我推廣到'圖像'而不是更具體的'位圖' - 任何理由不這樣做? 2)EXIF旋轉值的幻數2-8違反了我們的編碼風格策略,所以我做了一個枚舉[就像這裏](http://csharphelper.com/blog/2016/07/read-an-因爲它們在.NET框架庫中沒有定義/暴露 – dlatikay

+0

1)那麼'圖像'也可以是圖標或WMF,但我期望既沒有定位''圖像文件-exif-orientation-data-in- PropertyItem'因此我不想做任何承諾;-)。 2)當然,有這樣的政策很好;我通常試圖保持我的答案,而不是裸骨,沒有枚舉,沒有檢查等。順便說一句:你會注意到'RotateFlipType'枚舉包含許多重複;我選擇了那些我可以最輕鬆地包裹頭部的東西。 – TaW

2

來自相機的圖片可以包含所謂的EXIF元數據。這個EXIF元數據可以有一個「方向」標籤,許多圖像瀏覽程序可以查看這些標籤,並在顯示圖片時相應地旋轉圖片。但圖像數據本身的方向保持不變。 因此,如果您的圖像來自相機並且橫向方向的圖像受到您所描述的影響,則可能是因爲EXIF方向標籤。 This is an article關於此標籤。 也許有C#代碼可以幫助你處理EXIF標籤,我沒有檢查。