![]() |
Icons mit Delphi erstellen
Hi,
hat schon jemand so etwas gemacht ? Mein neues Projekt soll en IconEditor werden. Allerdings gibt es noch ein paar Probleme: :?: 1. Wie kann man die Farbpalette einen Icons ändern? :?: 2. Wie kann man Icons bearbeiten (verwende zur Zeit die Methode in Bitmap umwandeln. Allerdings geht dann die Transparenz verloren). Also es sollten möglichst alle Bittiefen verwendet werden können: 32 Bit, 24 Bit, 16 Bit, 8 Bit, 4 Bit, 1 Bit. Bei den Bittiefen 16, 8, 4 und 1 Bit sollten außerdem die Farben der Palette manuell geändert werden können. Sind in dieser Beziehung die Paletten bei Bitmaps und Icons (wegen Umwandlung) auch 1:1 kompatibel? Vielleicht hat ja jemand mit so etwas schon Erfahrungen gesammelt, in der Suche hab ich leider nichts brauchbares gefunden :? :cyclops: Wäre also für jeden Codeschnipsel dankbar... |
Re: Icons mit Delphi erstellen
|
Re: Icons mit Delphi erstellen
Danke, für die Antwort :thumb:
Nur leider ein ziemlich langer Code ohne Kommentare :? Aber mal sehen, vielleicht bekomme ich da so langsam den Durckblick :cyclops: Ich dachte halt, irgendjemand aus der DP hätte vielleicht so was schonmal gemacht und könnte mir evtl. ein paar kleine Tipps geben, bin für jede Hilfe dankber :!: |
Re: Icons mit Delphi erstellen
Weiß jemand, wie man eine Farbpalette (4 Bit, 8 Bit) speichern kann (also nur die Palette, ohne Bild) ???
Hab hier Farbpaletten von einem anderen Programm vorliegen (*.dat Dateien), wäre ganz gut wenn ich diese auslesen bzw. wieder speichern könnte... |
Re: Icons mit Delphi erstellen
Hmm....
Also irgendwie muss man doch eine Farbpalette speichern können... vielleicht als TStream ? |
Re: Icons mit Delphi erstellen
Hallo,
Zitat:
![]() Hierfür gibt es die Struktur TLogPalette. Das ist ein Record mit einem dynamischen Array am Ende. Im verlinkten Beitrag steht, wie Du Dir die Palette holen kannst. Danach musst Du nur noch den Record irgendwo speichern (SizeOf(TLogPalette) + (Palettengröße - 1) * SizeOf(TPaletteEntry)). Gruß xaromz |
Re: Icons mit Delphi erstellen
Danke erstmal...
Aber irgendwie ist das etwas zu hoch für mich: Palette laden: :?:
Delphi-Quellcode:
Palette speichern: :?:
{allocate memory for a logical palette}
GetMem(lpPal, SizeOf(TLOGPALETTE) + (255 * SizeOf(TPALETTEENTRY))); {zero it out to be neat} FillChar(lpPal^, SizeOf(TLOGPALETTE) + (255 * SizeOf(TPALETTEENTRY)), #0); {fill in the palette version} lpPal^.palVersion := $300; {grab the system palette entries} lpPal^.palNumEntries := GetSystemPaletteEntries(dc, 0, 256, lpPal^.palPalEntry); if (lpPal^.PalNumEntries <> 0) then {create the palette} bm.Palette := CreatePalette(lpPal^); FreeMem(lpPal, SizeOf(TLOGPALETTE) + (255 * SizeOf(TPALETTEENTRY)));
Delphi-Quellcode:
:wiejetzt: Ja, wo ist denn hier sowas wie FileName oder so???
(SizeOf(TLogPalette) + (Palettengröße - 1) * SizeOf(TPaletteEntry));
Kann mir einer helfen? :arrow: wäre echt nett... |
Re: Icons mit Delphi erstellen
Hallo,
Zitat:
![]() ![]() Zitat:
In diesem Fall hast Du ja eine Palette mit 256 Einträgen. Wenn Du einen Stream hast, dann geht das so:
Delphi-Quellcode:
Ich hoffe, das hilft.
Stream.Write(lpPal^, SizeOf(TLogPalette) + 255 * SizeOf(TPaletteEntry));
Gruß xaromz |
Re: Icons mit Delphi erstellen
Mal gucken, werd mir mal irgendwas daraus basteln...
Ziel soll eben so etwas sein:
Delphi-Quellcode:
procedure LoadPalette(const FileName: String {*.dat}; var Palette: array of TColor);
procedure SavePalette(const FileName: String; const Palette: array of TColor); |
Re: Icons mit Delphi erstellen
Okay, ich glaub ich check's langsam...
Die Palette ist also eine PLogPalette, ein Zeiger auf TLogPalette. 1. Frage: Wie bekomme ich aus TLogPalette ein array[0..255] of TColor ? 2. Frage: In dieser Zeile wird also die Palette geladen:
Delphi-Quellcode:
Es wird allerdings die Systempalette geladen.
lpPal^.palNumEntries :=
GetSystemPaletteEntries(dc, 0, 256, lpPal^.palPalEntry); Wie kann ich hier die Palette aus einem Stream (Datei) laden? GetPaletteEntries... und dann? |
Re: Icons mit Delphi erstellen
Hallo,
Zitat:
Delphi-Quellcode:
var
Farben: array[0..255] of TColor; Palette: TLogPalette; begin for C := 0 to 255 do Farben[C] := RGB(Palette.palPalEntry[C].peRed, Palette.palPalEntry[C].peGreen, Palette.palPalEntry[C].peBlue); Zitat:
![]() ![]() ![]() Gruß xaromz |
Re: Icons mit Delphi erstellen
Liste der Anhänge anzeigen (Anzahl: 1)
So, hab jetzt mal ein bisschen rumgebastelt.
Delphi-Quellcode:
Ich erstelle also eine 8 Bit Farbpalette mit allen Grauwerten.
var
MyArray: array[0..255] of TColor; // Farbpalette als Array lpPal: PLOGPALETTE; // Farbpalette {...} procedure TForm1.FormCreate(Sender: TObject); var i: byte; begin For i:=0 to 255 do MyArray[i] := RGB(i,i,i); // Array mit 256 Grauwerten, also 8 Bit Graustufung end; procedure TForm1.Button1Click(Sender: TObject); var i: byte; begin GetMem(lpPal, SizeOf(TLOGPALETTE) +(255 * SizeOf(TPALETTEENTRY))); FillChar(lpPal^, SizeOf(TLOGPALETTE) +(255 * SizeOf(TPALETTEENTRY)),#0); lpPal^.palVersion := $300; lpPal^.palNumEntries := 256; for i:=0 to 255 do begin // erstelle die Farbpalette aus MyArray lpPal^.palPalEntry[i].peRed := GetRValue(ColorToRGB(MyArray[i])); lpPal^.palPalEntry[i].peGreen:= GetGValue(ColorToRGB(MyArray[i])); lpPal^.palPalEntry[i].peBlue := GetBValue(ColorToRGB(MyArray[i])); end; CreatePalette(lpPal^); FreeMem(lpPal, SizeOf(TLOGPALETTE) +(255 * SizeOf(TPALETTEENTRY))); end; procedure TForm1.Button2Click(Sender: TObject); var STREAM: TStream; begin // Palette in Datei speichern STREAM := TFileStream.Create('C:\test.dat', fmCreate or fmOpenWrite); STREAM.Write(lpPal^, SizeOf(TLOGPALETTE) +(255 * SizeOf(TPALETTEENTRY))); STREAM.Free; end; Wenn ich mir dann die Palette in der fertige Datei anschaue (hab ein Programm, mit dem man Farbpaletten editieren kann, diese werden dann in *.dat Dateien gespeichert), kommt das bei raus: (Bild im Anhang). Merkwürdig sind die ersten 5 Farben, der Rest sieht eigentlich ganz gut aus. Hat jemand eine Idee, woran das liegen könnte? :gruebel: //Edit: Die Dateien vom Programm sind alle 1024 Byte groß, meine Datei ist 1028 Byte groß. Hat das damit evtl. was zu tun? Außerdem ist der letzte Farbwert nicht reines Weiß, sondern einer niederiger: 254, 254, 254 Warum? |
Re: Icons mit Delphi erstellen
Hallo,
Du erstellst in der einen Methode eine Palette und zerstörst diese wieder. In der anderen Methode speicherst Du die Palette, die aber gar nicht mehr existiert. Übrigens legst Du mit CreatePalette ein Paletten-Objekt an, speicherst das Handle aber nicht. Erstens musst Du zum Speichern einer Palette kein Paletten.Objekt erstellen (das brauchst Du nur, wenn Du die Palette für eine Graphik verwenden willst), und zweitens erzeugst Du damit ein Speicherleck. Versuchs mal so:
Delphi-Quellcode:
Zu Deinem Edit:
procedure TForm1.Button1Click(Sender: TObject);
var I: Byte; STREAM: TStream; begin // Speicher anfordern GetMem(lpPal, SizeOf(TLOGPALETTE) +(255 * SizeOf(TPALETTEENTRY))); // Palette füllen lpPal^.palVersion := $300; lpPal^.palNumEntries := 256; for i:=0 to 255 do begin // erstelle die Farbpalette aus MyArray lpPal^.palPalEntry[i].peRed := GetRValue(ColorToRGB(MyArray[i])); lpPal^.palPalEntry[i].peGreen:= GetGValue(ColorToRGB(MyArray[i])); lpPal^.palPalEntry[i].peBlue := GetBValue(ColorToRGB(MyArray[i])); end; // Palette speichern STREAM := TFileStream.Create('C:\test.dat', fmCreate or fmOpenWrite); STREAM.Write(lpPal^, SizeOf(TLOGPALETTE) +(255 * SizeOf(TPALETTEENTRY))); STREAM.Free; // Speicher freigeben FreeMem(lpPal, SizeOf(TLOGPALETTE) +(255 * SizeOf(TPALETTEENTRY))); end; Das Programm möchte anscheinend nur die Palettendaten, Du speicherst aber ja vorne noch Verwaltungsinformationan (Palettenversion...). Speichere doch einfach nur die Paletteneinträge:
Delphi-Quellcode:
Gruß
STREAM.Write(lpPal^.palPalEntry[0], (256 * SizeOf(TPALETTEENTRY)));
xaromz |
Re: Icons mit Delphi erstellen
Danke, super jetzt klappts!!!! :thumb: 1A
Vielen Dank, xaromz !!! So, das war das Speichern einer Palette. Und jetzt drehen wir den Spieß rum: Palette aus Datei in Array laden. Da hast du mir ja schon einiges in Beitrag #11 geschrieben, werd mich jetzt mal dran machen... |
Re: Icons mit Delphi erstellen
Zitat:
Evtl. mit ein wenig Code? Wäre echt super... Ich bekomme es irgendwie nicht gebacken, aus dem TStream in die PLOGPALETTE zu laden... |
Re: Icons mit Delphi erstellen
Irgendwie bekomme ich das Laden der Palette nicht hin.
Verwende jetzt diesen Code: Palette^ ist ein Zeiger auf ein array of TColor
Delphi-Quellcode:
Nach dem Laden ist die Datei merkwürdigerweise immmer leer (0 Byte groß), obwohl ich sie doch nur lese...
procedure LoadPalette;
var i: Byte; Stream: TStream; lpPal: PLogPalette; hPal: HPalette; begin GetMem(lpPal,SizeOf(TLogPalette)+High(Palette^)*SizeOf(TPaletteEntry)); lpPal^.palVersion:=$300; hPal:=CreatePalette(lpPal^); Stream:=TFileStream.Create('C:\test.dat', fmCreate or fmOpenWrite); Stream.Read(lpPal^,Length(Palette^)*SizeOf(TPaletteEntry)); Stream.Free; for i:=0 to High(Palette^) do begin Palette^[i]:=RGB(lpPal^.palPalEntry[i].peRed,lpPal^.palPalEntry[i].peGreen,lpPal^.palPalEntry[i].peBlue); end; FreeMem(lpPal,SizeOf(TLogPalette)+High(Palette^)*SizeOf(TPaletteEntry)); end; Ich verstehe es nicht... Wäre für jede Hilfe dankbar! |
Re: Icons mit Delphi erstellen
Hallo,
jetzt hatte ich einen so schönen Beitrag verfasst, und dann schließ ich Idiot den Browser :wall: . Egal, auf ein Neues: Zitat:
Du liest die Einträge übrigens in eine TLogPalette-Struktur ein, aber Du brauchst ja nur die Einträge. Außerdem erstellst Du mit CreatePalette ein Palettenobjekt, das Du nie verwendest. Und zu guter Letzt solltest Du auch nur so viele Einträge einlesen, wie tatsächlich vorhanden sind. Ich hab die Prozedur mal verbessert und mit Anmerkungen versehen:
Delphi-Quellcode:
Gruß
procedure LoadPalette;
var i: Byte; Stream: TStream; lpPal: PLogPalette; Count: Integer; begin // Stream öffnen Stream := TFileStream.Create('C:\test.dat', fmOpenRead); // Anzahl der Einträge ermitteln Count := Stream.Size div SizeOf(TPaletteEntry); // Speicher reservieren GetMem(lpPal, SizeOf(TLogPalette) + (Count - 1) * SizeOf(TPaletteEntry)); // Palette vorbereiten lpPal^.palVersion := $300; lpPal^.palNumEntries := Count; // Einträge einlesen Stream.Read(lpPal^.palPalEntry[0], Count * SizeOf(TPaletteEntry)); Stream.Free; // Einträge in Array kopieren for i := 0 to Count - 1 do Palette^[i] := RGB(lpPal^.palPalEntry[i].peRed, lpPal^.palPalEntry[i].peGreen, lpPal^.palPalEntry[i].peBlue); FreeMem(lpPal); end; xaromz |
Re: Icons mit Delphi erstellen
Hi xaromz, vielen Dank :thumb: für deinen Code!!!
Ich hab halt vorher noch nie mit Streams und sowas gearbeitet und hatte nicht wirklich viel Ahnung davon. Aber jetzt funzt's, Danke nochmal! Kurze Frage noch: Was macht das eigentlich für einen Unterschied, ob ich schreibe:
Delphi-Quellcode:
oder:
FreeMem(lpPal);
Delphi-Quellcode:
Ist das das gleiche?
FreeMem(lpPal, SizeOf(TLogPalette) + (Count-1) * SizeOf(TPaletteEntry));
Kann ich beim Speichern auch einfach nur FreeMem(lpPal); schreiben? |
Re: Icons mit Delphi erstellen
Hallo,
Zitat:
Gruß xaromz |
Re: Icons mit Delphi erstellen
Danke.
Hab grad was sehr merkwürdiges festgestellt und ich habe keine Ahnung warum das so ist: Irgendwie müssen die Rot- und Blauwerte vertauscht sein. Hab einfach mal ein paar Farben eingetragen und in die Palette gespeichert. Dann mit meinem anderen Programm die Palette angeschaut - und: Aus blau wurde rot und aus rot wurde blau. Das Grün hat immer gestimmt, nur eben Rot und blau war immer vertauscht. Beispiel: Aus der Farbe RGB(64,128,255) im Quellcode wurde RGB(255,128,64) im Programm. Den Fehler zu beheben ist ja sehr einfach, ich frage mich nur woher er kommt... Diese beiden Teile müssten ja dafür verantwortlich sein:
Delphi-Quellcode:
//Speichern:
for i := 0 to High(Palette^) do begin lpPal^.palPalEntry[i].peRed := GetRValue(ColorToRGB(Palette^[i])); lpPal^.palPalEntry[i].peGreen:= GetGValue(ColorToRGB(Palette^[i])); lpPal^.palPalEntry[i].peBlue := GetBValue(ColorToRGB(Palette^[i])); end; //Laden: for i := 0 to Count-1 do Palette^[i] := RGB(lpPal^.palPalEntry[i].peRed, lpPal^.palPalEntry[i].peGreen, lpPal^.palPalEntry[i].peBlue); |
Re: Icons mit Delphi erstellen
Hallo,
Zitat:
Der Mensch verwendet die Reihenfolge RGB. So steht sie vermutlich auch in Deiner Paletten-Datei. Da aber die Speicherverwaltung von PCs etwas anders läuft als beim Menschen, werden die Farben hier so gespeichert (in einem DWORD): ABGR, also Alpha (bzw. Dummy-Byte), Blau, Grün, Rot. Wie Du siehst, ist die Reihenfolge genau anders herum, wie man erwarten würde. Wenn Du Dir den Record TPaletteEntry ansiehst, wirst Du feststellen, dass dort auch die Reihenfolge umgedreht ist. Gruß xaromz |
Re: Icons mit Delphi erstellen
Zitat:
Also wenn ich mir eine Variable vom Typ TPaletteEntry anlege, gebe den Variablenname dann im Quellcode ein und drücke einen Punkt dahinter, dann erscheinen die Einträge aber genau in der Reigenfolge: peRed, peGreen und peBlue - ...nicht umgekehrt :? Übrigens, betreffende Teile im Quellcode geändert:
Delphi-Quellcode:
Also an die Reihenfolge BGR anstatt RGB muss ich mich erst gewöhnen, das hab ich ja sonst noch nie gehört/gelesen.....
//Speichern:
for i := 0 to High(Palette^) do begin lpPal^.palPalEntry[i].peRed := GetBValue(ColorToRGB(Palette^[i])); lpPal^.palPalEntry[i].peGreen:= GetGValue(ColorToRGB(Palette^[i])); lpPal^.palPalEntry[i].peBlue := GetRValue(ColorToRGB(Palette^[i])); end; //Laden: for i := 0 to Count-1 do Palette^[i] := RGB(lpPal^.palPalEntry[i].peBlue, lpPal^.palPalEntry[i].peGreen, lpPal^.palPalEntry[i].peRed); |
Re: Icons mit Delphi erstellen
Hallo,
Zitat:
Gruß xaromz |
Re: Icons mit Delphi erstellen
Zitat:
Da hab ich mich schon immer gewundert, warum das bei TColor umgekehrt ist... da wollt ich nämlich immer den HTML-Farbcode nehmen (ist ja genauso in Hexadezimal, wie TColor) und hab mich gewundert, warum da immer eine andere Frabe raus kam... ----- Zitat:
256 Fraben * (3 Byte pro RBG-Farbe + 1 Byte Alpha pro Farbe) = 1024 Byte !!! Komisch, dabei gibts den Alpha doch nur bei 32 Bit und nicht bei der 8 Bit Farbpalette :gruebel: ? //Edit: Oder kann man am End ein 8 Bit Icon mit Alpha-Channel erstellen????? |
Re: Icons mit Delphi erstellen
Hallo,
Zitat:
Gruß xaromz |
Re: Icons mit Delphi erstellen
Achso...
Also hab ich bei jedem Bild, was keine 32 Bit hat, ein Viertel der Dateigröße nur Datenmüll :zwinker: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:43 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz