Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Wie erstellt man ein transparentes pf32bit-Bitmap? (https://www.delphipraxis.net/177493-wie-erstellt-man-ein-transparentes-pf32bit-bitmap.html)

Keldorn 9. Nov 2013 11:43

Wie erstellt man ein transparentes pf32bit-Bitmap?
 
Hallo,

noch ein Problem, an dem ich mir die Zähne ausbeiße. Wie bekommt ein 32bit-Bitmap wirklich transparent? Ich meine nicht transparent/transparentcolor, das reicht nicht.
(Hintergrund: ich möchte ein 32bit-Alpha-Icon per DrawIconEx skaliert auf ein Bitmap zeichnen und dieses Bitmap mit Transparenz weiterverwenden)

Wenn ich ein Bitmap erstelle
Delphi-Quellcode:
Bmp:=TBitmap.create;
Bmp.Pixelformat:=pf32bit;
BMP.Width:=50;
BMP.height:=50;

DrawIconEx(…);
Canvas.draw(0,0,bmp);
Ist der Hintergrund trotzdem weiß.

Wenn ich das dazwischen setze,
Delphi-Quellcode:
  png:=TPngImage.CreateBlank(COLOR_RGBALPHA,8,bmp.Width,bmp.Height);
  bmp.Assign(png);
Hab ich was ich will. Aber wie bekomme ich das ohne den Umweg über ein PNG hin?

Danke&Gruß Frank

Jens01 9. Nov 2013 12:58

AW: Wie erstellt man ein transparentes pf32bit-Bitmap?
 
TBitmap32

jaenicke 9. Nov 2013 13:11

AW: Wie erstellt man ein transparentes pf32bit-Bitmap?
 
Wobei eine Bitmap dafür eigentlich wenig sinnvoll ist. Muss es denn unbedingt eine Bitmap sein?

Keldorn 9. Nov 2013 13:19

AW: Wie erstellt man ein transparentes pf32bit-Bitmap?
 
Zitat:

Zitat von Jens01 (Beitrag 1235223)

Danke, aber ich wollte das erstmal mit boardmitteln lösen bzw. die ganze Sache auch verstehen ;-).

Zitat:

Zitat von jaenicke (Beitrag 1235224)
Wobei eine Bitmap dafür eigentlich wenig sinnvoll ist. Muss es denn unbedingt eine Bitmap sein?

ja. dient auch der Weiterverarbeitung. Um noch etwas auszuholen: das Icon wird aus einer imagelist geholt. Da würde ich zwar auch schon die Bitmap rausbekommen, aber mit getmbitmap geht die Transparenz genauso flöten. mit Geticon nicht.

Bernhard Geyer 9. Nov 2013 13:38

AW: Wie erstellt man ein transparentes pf32bit-Bitmap?
 
Wenn du nicht unbedingt auf Bordmittel festgelegt bist: In den Elpack-Komponenten (sicherlich auch bei anderen Sammlungen ähnlich) kann man alle Gui-Controls (imageList, ....) mit PNG's arbeiten lassen. Dann sind solche problematischen Workarounds gar nicht mehr nötig.

Namenloser 9. Nov 2013 15:01

AW: Wie erstellt man ein transparentes pf32bit-Bitmap?
 
Zitat:

Zitat von Keldorn (Beitrag 1235228)
Zitat:

Zitat von Jens01 (Beitrag 1235223)

Danke, aber ich wollte das erstmal mit boardmitteln lösen bzw. die ganze Sache auch verstehen ;-).

Ich glaube mit Bordmitteln geht das nicht wirklich, weil das alles noch auf GDI32 aufbaut. Wobei es mich dann allerdings wundert, dass das mit
Delphi-Quellcode:
bmp.Assign(png);
laut deiner Aussage funktioniert. Hast du auch ausprobiert, dass das mit allen Hintergrundfarben funktioniert? Nicht, dass es nur gerade zufällig so aussieht als würde es funktionieren, weil beim Entfernen des Alphakanals zufällig gegen die richtige Farbe geblendet wird... Wenn ich halbtransparente Bilder in MS Paint einfüge, werden die z.B. auch gegen einen virtuellen, schwarzen Hintergrund geblendet.

Also ich würde dir auch zu Graphics32 raten, die Lib ist wirklich gut.

Thom 9. Nov 2013 15:32

AW: Wie erstellt man ein transparentes pf32bit-Bitmap?
 
Zitat:

Zitat von jaenicke (Beitrag 1235224)
Wobei eine Bitmap dafür eigentlich wenig sinnvoll ist. [...]

Zitat:

Zitat von Bernhard Geyer (Beitrag 1235230)
[...] Dann sind solche problematischen Workarounds gar nicht mehr nötig.

Zitat:

Zitat von Namenloser (Beitrag 1235239)
Ich glaube mit Bordmitteln geht das nicht wirklich, weil das alles noch auf GDI32 aufbaut. [...]

Ist schon interessant, wie hartnäckig sich Vorurteile halten... :wink:

Natürlich geht das auch mit TBitmap.
Wichtig ist, daß bei der Erstellung des Bitmaps auch die Eigenschaft AlphaFormat gesetzt wird, damit TBitmap intern die Methode AlphaBlend verwendet. Die zweite Sache ist, daß ein neues Bitmap weiß gefüllt ist und einen Alphawert von $FF für jedes Pixel besitzt. Deshalb muß es vor dem Kopieren eines Icons vollständig gelöscht werden, da sonst das Icon auf den weißen Hintergrund gerendert wird.

Da Du XE2 verwendest, habe ich das mal schnell als Class-Helper programmiert:
Delphi-Quellcode:
type
  TBitmapHelper = class helper for TBitmap
    procedure Clear(Color: TColor; Alpha: Byte);
  end;

procedure TBitmapHelper.Clear(Color: TColor; Alpha: Byte);
type
  TColor32 = packed record
    case Integer of
      0: (B, G, R, A: Byte);
      1: (BGRA: UInt32);
    end;
  TColor32Array = array[0..0] of TColor32;
  PColor32Array = ^TColor32Array;
var
  X, Y: Integer;
  R, G, B: Byte;
  Line: PColor32Array;
begin
  R:=GetRValue(Color);
  G:=GetGValue(Color);
  B:=GetBValue(Color);
  for Y:=0 to Height-1 do
  begin
    Line:=ScanLine[Y];
    for X:=0 to Width-1 do
    begin
      Line[X].R:=R;
      Line[X].G:=G;
      Line[X].B:=B;
      Line[X].A:=Alpha;
    end;
  end;
end;
Damit funktioniert sowohl das Kopieren eines 32Bit Bildes aus einer Image-Liste in das leere Bitmap als auch dessen Ausgabe in eine Paintbox:
Delphi-Quellcode:
procedure TForm1.PaintBox1Paint(Sender: TObject);
var
  Bmp: TBitmap;
begin
  Bmp:=TBitmap.Create;
  try
    Bmp.SetSize(50,50);
    Bmp.PixelFormat:=pf32bit;
    Bmp.AlphaFormat:=afDefined;
    Bmp.Clear(clBlack,0);
    ImageList1.Draw(Bmp.Canvas,0,0,0);
    //PaintBox1.Canvas.Draw(0,0,Bmp);
    PaintBox1.Canvas.StretchDraw(Rect(0,0,100,100),Bmp);
  finally
    Bmp.Free;
  end;
end;

Bernhard Geyer 9. Nov 2013 15:40

AW: Wie erstellt man ein transparentes pf32bit-Bitmap?
 
Zitat:

Zitat von Thom (Beitrag 1235246)
Zitat:

Zitat von Bernhard Geyer (Beitrag 1235230)
[...] Dann sind solche problematischen Workarounds gar nicht mehr nötig.

Ist schon interessant, wie hartnäckig sich Vorurteile halten... :wink:

...

Da Du XE2 verwendest, habe ich das mal schnell als Class-Helper programmiert:

Das was du in einen Helper programmiert hast ist für mich ein Workaround. zwar nicht mehr ganz so unelegant wie früher ohne Helper, aber letztendlich ist es einer.

Also wo ist das Vorurteil?

Thom 9. Nov 2013 15:58

AW: Wie erstellt man ein transparentes pf32bit-Bitmap?
 
Wozu sollte ein komplettes und umfangreiches Framework wie TBitmap32 oder Elpack verwendet werden, wenn das Problem auch mit einer einzigen (!!!) zusätzlichen Methode und integrierten Objekten zu lösen ist? Und weshalb stellt das Löschen eines 32Bit Bitmaps bzw. das Kopieren eines Bildes (Icon/Bitmap) aus einer Image-Liste in ein Bitmap einen "problematischen" Workaround dar? :gruebel:

Mit den Vorurteilen meinte ich die bezüglich der Untauglichkeit von TBitmap in Zusammenhang mit teiltransparenten Bildern. Es funktioniert (zumindest in neueren Delphi-Versionen) - man muß nur wissen, wie. :-D

jaenicke 9. Nov 2013 16:59

AW: Wie erstellt man ein transparentes pf32bit-Bitmap?
 
Zitat:

Zitat von Thom (Beitrag 1235249)
Es funktioniert (zumindest in neueren Delphi-Versionen) - man muß nur wissen, wie. :-D

Es funktioniert, ja, das heißt aber nicht, dass es sinnvoll ist.
Aber wenn es nicht anders geht, bleibt einem ja nichts anderes übrig.

Thom 9. Nov 2013 17:24

AW: Wie erstellt man ein transparentes pf32bit-Bitmap?
 
Wärst Du so nett und würdest Deine Behauptung "es ist nicht sinnvoll" auch mit nachvollziehbaren Argumenten untermauern? :stupid:

EWeiss 9. Nov 2013 17:58

AW: Wie erstellt man ein transparentes pf32bit-Bitmap?
 
Zitat:

Zitat von Thom (Beitrag 1235256)
Wärst Du so nett und würdest Deine Behauptung "es ist nicht sinnvoll" auch mit nachvollziehbaren Argumenten untermauern? :stupid:

Wüßte jetzt auch nicht was da nicht sinnvoll sein soll :thumb:
Alles macht sinn was letztendlich zum erfolg führt in welcher art auch immmer.

gruss

Keldorn 9. Nov 2013 19:40

AW: Wie erstellt man ein transparentes pf32bit-Bitmap?
 
Danke für die vielen Antworten :-)

Zitat:

Zitat von Bernhard Geyer (Beitrag 1235230)
Wenn du nicht unbedingt auf Bordmittel festgelegt bist: In den Elpack-Komponenten (sicherlich auch bei anderen Sammlungen ähnlich) kann man alle Gui-Controls (imageList, ....) mit PNG's arbeiten lassen. Dann sind solche problematischen Workarounds gar nicht mehr nötig.

auch die normale Imagelist nimmt problemlos PNG´s auf. Es muß nur die imagelist.colordepth auf cd32bit stehen. Problem ist halt eher die direkte Weiterverarbeitung
Delphi-Quellcode:
imagelist.getbitmap(...)
geht die Transparenz flöten
Delphi-Quellcode:
imagelist.geticon(...)
bmp.assign(Icon)
ist alles i.O.

Zitat:

Zitat von Namenloser (Beitrag 1235239)
Wobei es mich dann allerdings wundert, dass das mit
Delphi-Quellcode:
bmp.Assign(png);
laut deiner Aussage funktioniert. Hast du auch ausprobiert, dass das mit allen Hintergrundfarben funktioniert? Nicht, dass es nur gerade zufällig so aussieht als würde es funktionieren, weil beim Entfernen des Alphakanals zufällig gegen die richtige Farbe geblendet wird...

Doch, das geht. Andersrum
Delphi-Quellcode:
png.Assign(bmp);
geht es nicht korrekt :(. siehe auch meine Frage hier

@Thom:
Danke, das schaue ich mir genauer an. Das ist das was ich brauche.

Es ist ja auch die Frage, ob manchmal sowas schon versteckt in Delphi integriert ist, sich neuere Delphis anders verhalten oder mehr mitbringen.
Grade so in versteckten Units wie graphutils verbergen sich oftmals nette Sachen und man kommt nie drauf.

Bernhard Geyer 9. Nov 2013 22:31

AW: Wie erstellt man ein transparentes pf32bit-Bitmap?
 
Zitat:

Zitat von Keldorn (Beitrag 1235277)
auch die normale Imagelist nimmt problemlos PNG´s auf. Es muß nur die imagelist.colordepth auf cd32bit stehen.

Meine primäre Delphi-Version noch nicht (sollten doch mal updaten)


Zitat:

Zitat von Keldorn (Beitrag 1235277)
Problem ist halt eher die direkte Weiterverarbeitung
Delphi-Quellcode:
imagelist.getbitmap(...)
geht die Transparenz flöten

Da müsste/sollte Emba noch nachbessern. Vermutlich hat an diese Stelle noch keiner Gedacht.

Medium 10. Nov 2013 00:45

AW: Wie erstellt man ein transparentes pf32bit-Bitmap?
 
Da wohl noch einige Stellen im Zusammenhang mit Delphis TBitmap, und vor allem VCL-Controls und Bitmaps noch aus einer Zeit stammen, als Alpha-Blending nicht drin war (Seitens Windows/GDI), muss man vermutlich bei deren Benutzung - auch wenn es wie gezeigt prinzipiell möglich ist - etwas aufpassen, dass man seinen schönen Alphakanal nicht unterwegs irgendwo doch verliert. Das ist imho ein Vorteil von einer Lib bzw. 3rd Party Komponenten: Viele bringen alles mit was man braucht (bei der G32 ist richtig was los z.B.), und man kommt selten in die Verlegenheit den Nexus der Lib zu verlassen, und somit seltener in die Gefahr unerwarteten Verhaltens.
Ob etwas geht, oder im Handling angenehm ist, ist für mich schon ein nennenswerter Unterschied.

jaenicke 10. Nov 2013 13:01

AW: Wie erstellt man ein transparentes pf32bit-Bitmap?
 
Zitat:

Zitat von Bernhard Geyer (Beitrag 1235288)
Zitat:

Zitat von Keldorn (Beitrag 1235277)
auch die normale Imagelist nimmt problemlos PNG´s auf. Es muß nur die imagelist.colordepth auf cd32bit stehen.

Meine primäre Delphi-Version noch nicht (sollten doch mal updaten)

Dabei wird auch nur die Windows-Imagelist gekapselt. Direkt mit TPNGImage funktioniert die TImageList auch bei XE5 nicht. Deshalb nutze ich normalerweise eine TObjectList<TPicture>.


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:32 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz