Entwickler-Ecke
IO, XML und Registry - Filestream korrekt auslesen
Kenpachi - Do 14.01.10 02:25
Titel: Filestream korrekt auslesen
Guten Abend, werte Forengemeinde. :)
Ich verzweifel gerade ein wenig an einer Methode, die überprüft ob eine Bitmap Datei eine bestimmte Farbtiefe aufweist. Um dies zu realisisren, muss ich - wenn ich das richtig verstanden habe - Byte 29 und 30 auslesen (
siehe Wikipedia [
http://de.wikipedia.org/wiki/Windows_Bitmap#Informationsblock]).
Nun, ich bin - was den korrekten Umgang mit einem Filestream angeht - nicht wirklich bewandert und konnte mir mit Hilfe von Google auch nicht wirklich viel wissen aneignen. (Galileo OpenBook war - wohl aus mangelndem Verständnis - auch kein Knüller.)
Wie dem auch sei, ich habe einen Anfang gefunden, aber scheitere schon dabei kläglichst, da ich es absolut nicht hinbekomme, die beiden Bytes in mein Array zu speichern, wobei ich eigentlich nicht mal weiss, ob ich das eigentliche auslesen der Daten schon vermassel.
Hier meine Methode:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| public bool IsValidColorDepth(string strFileName) { byte[] bytColorDepth = new byte[2]; int iColorDepth; using (FileStream fs = File.OpenRead(strFileName)) { fs.Read(bytColorDepth, 29, 2); iColorDepth = BitConverter.ToInt16(bytColorDepth, 0); return (iColorDepth == 8 || iColorDepth == 24) ? true : false; } } |
Beim Debuggen wirft das ganze keinen Fehler aus, aber zur Laufzeit:
Quelltext
1: 2:
| Offset und Länge für das Array liegen außerhalb des gültigen Bereichs, oder die Anzahl ist größer als die Anzahl der Elemente vom Index bis zum Ende der Quellauflistung. |
Der Fehler bezieht sich auch die Zeile:
fs.Read(bytColorDepth, 29, 2);
Ich hoffe, dass ihr mir helfen könnt.
Und sollten euch noch andere Fehler ins Auge fallen, werft sie mir bitte auch gleich an den Kopf. :)
Grüße...
danielf - Do 14.01.10 11:03
Guten Morgen,
ich hab zwar nicht genau verstanden was da machen willst, aber Anmerkungen (Senf) habe ich trotzdem ;)
Bei der Read-Methode des FileStream bezieht sich der Offset nicht aufs Lesen, sondern aufs Schreiben. Deshalb bekommst du zur Laufzeit die ArrayOutOfBonds-Exception (er versucht in dein bytColorDepth Array mit Länge 2 an die Position 29 zu schreiben.. nicht gut ;) ).
Der Begriff Debugen ist so auch nicht korrekt. Den Vorgang bei dem der Kompilier den Quellcode überprüft und übersetzt nennt sich Kompilieren.
Fazit:
Um dein Laufzeit-Exception zu beheben musst du bei der Read-Methode den Offset auf 0 setzen. Wenn du aus der Datei eine bestimmte Stelle auslesen willst (Bit 29 und 30) musst du die Position des Streams verändern. Dies kannst du mit fs.Position = 28 machen.
Hier [
http://dotnet-snippets.de/dns/bitmap-header-auslesen-file--info-SID399.aspx] ist ein Beispiel wie man den kompletten Bitmap-Header ausließt. Je nachdem was du da genau machen willst ist vlt. auch die Klasse Bitmap (System.Drawing) interessant.
Gruß Daniel
Kenpachi - Do 14.01.10 11:44
danielf hat folgendes geschrieben : |
ich hab zwar nicht genau verstanden was da machen willst, aber Anmerkungen (Senf) habe ich trotzdem ;) |
Nur die Farbtiefe ermitteln, mehr nicht...
danielf hat folgendes geschrieben : |
Bei der Read-Methode des FileStream bezieht sich der Offset nicht aufs Lesen, sondern aufs Schreiben. Deshalb bekommst du zur Laufzeit die ArrayOutOfBonds-Exception (er versucht in dein bytColorDepth Array mit Länge 2 an die Position 29 zu schreiben.. nicht gut ;) ). |
Okay, wenn sich der Offset auf das Schreiben bezieht, ist die Exception natürlich logisch. Nur schade, dass sowas nicht in der Info steht. :(
danielf hat folgendes geschrieben : |
Der Begriff Debugen ist so auch nicht korrekt. Den Vorgang bei dem der Kompilier den Quellcode überprüft und übersetzt nennt sich Kompilieren. |
Ist mir schon bewusst, aber es war spät. ;)
danielf hat folgendes geschrieben : |
Fazit:
Um dein Laufzeit-Exception zu beheben musst du bei der Read-Methode den Offset auf 0 setzen. Wenn du aus der Datei eine bestimmte Stelle auslesen willst (Bit 29 und 30) musst du die Position des Streams verändern. Dies kannst du mit fs.Position = 28 machen. |
Vielen Dank. Das sollte die Lösung meines Problems sein...
Stream-Position auf 28 setzen und dann mittels
fs.Read(bytColorDepth, 0, 2); das Array füllen.
Ich kann das ganze gerade nicht ausprobieren, da ich nicht zu Hause bin, aber von der Logik her sollte das doch passen. :)
Hehe, genau an diesem Beispiel habe ich mich orientiert, auch wenn ich von VB wirklich keinen Schimmer habe.
Die Bitmap-Klasse hilft mir bezüglich der Farbtiefe leider nicht weiter, sonst würde ich natürlich deren Property nutzen, anstatt extra den Dateikopf auszulesen.
Ich bedanke mich für die freundliche Hilfe. :)
Grüße...
danielf - Do 14.01.10 13:56
Auf das wollte ich vorher hinaus. Dachte nur wenn er sehr sehr viele Bilder durchsuchen will bzw. deren Farbtiefe auslesen will, dass es dann unnötig Performancelastig ist, jedes Mal das komplette Bitmap Objekt aufzubauen.
"Muss" wohl er entscheiden.
Ralf Jansen - Do 14.01.10 15:23
Zitat: |
Das ist doch widersprüchlich oder? |
Zumindest schlecht ausgedrückt. Der Teil 'byte offset in array' ist aber immer gleich und richtig. Der Offset bezieht sich wie dort steht auf das Array und nicht auf die Position im Filestream.
Oder wenn man der Doku nicht mehr traut ;) so sieht die Stelle in Filestream.Read aus über die Kenpachi gestolpert ist. Nirgendwo wir Bezug auf den Stream genommen.
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| public override int Read([In, Out] byte[] array, int offset, int count) { ... blah if ((array.Length - offset) < count) { throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); }
... blah } |
Kenpachi - Do 14.01.10 15:43
danielf hat folgendes geschrieben : |
Auf das wollte ich vorher hinaus. Dachte nur wenn er sehr sehr viele Bilder durchsuchen will bzw. deren Farbtiefe auslesen will, dass es dann unnötig Performancelastig ist, jedes Mal das komplette Bitmap Objekt aufzubauen.
"Muss" wohl er entscheiden. |
Jain, das Pixelformat hat mit der Farbtiefe nur indirekt zu tun, wie man an der Beschreibung des Members "Canonical" erkennen kann, aber trotzdem danke. :)
Jo, genau das hatte ich auch gelesen, daher war die Verwirrung für mich als Anfänger auch ziemlich groß. Aber dank eurer tatkräftigen unterstützung ist das ja nun auch für mich einleuchtend. :idea:
Grüße...
Ralf Jansen - Do 14.01.10 16:08
C#-Quelltext
1:
| Jain, das Pixelformat hat mit der Farbtiefe nur indirekt zu tun, wie man an der Beschreibung des Members "Canonical" erkennen kann, aber trotzdem danke. :) |
Der Pixelformat Enum ist für alle Image Formate gedacht das heißt nicht das jeder Wert auch bei jedem Imagetyp gültig ist. Ein ~Canonical Bitmap~ gibt es nicht. Die einzig gültigen Pixelformat werte für Bitmaps sind glaube ich die FormatXXX Werte. Insofern sollte das prüfen von Pixelformat reichen. Wenn es ein theoretisches ~canonical Bitmap~ gäbe vermute ich das du im Header auch eine 32 für die Farbtiefe gefunden hättest und keine 24.
Kenpachi - Do 14.01.10 18:28
Ralf Jansen hat folgendes geschrieben : |
C#-Quelltext 1:
| Jain, das Pixelformat hat mit der Farbtiefe nur indirekt zu tun, wie man an der Beschreibung des Members "Canonical" erkennen kann, aber trotzdem danke. :) |
Der Pixelformat Enum ist für alle Image Formate gedacht das heißt nicht das jeder Wert auch bei jedem Imagetyp gültig ist. Ein ~Canonical Bitmap~ gibt es nicht. Die einzig gültigen Pixelformat werte für Bitmaps sind glaube ich die FormatXXX Werte. Insofern sollte das prüfen von Pixelformat reichen. Wenn es ein theoretisches ~canonical Bitmap~ gäbe vermute ich das du im Header auch eine 32 für die Farbtiefe gefunden hättest und keine 24. |
Ich habe mich gerade noch mal schlau gemacht und du hast natürlich Recht - Schande über mein Haupt.
Naja, nun muss ich mich entscheiden, wie ich vorgehe... All zu oft wird die Methode nicht aufgerufen, allerdings wärs - unbeachtlich - mehr Aufwand, die ganzen verschidenen Formate abzufragen, die für mich in Frage kommen würden.
Ich denke, ich werde beim Filestream bleiben, da ich dabei auf jeden Fall mehr lerne.
~Problem gelöst~
Grüße...
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!