Ich muss leider den Thread wieder aussem Grab heraus befördern, weil ich immer noch in dieser Hinsicht Probleme hab. Am besten beschreibe ich mal alles haargenau was ich mache, vielleicht kann man dann besser das Problem nachvollziehen.
Also:
Ich möchte Icons in eine 32bit Bitmap umwandeln und je nachdem ob ich ein neues XP Icon oder ein altes Icon mit 24bit Farbe umwandle, muss ich da anders ran. Jedes Icon hat ja einmal eine BMP, in der die Farbinformationen (und bei XP Icons, der Alphakanal) enthalten ist.
Dann hat das Ding eine Maskierungs BMP, in der (auch bei XP Icons, zwecks Kompatibilitätsgründen schätz ich ma) eine 1bit Maskierung abgespeichert is, die bestimmt welcher Pixel vom Icon durchsichtig is und welcher nicht.
Wenn ich also ein XP Icon umwandeln möchte, dann ist die BMP mit dem Farbinformationen eine 32bit Bitmap, in der auch der Alphakanal drinne ist, sprich ich muss einfach nur diese BMP weiterverwenden und gut ist.
Wenn ich nun aber ein altes Icon umwandle, dann is die BMP mit den Farbinformationen nur max. 24bit, sprich ich muss die BMP mit dem Farbinformationen zu 32bit umwandeln und dort selbstständig den Alphakanal reinspeichern, der sich aus der Maskierungs Bitmap ergibt.
Problem: Ich benutze bei den Bitmaps die Klasse TBitmap. Deren Eigenschaft PixelFormat ist leider vom Typ pfDevice (und nicht pf32bit wie ich erhofft hatte), das bedeutet das das PixelFormat vom jeweiligen anzeigendem Device abhängig ist. Leider sind ALLE Farbbitmaps von Icons, egal ob XP, 24bit oder 256 bzw. 16 Farben, beim PixelFormat vom Typ pfDevice. Sprich ich kann nicht unterscheiden ob ich nen XP Icon habe oder nicht, folglich kann ich nicht entscheiden ob ich die Bitmap mit den Farbinformationen noch bearbeiten muss oder nicht und wenn ich das Ding bearbeite obwohl ichs nicht soll, dann sehen XP Icons ziemlich dämlich aus.
erster Lösungversuch: Über den PixelFormatDescriptor rauskriegen von welchem Typ das Bitmap ist.
Folgender Code:
Delphi-Quellcode:
function IconToBitmap(const IconHandle: HIcon):TBitmap;
var
IcoInfo: TIconInfo;
mask: TBitmap;
x, y: word;
ColorSL, MaskSL: pRGBALine;
pfd: PixelFormatDescriptor;
begin
result := nil;
if NOT GetIconInfo(IconHandle, IcoInfo) then
exit;
try
try
result := TBitmap.Create;
result.Handle := IcoInfo.hbmColor;
mask := TBitmap.Create;
mask.Handle := IcoInfo.hbmMask;
mask.PixelFormat := pf32bit;
DescribePixelFormat(result.Canvas.Handle, 1, sizeof(PixelFormatDescriptor), pfd); // Tiiiiiiiiiiierisch laaaaaaaaaaaaaaahm
if pfd.iPixelType <> PFD_TYPE_RGBA then
begin
result.PixelFormat := pf32bit;
for y := 0 to result.Height-1 do
begin
ColorSL := result.Scanline[y];
MaskSL := mask.ScanLine[y];
for x := 0 to result.Width-1 do
ColorSL^[x].rgbReserved := NOT MaskSL^[x].rgbRed;
end;
end;
except
FreeAndNil(result);
end;
finally
if Assigned(mask) then
mask.Free;
end;
end;
Wie schon im Code am Kommentar ersichtlich, ist die Funktion DescribePixelFormat
saulahm, sprich für ca. 6 Bitmaps braucht mein Rechner 2-3 Sekunden, da das Ganze eigntlich eher so ca. 20 Bitmaps aufeinma abchecken muss, kann das nicht einfach mal 7-10 Sekunden dauern.
Habt ihr noch ne Ahnung was man da machen könnte, was auch einigermaßen schnell ist ?
Danke schon mal im Vorraus
- Thebe