Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Bitmap transparent aus TImageList holen (https://www.delphipraxis.net/199882-bitmap-transparent-aus-timagelist-holen.html)

amigage 27. Feb 2019 15:53

Bitmap transparent aus TImageList holen
 
Hallo,

ich bin am Verzweifeln und habe schon einige Stunden im Netz recherchiert, aber keine wirkliche Lösung gefunden, die mein simples Problem löst.

Ich habe eine TImageList, die mit transparenten Bitmaps gefüllt ist. Nun möchte ich ein TImage mit einem Bitmap aus der Imagelist transparent füllen.

Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
var
  IconData : TBitmap;
  TransColor : TColor;
begin
  IconData := TBitmap.Create;

  ImageList1.GetBitmap(1, IconData); // das zweite Image soll angezeigt werden

//  IconData.PixelFormat := pf32Bit;
//  IconData.HandleType := bmDIB;
//  IconData.alphaformat := afDefined;

  IconData.Transparent := true;
  IconData.TransparentColor := clFuchsia;
//  IconData.TransparentMode := tmAuto;

  Image1.Picture.Bitmap := IconData;
end;
Imagelist-Eigentschaften:
BKColor: clFuchsia;
ColorDepth : cd32Bit;
Masked: true;

Und das TImage ist auf Transparent : true gesetzt.

Nichts passiert, egal welche Eigenschaft ich oben aktiviere, die Grafik wird immer mit dem Hintergrund dargestellt, der als BKColor angegeben ist. Außer bei ClNone, da wird der Hintergrund weiß.

Kann mir vielleicht jemand einen Tipp geben?
Besten Dank.

TiGü 27. Feb 2019 15:59

AW: Bitmap transparent aus TImageList holen
 
Auf was ist denn
Delphi-Quellcode:
ImageList1.DrawingStyle
gesetzt?

amigage 27. Feb 2019 16:07

AW: Bitmap transparent aus TImageList holen
 
Delphi-Quellcode:
ImageList1.DrawingStyle
ist auf dsTransparent gesetzt.

Neutral General 27. Feb 2019 16:13

AW: Bitmap transparent aus TImageList holen
 
Probier mal GetImage statt GetBitmap

amigage 27. Feb 2019 17:19

AW: Bitmap transparent aus TImageList holen
 
Wo meinst Du?
TImageList hat keine solche Methode.

peterbelow 28. Feb 2019 11:29

AW: Bitmap transparent aus TImageList holen
 
Zitat:

Zitat von amigage (Beitrag 1426544)
Hallo,

ich bin am Verzweifeln und habe schon einige Stunden im Netz recherchiert, aber keine wirkliche Lösung gefunden, die mein simples Problem löst.

Ich habe eine TImageList, die mit transparenten Bitmaps gefüllt ist. Nun möchte ich ein TImage mit einem Bitmap aus der Imagelist transparent füllen.

Imagelist-Eigentschaften:
BKColor: clFuchsia;
ColorDepth : cd32Bit;
Masked: true;

Und das TImage ist auf Transparent : true gesetzt.

Nichts passiert, egal welche Eigenschaft ich oben aktiviere, die Grafik wird immer mit dem Hintergrund dargestellt, der als BKColor angegeben ist. Außer bei ClNone, da wird der Hintergrund weiß.

Kann mir vielleicht jemand einen Tipp geben?
Besten Dank.

Du gehst das falsch an. Versuch nicht, die Bitmap aus der Imagelist zu holen, erzeuge eine eigene der richtigen Größe, fülle sie mit dem gewünschten Hintergrund, und verwende dann die Draw-Methode der Imagelist um die gewünschte Bitmap aus der Liste auf den Canvas deiner Bitmap zu zeichnen.

EWeiss 28. Feb 2019 11:34

AW: Bitmap transparent aus TImageList holen
 
Zitat:

Versuch nicht, die Bitmap aus der Imagelist zu holen
Was spricht dagegen wenn man wie du angedeutet hast die Bitmaps in der ImageList aktualisiert zur Laufzeit.
Danach sollten alle transparent sein.

Hatten wir schon..

Delphi-Quellcode:
function ImageListToGPBitmap(SourceImageList: TImageList): TGPBitmap;
var
    bmp: TGPBitmap;
    g: TGPGraphics;
    dc: HDC;
    i: Integer;
    x: Integer;

    procedure GdipCheck(Status: Winapi.GDIPAPI.TStatus);
    begin
        if Status <> Ok then
            raise Exception.CreateFmt('%s', [GetStatus(Status)]);
    end;
begin
    //Note: Code is public domain. No attribution required.
    bmp := TGPBitmap.Create(SourceImageList.Width*SourceImageList.Count, SourceImageList.Height);
    GdipCheck(bmp.GetLastStatus);

    g := TGPGraphics.Create(bmp);
    GdipCheck(g.GetLastStatus);

    g.Clear($00000000);
    GdipCheck(g.GetLastStatus);

    dc := g.GetHDC;

    for i := 0 to dmGlobal.imgImages.Count-1 do
    begin
        x := i * dmGlobal.imgImages.Width;

        ImageList_DrawEx(dmGlobal.imgImages.Handle, i, dc,
                        x, 0, dmGlobal.imgImages.Width, dmGlobal.imgImages.Height,
                        CLR_NONE, CLR_DEFAULT,
                        ILD_TRANSPARENT);
    end;
    g.ReleaseHDC(dc);
    g.Free;

    Result := bmp;
end;
Erst dann sind die Bitmaps in der ImageList wirklich Transparent.
Link zur Diskussion

gruss

Sherlock 28. Feb 2019 12:22

AW: Bitmap transparent aus TImageList holen
 
Und wo soll die Bitmap reingeladen werden? Die Unterstützung für transparente Bitmaps, also solche die einen Alphakanal haben, nicht die Trickserei mit irgendwelchen "transparenten" Farben wie clFuchsia, ist IIRC auch in Rio nicht korrekt/vollständig eingebaut. Dafür aber eine wunderbare Unterstützung von PNGs. Ich befülle meine ImageListe mit PNGs und kann die mit einem Einzeiler in ein TImage füllen, transparent.
Delphi-Quellcode:
notesImg.Bitmap := GlobalDataModule.IconList.Bitmap(TSizeF.Create(cSmallImgSize, cSmallImgSize ), ImgIndex);
Sherlock

EWeiss 28. Feb 2019 12:26

AW: Bitmap transparent aus TImageList holen
 
Zitat:

ist IIRC auch in Rio nicht korrekt/vollständig eingebaut.
Traurig genug.
Zitat:

Und wo soll die Bitmap reingeladen werden?
Es wird in der ImageList neu gezeichnet nicht reingeladen. Siehe ImageList_DrawEx
Einmalig beim Start der Anwendung wenn man es denn richtig macht.

gruss

Sherlock 28. Feb 2019 12:37

AW: Bitmap transparent aus TImageList holen
 
Ahja, tut mir Leid, falscher Begriff. Wo soll die Bitmap schlußendlich angezeigt werden? Ein TImage kann auch PNG, und TSpeedButton ebenso. Ich will eigentlich nur sagen: es werden endlich "moderne" Bilddatentypen unterstützt. Warum nicht nutzen?

Sherlock

EWeiss 28. Feb 2019 12:41

AW: Bitmap transparent aus TImageList holen
 
Zitat:

Zitat von Sherlock (Beitrag 1426619)
Ahja, tut mir Leid, falscher Begriff. Wo soll die Bitmap schlußendlich angezeigt werden? Ein TImage kann auch PNG, und TSpeedButton ebenso. Ich will eigentlich nur sagen: es werden endlich "moderne" Bilddatentypen unterstützt. Warum nicht nutzen?

Sherlock

Das Image oder Bitmap wird transparent ins ImageList kopiert (gezeichnet) danach kannst du die ImageList weiterhin auf normalem weg benutzen ohne dazwischen irgend etwas konvertieren zu müssen.
Der einzige unterschied ist halt das dann der Bildstrip (Ist ja nur ein einzelnes Bitmap in der ImageList) transparent ist.

btw. Die beste Methode ist natürlich die ImageList direkt mit dem korrekten Format zu befüllen in dem fall wie du schon sagst *.png
Bin mir nur nicht sicher ob das von der IDE (Resourcen Editor) unterstützt wird.

gruss

Sherlock 28. Feb 2019 13:05

AW: Bitmap transparent aus TImageList holen
 
Zitat:

Zitat von EWeiss (Beitrag 1426620)
btw. Die beste Methode ist natürlich die ImageList direkt mit dem korrekten Format zu befüllen in dem fall wie du schon sagst *.png
Bin mir nur nicht sicher ob das von der IDE (Resourcen Editor) unterstützt wird.

Der Kollege amigage setzt Rio ein, und das unterstützt PNGs in ImageListen.

Sherlock

EWeiss 28. Feb 2019 13:12

AW: Bitmap transparent aus TImageList holen
 
Zitat:

Zitat von Sherlock (Beitrag 1426624)
Zitat:

Zitat von EWeiss (Beitrag 1426620)
btw. Die beste Methode ist natürlich die ImageList direkt mit dem korrekten Format zu befüllen in dem fall wie du schon sagst *.png
Bin mir nur nicht sicher ob das von der IDE (Resourcen Editor) unterstützt wird.

Der Kollege amigage setzt Rio ein, und das unterstützt PNGs in ImageListen.

Sherlock

Ok, dann gebe ich dir recht soll einfach *.png verwenden und gut ist.
Diese alternative sollte aber bei D7 und Delphi Versionen funktionieren wo *.png Nicht mit dem Ressourcen Editor addiert werden können.

gruss

amigage 28. Feb 2019 14:11

AW: Bitmap transparent aus TImageList holen
 
Zitat:

Zitat von peterbelow (Beitrag 1426607)
Versuch nicht, die Bitmap aus der Imagelist zu holen

Muss ich aber, weil ich die die Grafiken eigentlich in einem Listview verwenden will. Das mit dem Button war erst einmal ein Test, die Grafiken generell transparent zu bekommen.

Mein eigentliches Anliegen ist folgendes:
Der Anwender soll als "Customizing" im Programm seine eigenen Symbole auswählen können, die in einem Listview als grafische Unterstützung einer Ordnerstruktur angezeigt werden sollen. Jedem Eintrag soll eine spezielle Grafik zugewiesen werden können.

Die ausgewählten Grafiken werden in einer Imagelist abgelegt und am Ende in einem Stream als Datei gespeichert, mitsamt anderer Daten, die verwendet werden.

Beim nächsten Start soll dieser Stream wieder geladen werden, und die einzelnen Grafiken in der Imagelist eingefügt werden. Anhand des ImageIndex wird die Grafik im Listview angezeigt.

Das funktioniert soweit auch ganz gut, bis auf die Transparenz! Die geht verloren.

Zum Laden verwende ich
Delphi-Quellcode:
TBitmap.CreateFromStream(IconStream);
wobei
Delphi-Quellcode:
IconStream : TMemoryStream;
definiert ist. Und dann übergebe ich die gelesenen Grafiken der Imagelist, wobei
Delphi-Quellcode:
TIconData(IconList[i]).Icon
die Grafik beinhaltet:

Delphi-Quellcode:
for i := 0 to IconList.Count - 1 do
begin
   ii := ImageListLeft32.AddMasked(TIconData(IconList[i]).Icon, clFuchsia);
   ImageListLeft32.Draw(Canvas, 0, 0, ii);
end;
Vielleicht ist mein Ansatz auch grundlegend falsch und ich müsste es anders angehen.
Für einen Tipp wäre ich dankbar.

EWeiss 28. Feb 2019 14:15

AW: Bitmap transparent aus TImageList holen
 
Zitat:

Für einen Tipp wäre ich dankbar.
Habe dir Tips gegeben wenn diese nicht reichen sorry mehr geht nicht!

Du verstehst einfach nicht das in RIO die Bitmaps nicht transparent abgelegt werden das musst du selbst tun.
Wie das geht habe ich gezeigt.

Verstehe nicht was da so schwer ist das umzusetzen.
Ok bin raus ;)

gruss

amigage 28. Feb 2019 14:35

AW: Bitmap transparent aus TImageList holen
 
Sorry @EWeiss. Deinen Sourcecode habe ich nicht wirklich wahrgenommen.
Den werde ich mir natürlich einmal anschauen, denn genau das möchte ich, dass die Grafiken in der Imagelist zur Laufzeit transparent gesetzt werden.

EWeiss 28. Feb 2019 18:51

AW: Bitmap transparent aus TImageList holen
 
Hatte gerade etwas zeit.
In der ImageList befinden sich Bitmaps in 24Bit Format. Ohne Transparenz\Alpha.

gruss

amigage 1. Mär 2019 13:51

AW: Bitmap transparent aus TImageList holen
 
Hallo und danke für den Quellcode.

Leider hilft mir das nicht 100%ig weiter. Wie oben beschrieben, benötige ich die Grafiken in einem Listview, der die Images über den ImageIndex steuert.

In Deinem Beispiel, wird der Inhalt der ImageList in eine BMP und PNG Datei gespeichert, wobei letztere dann in ein TImage geladen wird.

Erstens, wäre die Lösung über einen MemoryStream eleganter, aber eine solche Funktion scheint es wohl nicht in GDI zu geben?
Und wie bringe ich dann die transparente Grafik in den Listview?

EWeiss 1. Mär 2019 13:56

AW: Bitmap transparent aus TImageList holen
 
Zitat:

In Deinem Beispiel, wird der Inhalt der ImageList in eine BMP und PNG Datei gespeichert
Ja um zu dokumentieren das der Inhalt vom ImageList Transparent ist.

Du kannst auf das speichern verzichten und anschließend direkt die Images aus der ImageList laden.
Die sind zu diesen Zeitpunkt Transparent.

Ein bisschen musst du auch selber machen ;)

gruss

amigage 1. Mär 2019 14:25

AW: Bitmap transparent aus TImageList holen
 
Du hast Recht, es funktioniert :thumb:
Also, erst die ImageList transparent setzen lassen und dann ganz normal die Listview füllen.
Jetzt habe ich es verstanden. Sorry, wenn ich dich aufgrund meiner Unwissenheit genervt haben sollte :wink:

EWeiss 1. Mär 2019 14:31

AW: Bitmap transparent aus TImageList holen
 
Zitat:

Zitat von amigage (Beitrag 1426746)
Du hast Recht, es funktioniert :thumb:
Also, erst die ImageList transparent setzen lassen und dann ganz normal die Listview füllen.
Jetzt habe ich es verstanden.

Na da bin ich ja froh! Und hoffe das jetzt alles Transparent ist. :)
Zitat:

Sorry, wenn ich dich aufgrund meiner Unwissenheit genervt haben sollte
Kein Problem.

Zitat:

Erstens, wäre die Lösung über einen MemoryStream eleganter, aber eine solche Funktion scheint es wohl nicht in GDI zu geben?
Du meinst wohl GDI+ und klar gibt es das..

Delphi-Quellcode:
  function TGPBitmap.FromStream(stream: IStream; useEmbeddedColorManagement: BOOL = FALSE): TGPBitmap;
  begin
    result := TGPBitmap.Create(
        stream,
        useEmbeddedColorManagement
    );
  end;
Natürlich musst du dann den Stream vorher erst erstellen!
Informiere dich deshalb mal im INet.
Sorry ist mir jetzt zu viel Aufwand weil ich an meinem eigenen Projekt am Arbeiten bin.

PS:
Was ich dir noch mitgeben kann..
Delphi-Quellcode:
GdipLoadImageFromStream
GdipCreateBitmapFromStream > sollte damit gleichzusetzen sein. TGPBitmap.FromStream
gruss


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:45 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