[delphi] Icoontje in runtime maken, "kleuren" kloppen niet

Pagina: 1
Acties:

  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 15-05 14:44

_Thanatos_

Ja, en kaal

Topicstarter
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:
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 ]

日本!🎌


  • Reptile209
  • Registratie: Juni 2001
  • Laatst online: 18:09

Reptile209

- gers -

Meestal wordt voor de transparantie de pixel op (0,0) gebruikt, of de gestelde achtergrondkleur (in de imagelist, niet per definitie zwart, meestal paars ofzo). Als je dat op jouw bitmap/png toepast, helpt dat dan?

Zo scherp als een voetbal!


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Misschien helpt dit.

[ Voor 4% gewijzigd door LordLarry op 19-10-2004 09:16 ]

We adore chaos because we like to restore order - M.C. Escher