Ik heb een functie gemaakt die van een PNG een icoontje maakt, met een vaste achtergrondkleur. Ja ik weet dat PNG een alpha-channel heeft, maar dat is het probleem nu niet. Ik wil em omzetten in een icoontje dat compatible is met win2000 en lager.
Goed, ik maakt dus twee bitmaps: eentje met de PNG op een achtergrondkleur, en een mask bitmap. Die mask bitmap daarin gaat echt vanalles fout. Ik heb em nu zover dat ie wel een mask pakt, maar toch ook weer niet... zie code:
Die twee BitBlt en DrawIcon functies zijn om te testen, uiteraard.
Wat gebeurt er: hij maakt een icoontje waarvan het stuk dat doorzichtig zou moeten zijn (waar de pixels in de mask op clWhite worden gezet) de pixels juist inversed.
Een ander probleem (dat er hopelijk mee te maken heeft): dit icon aan een imagelist toevoegen zorgt ervoor dat de mask compleet genegeerd wordt en de imagelist gewoon op eigen houtje alleen de kleurbitmap gaat tekenen.
Ik heb al geprobeerd te rommelen met de kleuren van de mask bitmap, maar gewoon transparant krijg ik em niet, alleen maar inversed. ook PixelFormat lijkt weinig uit te maken...
/edit
Ik heb uitgevonden dat de kleurenbitmap op de transparante plekken zwart moet zijn, dus de transparantie werkt nu. Nu nog het laatste probleem, dat de imagelist de transparantie compleet negeert
Goed, ik maakt dus twee bitmaps: eentje met de PNG op een achtergrondkleur, en een mask bitmap. Die mask bitmap daarin gaat echt vanalles fout. Ik heb em nu zover dat ie wel een mask pakt, maar toch ook weer niet... zie code:
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
| function PngToIcon24(Png: TPNGObject; Background: TColor): TIcon; var ColorBitmap, MaskBitmap: TBitmap; X, Y: Integer; AlphaLine: PByteArray; ColorLine: PRGBQuadArray; IconInfo: TIconInfo; begin ColorBitmap := TBitmap.Create; MaskBitmap := TBitmap.Create; try ColorBitmap.Width := Png.Width; ColorBitmap.Height := Png.Height; ColorBitmap.PixelFormat := pfDevice; MaskBitmap.Width := Png.Width; MaskBitmap.Height := Png.Height; MaskBitmap.PixelFormat := pfDevice; //Create a mask bitmap for Y := 0 to Png.Height - 1 do begin AlphaLine := Png.AlphaScanline[Y]; for X := 0 to Png.Width - 1 do if AlphaLine^[X] = 0 then SetPixelV(MaskBitmap.Canvas.Handle, X, Y, clWhite) else SetPixelV(MaskBitmap.Canvas.Handle, X, Y, clBlack) end; BitBlt(GetDC(0), 0, 0, 16, 16, MaskBitmap.Canvas.Handle, 0, 0, SRCCOPY); //Draw the color bitmap ColorBitmap.Canvas.Brush.Color := Background; ColorBitmap.Canvas.FillRect(Rect(0, 0, Png.Width, Png.Height)); Png.Draw(ColorBitmap.Canvas, Rect(0, 0, Png.Width, Png.Height)); BitBlt(GetDC(0), 0, 0, 16, 16, ColorBitmap.Canvas.Handle, 0, 0, SRCCOPY); //Create the icon IconInfo.fIcon := True; IconInfo.hbmColor := ColorBitmap.Handle; IconInfo.hbmMask := MaskBitmap.Handle; Result := TIcon.Create; Result.Handle := CreateIconIndirect(IconInfo); DrawIcon(GetDC(0), 0, 0, Result.Handle); finally ColorBitmap.Free; MaskBitmap.Free; end; end; |
Die twee BitBlt en DrawIcon functies zijn om te testen, uiteraard.
Wat gebeurt er: hij maakt een icoontje waarvan het stuk dat doorzichtig zou moeten zijn (waar de pixels in de mask op clWhite worden gezet) de pixels juist inversed.
Een ander probleem (dat er hopelijk mee te maken heeft): dit icon aan een imagelist toevoegen zorgt ervoor dat de mask compleet genegeerd wordt en de imagelist gewoon op eigen houtje alleen de kleurbitmap gaat tekenen.
Ik heb al geprobeerd te rommelen met de kleuren van de mask bitmap, maar gewoon transparant krijg ik em niet, alleen maar inversed. ook PixelFormat lijkt weinig uit te maken...
/edit
Ik heb uitgevonden dat de kleurenbitmap op de transparante plekken zwart moet zijn, dus de transparantie werkt nu. Nu nog het laatste probleem, dat de imagelist de transparantie compleet negeert
[ Voor 5% gewijzigd door _Thanatos_ op 18-10-2004 23:18 ]
日本!🎌