2009-02-16 6 views
21

Ich weiß, wie die Größe (x, y) ein Bild erhaltenWie bekomme ich zuverlässig eine Bildgröße in .NET, ohne das Bild zu laden?

Image.FromFile("cat.jpg").Size 

aber das erfordert das Bild aus dem Speicher geladen werden.

Wenn ich die Bilder im Windows Explorer anschaue, zeigt es mir die Größe.

  • Wie greife ich auf diese Größe zu?
  • Ist es für alle Bilder zuverlässig? Muss der Windows-Explorer das Bild zuerst "gesehen" haben, damit die Größe verfügbar ist? Ich möchte nicht auf einen Server hochladen und habe keine Metadaten verfügbar, bevor ich sie in den Internet Explorer geladen habe.

Edit: wechselte ich das Thema von ‚Größe‘ auf ‚Dimensionen‘, welche Größe ich wollte zu klären.

Antwort

3

Dies beinhaltet in der Regel beinhaltet das Öffnen der Datei und Lesen nur seiner Kopfzeile (die ersten paar Bytes), um sein Format und die Größe zu finden. Sie müssen nicht die gesamte Datei lesen, um ihre Größe herauszufinden. Manchmal ist die Größe sogar in einem bestimmten Offset in der Datei, so dass das Finden der Größe nur 8 Bytes liest.

Sie können filemon.exe verwenden, um herauszufinden, was Windows Explorer selbst tut, um die Größe zu finden.

+0

Geht Windows nicht direkt zum Betriebssystem und fragt, wie viel Platz das Bild auf der Festplatte hat? Ist es kein Dateiattribut? Oder wie Sie sagen, ist es codierte Metadaten? – Paxic

+0

@panix - Entschuldigung, wenn ich dich verwirrt habe. ich meine Größe wie in Breite + Höhe und nicht Größe wie in Bytes. –

+0

@shy wissen Sie, ob das was Explorer tut? Kann ich mich auf die Metadaten von Windows Explorer verlassen?Ich denke nur, das ein wenig hinterhältig ist und möglicherweise unzuverlässig in einigen wierd Grenzfälle - das ist, warum ich die Frage gepostet –

11

Wenn Sie die Bildabmessungen (Breite und Höhe) ohne das Bild laden möchten, müssen Sie einen Teil der JPEG-Datei selbst lesen, wie unten.

ist hier ein aus der Box Methode für Sie

public static Size GetJpegImageSize(string filename) { 
    FileStream stream=null; 
    BinaryReader rdr=null; 
    try { 
     stream=File.OpenRead(filename); 
     rdr=new BinaryReader(stream); 
     // keep reading packets until we find one that contains Size info 
     for(; ;) { 
      byte code=rdr.ReadByte(); 
      if(code!=0xFF) throw new ApplicationException(
        "Unexpected value in file "+filename); 
      code=rdr.ReadByte(); 
      switch(code) { 
       // filler byte 
       case 0xFF: 
        stream.Position--; 
        break; 
       // packets without data 
       case 0xD0: case 0xD1: case 0xD2: case 0xD3: case 0xD4: 
       case 0xD5: case 0xD6: case 0xD7: case 0xD8: case 0xD9: 
        break; 
       // packets with size information 
       case 0xC0: case 0xC1: case 0xC2: case 0xC3: 
       case 0xC4: case 0xC5: case 0xC6: case 0xC7: 
       case 0xC8: case 0xC9: case 0xCA: case 0xCB: 
       case 0xCC: case 0xCD: case 0xCE: case 0xCF: 
        ReadBEUshort(rdr); 
        rdr.ReadByte(); 
        ushort h=ReadBEUshort(rdr); 
        ushort w=ReadBEUshort(rdr); 
        return new Size(w, h); 
       // irrelevant variable-length packets 
       default: 
        int len=ReadBEUshort(rdr); 
        stream.Position+=len-2; 
        break; 
      } 
     } 
    } finally { 
     if(rdr!=null) rdr.Close(); 
     if(stream!=null) stream.Close(); 
    } 
} 

private static ushort ReadBEUshort(BinaryReader rdr) { 
    ushort hi=rdr.ReadByte(); 
    hi<<=8; 
    ushort lo=rdr.ReadByte(); 
    return (ushort)(hi|lo); 
} 

:) Das ist nicht mein Code, habe dieses Beispiel in Code-Projekt einige Zeit zurück. Ich kopierte und speicherte es in meinen Utility-Snippets, erinnere mich aber nicht an den Link.

+2

Pfui! lol. Whoa das ist eine Menge Code. Außerdem bin ich in einer Web-Umgebung, so kann ich auch Gifs und PNGs haben. Ich bin Neigung zu Caching Image.FromFile („cat.jpg“) Größe -. oder zumindest Timing, wie lange es in einem Bild –

+0

Yep zu lesen braucht - es öffnet sich das jpg den Header mit Größeninformationen – amazedsaint

32

Sie können einfach Image.FromStream(Stream, bool, bool) mit "false" 2. und 3. Parameter verwenden, um das Laden der Datei in den Speicher zu vermeiden.

+1

Dies ist genau zu lesen was ich brauchte; keine Byteverwaltung, usw. Danke! –

+0

+1 Arbeiten für mich ... – takrl

1

Von ganz oben - LoadImage() hat eine Überschreibung, die Fortschritt Rückruf angibt. Vielleicht können Sie damit den Ladevorgang nach dem Lesen des Headers abbrechen?

Verwandte Themen