Autor Beitrag
Kenpachi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 30

Win Vista, Win 7
C#, VB, ASP.NET (VS 2010 Express)
BeitragVerfasst: Do 14.01.10 02:25 
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).
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:
ausblenden 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, 292);
                iColorDepth = BitConverter.ToInt16(bytColorDepth, 0);
                return (iColorDepth == 8 || iColorDepth == 24) ? true : false;
            }
        }


Beim Debuggen wirft das ganze keinen Fehler aus, aber zur Laufzeit:
ausblenden 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, 292);


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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1012
Erhaltene Danke: 24

Windows XP
C#, Visual Studio
BeitragVerfasst: 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 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 30

Win Vista, Win 7
C#, VB, ASP.NET (VS 2010 Express)
BeitragVerfasst: Do 14.01.10 11:44 
user profile icondanielf hat folgendes geschrieben Zum zitierten Posting springen:
ich hab zwar nicht genau verstanden was da machen willst, aber Anmerkungen (Senf) habe ich trotzdem ;)

Nur die Farbtiefe ermitteln, mehr nicht...

user profile icondanielf hat folgendes geschrieben Zum zitierten Posting springen:

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. :(

user profile icondanielf hat folgendes geschrieben Zum zitierten Posting springen:

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

user profile icondanielf hat folgendes geschrieben Zum zitierten Posting springen:

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, 02); 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. :)

user profile icondanielf hat folgendes geschrieben Zum zitierten Posting springen:

Hier 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.

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...
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 14.01.10 13:40 
Zitat:
Nur die Farbtiefe ermitteln, mehr nicht...

Dann sollte es doch reichen das Pixelformat abzufragen?
danielf
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1012
Erhaltene Danke: 24

Windows XP
C#, Visual Studio
BeitragVerfasst: 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.
danielf
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1012
Erhaltene Danke: 24

Windows XP
C#, Visual Studio
BeitragVerfasst: Do 14.01.10 14:47 
Ich habe mir gerade nochmal die MSDN-Dokumentation von FileStream angeschaust und da steht tatsächlich:
Zitat:
offset Der Byteoffset im array, ab dem gelesen werden soll.

Konnte ich dann nicht glauben und hab mir noch das englische "Orginal" angeschaut.
Zitat:
offset The byte offset in array at which to begin reading.

Und zum Vergleich die Parameterbeschreibung aus VS 2008 Expr. Edition:
Zitat:
offset The byte offset in array at which the read bytes will be placed.

Das ist doch widersprüchlich oder?

Dann wäre laut MSDN-Doc Kenpachi's Version aus dem ersten Thread korrekt - und meine falsch. Kann das jemand aufklären?

Gruß Daniel
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: 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.

ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 30

Win Vista, Win 7
C#, VB, ASP.NET (VS 2010 Express)
BeitragVerfasst: Do 14.01.10 15:43 
user profile iconRalf Jansen hat folgendes geschrieben Zum zitierten Posting springen:
Zitat:
Nur die Farbtiefe ermitteln, mehr nicht...

Dann sollte es doch reichen das Pixelformat abzufragen?

user profile icondanielf hat folgendes geschrieben Zum zitierten Posting springen:
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. :)

user profile icondanielf hat folgendes geschrieben Zum zitierten Posting springen:
Ich habe mir gerade nochmal die MSDN-Dokumentation von FileStream angeschaust und da steht tatsächlich:
Zitat:
offset Der Byteoffset im array, ab dem gelesen werden soll.

Konnte ich dann nicht glauben und hab mir noch das englische "Orginal" angeschaut.
Zitat:
offset The byte offset in array at which to begin reading.

Und zum Vergleich die Parameterbeschreibung aus VS 2008 Expr. Edition:
Zitat:
offset The byte offset in array at which the read bytes will be placed.

Das ist doch widersprüchlich oder?

Dann wäre laut MSDN-Doc Kenpachi's Version aus dem ersten Thread korrekt - und meine falsch. Kann das jemand aufklären?

Gruß Daniel
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 14.01.10 16:08 
ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 30

Win Vista, Win 7
C#, VB, ASP.NET (VS 2010 Express)
BeitragVerfasst: Do 14.01.10 18:28 
user profile iconRalf Jansen hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden 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...