Autor Beitrag
NTcomputer
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 33

Windows 7 x64
Delphi 2005 PE
BeitragVerfasst: Mi 24.06.09 17:05 
Hallo, ich hab mal wieder ein Problem und keine Ahnung was ich noch machen kann. :wink:

Ich versuche mit den Graphics32-Komponenten mehrere png-Bilder mit Alphatransparenz zusammenzufügen,
aber so richtig klappt das nicht. :x

denn überall dort, wo das obere png halbtransparente Pixel hat, werden die nicht mit dem Hintergrund kombiniert sondern erhalten einen schwarzen Hintergrund (siehe bild..)

Ach ja, die PNGs sind alle in Variablen vom Typ TBitmap32, übrigens aus einer externen dll geladen.

ausblenden volle Höhe Delphi-Quelltext
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:
procedure TForm1.UpdateBackground;
begin
  png:=bgpng;
  blendpng.DrawMode := dmblend;
  blendpng.CombineMode := cmMerge;
  pointpng.DrawMode := dmblend;
  pointpng.CombineMode := cmMerge;
  statuspng.DrawMode := dmblend;
  statuspng.CombineMode := cmMerge;
  statuspng.Width:=Round(status);
  statuspng.DrawTo(png,0,0);
  pointpng.DrawTo(png,Round(status-11),0);
  blendpng.DrawTo(png,0,0);
  UpdateLayer;
end;

procedure TForm1.UpdateLayer;
var
  BlendF: TBlendFunction;
  P:TPoint;
begin
  setWindowLong(Handle, GWL_EXSTYLE,
  getWindowLong(Handle, GWL_EXSTYLE) or WS_EX_LAYERED {or WS_EX_TRANSPARENT});
  // WS_EX_TRANSPARENT macht das Fenster für Mausklicks transparent
  
  BlendF.BlendOp := AC_SRC_OVER;
  BlendF.BlendFlags := 0;
  BlendF.SourceConstantAlpha := 255;
  BlendF.AlphaFormat := AC_SRC_ALPHA;
  P:=Point(0,0);

  UpdateLayeredWindow(Handle, 0, nil, @layersize, png.Handle, @P, 0, @BlendF, ULW_ALPHA);
end;


Hat jemand eine Idee, woran das liegten könnte?
Einloggen, um Attachments anzusehen!
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Fr 26.06.09 11:03 
Bei deiner Blending-Funktion nutzt du den Source_Alpha. Spiel von daher also mal ein wenig mit den Operationen für das Blending rum. Bei OpenGL hab ich da schön öfters recht merkwürdige Effekte beobachtet, dass dort ähnliche Effekte anzutreffen sind. Es kann ggf. auch helfen, den Mischmodus auf Additiv zu setzen. Auch hier könnte etwas Spielen ggf. helfen. Hab Graphics32 grad nicht da, um das genau nachzugucken, wie die das berechnen, von daher kann ich leider nichts Genaues sagen ...

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
NTcomputer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 33

Windows 7 x64
Delphi 2005 PE
BeitragVerfasst: Fr 26.06.09 16:49 
Ich habe die Lösung gefunden.

1. bgpng nicht direkt png zuweisen sondern erst png:=TBitmap32.Create und dann bgpng.DrawTo(png,0,0)

2. aus irgendeinem Grund (vielleicht hat Delphi vorher was vermurkst, beziehungsweise ich, oder Photoshop hat die PNGs direkt so gespeichert) waren die PNG-Kanäle RGB schon mit der Transparenz verrechnet.
Also statt weiß (255/255/255) waren bei z.B. Transparenz A=100 die RGB-Kanäle schon 100/100/100. Folgender Code hilft da weiter, falls noch jemand das PRoblem hat:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
procedure BitmapsVerrechnen;
begin
vorderespng.DrawMode:=dmCustom;
vorderespng.CombineMode:=cmMerge;
vorderespng.OnPixelCombine:=AlphaPixelMerge;
vorderespng.DrawTo(hinterespng,0,0);
end;

procedure AlphaPixelMerge(F: TColor32; var B: TColor32; M: TColor32);
var Faktor:real;
begin
  Faktor := 1 - (TColor32Entry(F).A/255);
  TColor32Entry(B).R := Byte(Round((TColor32Entry(F).R) + (TColor32Entry(B).R * Faktor)));
  TColor32Entry(B).G := Byte(Round((TColor32Entry(F).G) + (TColor32Entry(B).G * Faktor)));
  TColor32Entry(B).B := Byte(Round((TColor32Entry(F).B) + (TColor32Entry(B).B * Faktor)));
end;
Einloggen, um Attachments anzusehen!