2017-03-23 1 views
3

Ich habe ein einfaches Problem: Wenn ich ein Bild in ein Windows-Formular PictureBox laden, werden einige Bilder gedreht und andere nicht.Die richtige Bilddrehung

Grundsätzlich wählt ein Benutzer ein Bild mit einem OpenFileDialog und wenn das Bild ausgewählt:

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

Und ja überprüfte ich die Original-Bildrotation

EDIT:
ich die PictureBox Eigenschaft geändert SizeMode zu StretchImage

+0

Sie meinen einige Bilder (ohne die ursprüngliche Bilddrehung zu ändern), wenn das hochgeladene Bild sich beispielsweise um 90 Grad von der ursprünglichen Drehposition dreht? –

+0

@ P.Pat Ja, manchmal sogar 180 ° –

Antwort

4

Wenn die Bilder enthält exif data die PropertyItems sollte die Orientierung Tag enthalten.

PropertyTagOrientation

Bildausrichtung betrachtet in Bezug auf die Zeilen und Spalten: richtig

Es kodiert für die Rotation/Spiegeln notwendig, das Bild anzuzeigen.

Tag 0x0112

1 - die 0-te Zeile ist an der Spitze des visuellen Bildes, und die 0-te Spalte ist die visuelle linke Seite.
2 - Die 0th Zeile befindet sich am oberen Bildrand und die 0te Spalte ist die visuelle rechte Seite.
3 - Die 0. Zeile befindet sich im unteren Bereich des Bildes , und die 0. Spalte ist die visuelle rechte Seite.
4 - Die 0. Zeile befindet sich am unteren Bildrand und die 0. Spalte ist die visuelle linke Seite.
5 - Die 0. Zeile ist die visuelle linke Seite des Bildes und die 0. Spalte ist die visuelle Spitze.
6 - Die 0. Zeile ist die visuelle Seite des Bildes, und die 0. Spalte ist die visuelle Spitze.
7 - Die 0. Zeile ist die visuelle rechte Seite des Bildes und die 0. Spalte ist die visuelle Unterseite.
8 - Die 0. Reihe ist die visuelle linke Seite des Bildes, und die 0. Spalte ist der visuelle Boden.

Hier ist eine Funktion ein abzurufen PropertyItem:

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

Hier ist ein Beispiel für die GDI + RotateFlip Verfahren der Verwendung eines Bildes auf der Fliege zu justieren:

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

Es gibt die gedrehte Version ..

Ich habe getestet, um Werte mit this nice set of sample images.

Hinweis: Der Code funktioniert nur, wenn die Bilder tatsächlich das Orientierungs-Tag enthalten. Wenn sie es nicht tun, vielleicht weil sie Scans sind, dann wird es nichts tun.

Hinweis 2 Sie schrieb Ich überprüfte die ursprüngliche Bildrotation. Das ist nicht so einfach: Der Explorer zeigt die bereits gedrehten Bilder an, so dass sie alle richtig aussehen und selbst die Überprüfung der Eigenschaften zeigt nicht die Ausrichtung!

Normalerweise, wenn keine EXIF-Daten vorhanden sind, die PropertyTagOrientation Tag ist vorhanden, aber nur den Standardwert von 1 ..

Update: Wenn das Bild nicht die PropertyTagOrientation haben hier ist, wie Sie hinzufügen können:

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

Kudos to @ ne1410s ausgezeichneten answer here!.

Beachten Sie, dass das Hinzufügen von PropertyItems zu einem Bild keine Exif-Daten hinzufügt; Die zwei sind verschiedene Tag-Sets!

+0

Entschuldigung für eine späte Antwort, musste ein Dokument über EXIF-Daten finden. Habe es auf mehreren Bildern versucht, und es funktioniert super! Vielen Dank :) –

+0

heute angewendet. funktioniert super. nur zwei Anmerkungen: 1) für "Drehen", verallgemeinerte ich zu "Image" statt der spezifischeren "Bitmap" - irgendeinen Grund, dies nicht zu tun? 2) die magischen Zahlen 2-8 für den EXIF-Rotationswert verletzen eine Kodierungsstil-Richtlinie von uns, also habe ich ein enum gemacht [genau wie hier] (http://csharphelper.com/blog/2016/07/read-an- image-files-exif-orientation-data-in-c), da sie nirgendwo in den .NET Framework Bibliotheken definiert sind – dlatikay

+0

1) Nun 'Image' kann auch Icon oder WMF sein aber ich erwarte weder die Orientierung noch ' PropertyItem' also wollte ich keine Versprechungen machen ;-). 2) Sicher, gut, solche Richtlinien zu haben; Ich versuche normalerweise, meine Antworten eher blank zu halten, keine Enums, keine Checks usw. Btw: Sie werden bemerkt haben, dass die 'RotateFlipType'-Enumeration viele Duplikate enthält; Ich habe diejenigen ausgewählt, die ich am leichtesten umschließen kann. – TaW

2

Bilder von einer Kamera können so genannte EXIF-Metadaten enthalten. Diese EXIF-Metadaten können ein "Orientierungs" -Tag haben, auf das viele Bildanzeigeprogramme schauen, und das Bild entsprechend rotieren, wenn es angezeigt wird. Die Ausrichtung der Bilddaten selbst bleibt jedoch unverändert. Wenn also Bilder von einer Kamera kommen und Bilder im Querformat von dem, was Sie beschreiben, betroffen sind, ist es wahrscheinlich, dass es sich um das EXIF-Orientierungs-Tag handelt. This is an article über dieses Tag. Vielleicht gibt es C# -Code, der Ihnen helfen kann, mit dem EXIF-Tag umzugehen, habe ich nicht überprüft.