Programmatisch eine hochwertige ico-Datei erstellen

8

Ich versuche, ein qualitativ hochwertiges Symbol zu erstellen (bedeutet: passend für Win Vista / 7/8 ) aus einer PNG-Datei programmatisch in C # zur Verwendung als Verknüpfungssymbole. Da die Bitmap.GetHIcon () - Funktion diese Art von Symbolen nicht unterstützt und externe Abhängigkeiten oder Bibliotheken vermieden werden sollen, verwende ich derzeit einen leicht modifizierten ICO-Writer, den ich gefunden habe hier auf SO . Ich habe funktionierenden Code, aber ich habe einige Störungen in der Art, wie Windows diese Symbole anzeigt. Der relevante Code ist:

%Vor%

Das kompiliert und funktioniert, aber mit einem Problem. Windows zeigt das Symbol auf der Verknüpfung falsch an. Ich mache das auch programmatisch, aber es passiert auch, wenn ich es manuell mache (über Dateieigenschaften, Symbol ändern). Das Problem ist, dass das Symbol abgeschnitten ist (das Bild selbst wird korrekt angezeigt). Es hängt vom Bild ab, aber normalerweise werden nur ungefähr 20% des tatsächlichen Symbols angezeigt. Wenn ich die Datei in einem Bildbetrachter wie XNView öffne, wird sie vollständig und korrekt angezeigt, MS Paint jedoch nicht. Ich habe diesen Screenshot gemacht, zusammen mit einem korrekt angezeigten Symbol zum Vergleich

Ich vermute, dass der Fehler in der ICO-Speichermethode liegt, aber selbst nach dem Vergleich mit normal angezeigten ICOs in einem Hex-Editor wird der Header korrekt geschrieben, aber der PNG-Bildteil selbst sieht anders aus. Hat jemand eine Idee? Ich begrüße auch bessere, weniger hacky Lösungen.

    
Lennart 04.01.2013, 12:21
quelle

1 Antwort

7

Ihre ico-Datei ist so eingestellt, dass die Länge der eingebetteten Bitmap mit einer Genauigkeit von nur 16 Bit gespeichert wird. Die PNG-Datei ist jedoch zu groß (größer als 65535 Byte), sodass der Längeneintrag überläuft.

i.e. Die folgenden Zeilen sind unvollständig:

%Vor%

Sie könnten diese Zeilen hinzufügen:

%Vor%

Aus Gründen der Sauberkeit und Leistung würde ich im Allgemeinen all diese separaten Schreibvorgänge vermeiden und einfach die Schreibüberlastung mit dem Byte-Array-Parameter verwenden. Anstelle der etwas trickreichen Datei Save-To-File, die Sie dann suchen, können Sie auch einen Save-To-MemoryStream, dann einen einzelnen Write für den Header (der jetzt die PNG-Länge in Bytes verwenden kann) und einen einzelnen Schreibvorgang zum Kopieren des PNG in Erwägung ziehen Daten aus dem Speicher-Stream in die Datei.

Ein weiterer Punkt, den Sie wirklich ansprechen sollten, ist disposing IDisposable resources . Selbst wenn Sie es noch nicht brauchen, da Sie keine Probleme haben, wird es Sie eines Tages beißen und wenn Sie sogar eine ziemlich kleine Codebasis mit allen Arten von Einweg-Disposables haben, wird es Ihnen sehr schwer fallen, die Quelle zu finden Ihr Leck und / oder Deadlock. Im Allgemeinen: Niemals rufen Sie Close auf, es sei denn, Sie können es nicht vermeiden - wickeln Sie stattdessen Ihre FileStream in einen using -Block ein. Ebenso sind Image und Bitmap wegwerfbar und weisen native Ressourcen zu, obwohl Sie zumindest keine Locking-Probleme mit diesen bekommen (AFAIK - aber besser als Nachsicht).

    
Eamon Nerbonne 04.01.2013, 12:25
quelle

Tags und Links