2009-07-20 4 views
31

Ich habe ein Formular mit einem großen TImage als Hintergrund. Problem ist, dass dies direkt im DFM als Bitmap gespeichert wird, das ca. 3 MB benötigt. Die ursprüngliche PNG-Datei ist ~ 250 KB. Ich möchte versuchen, Aufblähung zu reduzieren, indem Sie das PNG in einer Ressource einbetten, und das Formular dann während OnCreate laden. Ich kann das jetzt tun, da Delphi 2009 PNG-Unterstützung enthält, außer dass ich nicht ganz weiß, wie man eine Ressourcendatei mit einem PNG erstellt. Wer weiß wie das geht?Wie erstelle ich eine PNG-Ressource?

Antwort

50

Beispiel Textdatei (mit dem Namen myres.rc):

MYPNG RCDATA mypng.png 

zum Projekt hinzugefügt:

{$R 'myres.res' 'myres.rc'} 

Beispiel Laden zur Laufzeit:

uses 
    PngImage; 

var 
    Png: TPngImage; 
begin 
    Png := TPngImage.Create; 
    try 
    Png.LoadFromResourceName(HInstance, 'MYPNG'); 
    Image1.Picture.Graphic := Png; // Image1: TImage on the form 
    finally 
    Png.Free; 
    end; 
end; 
+0

Ist 'RCDATA' wirklich der spezifischste Ressourcentyp, der für diesen Grafiktyp verfügbar ist? Es gibt zum Beispiel kein 'RT_PNG'? –

+2

Gute Frage, Rob. Mein momentan installiertes Platform SDK ist für Windows Server 2003 R2 und ich konnte eine PNG-spezifische Konstante in WinUser.h nicht finden. Ich bin mir jedoch nicht sicher. Es könnte an anderer Stelle deklariert werden, vielleicht in einer späteren Version des Platform SDK. –

+11

LoadFromResourceName sucht speziell nach einer Ressource vom Typ RCDATA. –

1

Wenn Sie mit Delphi 2009, TImage sollte Ihre PNG-Datei als PNG in der DFM-Datei speichern. Der DFM wird größer sein, da der binäre Inhalt der Picture.Data-Eigenschaft des TImage-Objekts im DFM als hexadezimaler Text codiert ist. Wenn der DFM jedoch in Ihre EXE kompiliert wird, wird er in eine binäre Ressource kompiliert. Ihr Image sollte dann den gleichen Speicherplatz in der RCDATA-Ressource des Formulars belegen, wenn das PNG in seiner eigenen RCDATA-Ressource gespeichert wird.

Ich habe dies gerade getestet, indem ich eine meiner eigenen Delphi 2009 DFM-Dateien geöffnet habe, die eine TImage-Komponente mit einem PNG-Bild zur Entwurfszeit in einem Texteditor geladen haben, den Inhalt der Picture.Data-Eigenschaft kopieren und in eine einfügen Hex-Editor. Der Hex-Editor zeigt mir, dass die Picture.Data-Eigenschaft eine tatsächliche PNG-Datei mit dem Präfix 10 Byte speichert. Das erste Byte ist $ 09, und die nächsten 9 Bytes buchstabieren TPngImage. Wenn ich diese 10 Bytes lösche und die Datei im Hex-Editor speichere, bekomme ich eine richtige PNG-Datei.

Wenn Sie also Delphi 2009 verwenden, laden Sie einfach das PNG-Bild zur Entwurfszeit in eine TImage-Komponente.

+0

Interessant, aber was ist mit dem Fall, wo ein Bild Wird auf mehreren Formularen wiederverwendet? Ist Delphi intelligent genug, um nur eine Kopie zu speichern, oder speichert es das Bild n mal, wobei n die Anzahl der TImage-Komponenten mit dem geladenen Bild ist? :) – Drarok

+3

Jede TImage-Komponente speichert ihr Bild unabhängig von anderen TImage-Instanzen.Wenn Sie also das gleiche Bild in n Instanzen von TImage laden, wird dasselbe Bild n-mal gespeichert. Eine Möglichkeit, dies zu lösen, ist die Verwendung der Formularvererbung. Erstellen Sie ein Basisformular mit dem TImage und laden Sie das Bild in das Bild. Dann leiten Sie alle Formulare ab, die dasselbe TImage von diesem Formular haben müssen. Alle Eigenschaften, die in abgeleiteten Formularen nicht geändert werden, werden nur im DFM des Vorgängerformulars gespeichert. Dazu gehören die Bilddaten eines TImage. –

2

Für diejenigen, die dieser Code C++ Builder funktioniert für mich:

Im ResourceTest.rc

IMG_BMP BITMAP "Ressources\\myimage.bmp"; 
IMG_PNG RCDATA "Ressources\\myimage.png"; 

In der ResourceTest.rh Datei Datei

#ifndef ResourceTestRH 
#define ResourceTestRH 

#define IMG_BMP "IMG_BMP" 
#define IMG_PNG "IMG_PNG" 

#endif 

In der Datei ResourceTest.cpp

#include "pngimage.hpp" 

// Loading bmp image from resource 
Graphics::TBitmap *bmpImage = new Graphics::TBitmap(); 
bmpImage->LoadFromResourceName((int)HInstance, IMG_BMP); 

// Loading png image from resource 
TPngImage *pngImage = new TPngImage(); 
pngImage->LoadFromResourceName((int)HInstance, IMG_PNG);