Laden...

Wie Grafikformat aus Image-Objekt einer Bilddatei erhalten?

Erstellt von tomybyte vor 14 Jahren Letzter Beitrag vor 14 Jahren 2.697 Views
T
tomybyte Themenstarter:in
11 Beiträge seit 2003
vor 14 Jahren
Wie Grafikformat aus Image-Objekt einer Bilddatei erhalten?

Hallo,

wenn ich ein Bild in ein Image-Objekt geladen habe, wie kann ich dann über dieses Image-Objekt das Grafikformat der Datei (z.B. BMP, JPEG, TIFF, GIF etc.) erhalten.
Folgender Code liefert (in der Umwandlung in einen String) einen für mich unbrauchbaren HashCode:
[ImageFormat: b96b3cae-0728-11d3-9d7b-0000f81ef32e]


Image _Image = Image.FromFile("C:\\test.jpg");
ImageFormat iF = _Image.RawFormat;
MessageBox.Show(iF.ToString());

Auch Image.PixelFormat ist nicht viel brauchbarer.

Verstehen tu ich es nicht, da ich im "Petzold" unter ImageFormat als Eigenschaftswerte die verschiedenen spezifischen Grafikformate in einer Tabelle gefunden habe (so wie ich es gerne hätte). Googlen (bestimmt 10 Versuche) - hat außer dem Hinweis auf Image.RawFormat nichts gebracht!

Hat jemand den Durchblick? 8o

K
133 Beiträge seit 2009
vor 14 Jahren

Sieht aus wie eine GUID versuch die doch mal in deiner Registry aufzulösen.

T
433 Beiträge seit 2006
vor 14 Jahren

Servus,

ich hab das so vor einiger Zeit gelöst gehabt:

        
public static ImageFormat GetImageFormat(Image image)
{
   PropertyInfo[] propertyInfos = typeof(ImageFormat).GetProperties(BindingFlags.Public | BindingFlags.Static);

   // Have to check via Equals otherwise it cannot be compared
   foreach (PropertyInfo info in propertyInfos)
      if (info.GetValue(null, null).Equals(image.RawFormat))
         return (ImageFormat)info.GetValue(null, null);

   // Return MemoryBmp as default
   return ImageFormat.MemoryBmp;
}

Hatte bisher keine Probleme damit.
Solltest du performance benötigen kannst du auch noch eine Liste zum vergleichen aufbauen und die ständig abfragen.

Gruß,
Tom

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo tomybyte,

ImageFormat.ToString ist implementiert als:

public override string ToString()
{
   if (this == memoryBMP)
   {
      return "MemoryBMP";
   }
   if (this == bmp)
   {
      return "Bmp";
   }
   if (this == emf)
   {
      return "Emf";
   }
   if (this == wmf)
   {
      return "Wmf";
   }
   if (this == gif)
   {
      return "Gif";
   }
   if (this == jpeg)
   {
      return "Jpeg";
   }
   if (this == png)
   {
      return "Png";
   }
   if (this == tiff)
   {
      return "Tiff";
   }
   if (this == exif)
   {
      return "Exif";
   }
   if (this == icon)
   {
      return "Icon";
   }
   return ("[ImageFormat: " + this.guid + "]");
}

Das bedeutet, dass du den Klartext bekommen würdest, wenn dein Bild ein bekanntes ImageFormat hätte.

herbivore

T
tomybyte Themenstarter:in
11 Beiträge seit 2003
vor 14 Jahren

Gut es ist so wie Du vermutet hast:
[HKEY_CLASSES_ROOT\CLSID{D2923B86-15F1-46FF-A19A-DE825F919576}\SupportedExtension.jpeg]
"Generic"="image"
"FormatGUID"="{B96B3CAE-0728-11D3-9D7B-0000F81EF32E}"

Aber da kommen mir nun zig Fragen:
Ist dieser Schlüssel eindeutig?
Finde ich den auch auf anderen Systemen?
Und auch genauso auf Windows7?
Wieso dieser Umweg über die Registry?
Gehts nicht einfacher?
Außerdem:
Wie hol ich denn das eindeutig aus der Registry?
Und muss nicht der angemeldete User bzw. der ausführende Prozess dann Admin-Rechte haben, um auf die Registry zugreifen zu können?

Du siehst von diesem Weg bin ich überhaupt nicht begeistert. Manchmal sehne ich mich doch nach dem guten alten VB6 zurück! 🙁

T
tomybyte Themenstarter:in
11 Beiträge seit 2003
vor 14 Jahren

Das bedeutet, dass du den Klartext bekommen würdest, wenn dein Bild ein bekanntes ImageFormat hätte.

@ herbivore:
Wie Du aus meinem letzten Beitrag entnehmen kannst, hat das Bild ja ein bekanntes Bildformat (jpeg), wieso erhalte ich dann nur die GUID des Formats?

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo tomybyte,

hm, schwer zu sagen. Vergleiche mal die GUID von deinem ImageFormat mit der Guid von ImageFormat.Jpeg.

herbivore

K
133 Beiträge seit 2009
vor 14 Jahren

Ist dieser Schlüssel eindeutig?
Finde ich den auch auf anderen Systemen?

Ja eindeutig wird er sein. Auf meinem Win7 ist der Schlüssel nicht vorhanden.

T
tomybyte Themenstarter:in
11 Beiträge seit 2003
vor 14 Jahren

Könnte es daran liegen, dass hier nur die GUID zurückgegeben wird, da in der Registry für jpg und jpeg der gleiche Schlüssel hinterlegt ist?

[HKEY_CLASSES_ROOT\CLSID{D2923B86-15F1-46FF-A19A-DE825F919576}\SupportedExtension.jpg]
"Generic"="image"
"FormatGUID"="{B96B3CAE-0728-11D3-9D7B-0000F81EF32E}"

Das heißt allerdings die FormtGUID ist nicht eindeutig. Kann das sein? Bzw. darf das sein oder ist das ein Registry-Defekt (sowas kommt ja vor). Würde allerdings bedeuten, dass eine auf ImageFormat basierende C#-Programmierung auf manchen PCs läuft und auf anderen Probleme macht.

Gibt es da nicht eine Lösung, die das Bildformat aus den Image-Daten des Image-Objektes entnehmen kann (z.B. aus dem header?)

T
tomybyte Themenstarter:in
11 Beiträge seit 2003
vor 14 Jahren

@ Tom:
Der Ansatz von Dir funktioniert bei meinem Test einwandfrei. Performance ist an der Stelle nicht wichtig. Danke, scheint genau, das was ich gesucht habe! 🙂

T
433 Beiträge seit 2006
vor 14 Jahren

Das Problem ist der bescheuerte override von ToString. Naja zumindest für den Entwickler bescheuert, nicht aber fürs Framework.

Die müssten da equals anstatt == verwenden, dann würde man auch von RawFormat den ImageFomat auf anhieb vergleichen können.
Denn bei RawFormat wird ein neuer ImageFormat erstellt anstatt die statischen ImageFormats zurückzugeben.

Folgender Code veranschaulicht das Problem:


Bitmap bitmap = new Bitmap(@"C:\temp\test.jpg");

ImageFormat imageFormat = new ImageFormat(bitmap.RawFormat.Guid);

Console.WriteLine(imageFormat);

Console.WriteLine("Guid the same: " + (imageFormat.Guid == ImageFormat.Jpeg.Guid));

Console.WriteLine("Image types the same: " + (bitmap.RawFormat == ImageFormat.Jpeg));

Console.WriteLine("Image types really not the same?: " + bitmap.RawFormat.Equals(ImageFormat.Jpeg));

Console.WriteLine(ImageFormat.Jpeg.Guid + " | " + ImageFormat.Jpeg);

Console.ReadKey();

ToString ist hier eigentlich nur für die statischen Klassen vernünftig nutzbar.

Gruß,
Tom

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo tomybyte,

Bzw. darf das sein oder ist das ein Registry-Defekt?

nein, das ist kein Defekt und auch kein Problem bezüglich der Eindeutigkeit. Die GUID steht ja für das Dateiformat. Und das ist ja bei .jpg und .jpeg dasselbe.

herbivore