Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi ImageList mit Alpha Channel (https://www.delphipraxis.net/105411-imagelist-mit-alpha-channel.html)

HeinBlöd 21. Dez 2007 10:32


ImageList mit Alpha Channel
 
Moin zusammen, ich quäle mich schon seit 10 Stunden mit einem Problem der ImageList von der Windows API rum:

Wie kann ich .ico Files in die Image List laden, und später mit ImageList_Draw die Icons zusammen mit dem Alpha Channel auf ein Canvas malen?

Ich bekomme die Pixel mit halber Transparenz immer in Schwarz angezeigt.

Ich habe schon rausgefunden, dass die ImageList mit ILC_COLOR32 erstellt werden muss. Die Icons lade ich mit ImageList_AddIcon, nachdem ich sie mit ExtractIcon aus der .ico Datei geladen habe.

HeinBlöd 22. Dez 2007 12:51

Re: ImageList mit Alpha Channel
 
Da mir leider niemand geantwortet hat habe ich weiter nach einer Lösung gesucht.

This solution adds an icon with a predefined color count the the ImageList of Windows.

Maybe somebodyelse will implement a solution for TImageList too (since I don't need that I don't do it.)

Delphi-Quellcode:
function ImageList_LoadIcon(const ImageList: HIMAGELIST; const lpicon: LPWSTR; const uFlags: UINT): Integer;
type
  TIcoHeader = packed record
    Reserved: Word;
    FileType: Word;
    Count: Word;
  end;
  TIconHeader = packed record
    Width: Byte;
    Height: Byte;
    ColorCount: Byte;
    Reserved: Byte;
    Planes: Word;
    BitCount: Word;
    Size: DWord;
    FileOffset: DWord;
  end;
var
  IconSize: TPoint;
  FileStream: TFileStream;
  FileHeader: TIcoHeader;
  I: Integer;
  IconHeaderOffset: Int64;
  IconHeaderOffset8Bit: Int64;
  IconHeaderOffsetDefault: Int64;
  IconHeaderOffsetDefault8Bit: Int64;
  IconHeader: TIconHeader;
  IconStream: TMemoryStream;
  Icon: TIcon;
begin
  Result := -1;

  IconHeaderOffset := 0;
  IconHeaderOffset8Bit := 0;
  IconHeaderOffsetDefault := 0;
  IconHeaderOffsetDefault8Bit := 0;

  if (not ImageList_GetIconSize(ImageList, IconSize.X, IconSize.Y)) then
  begin
    IconSize.X := GetSystemMetrics(SM_CXICON);
    IconSize.Y := GetSystemMetrics(SM_CYICON);
  end;

  FileStream := TFileStream.Create(WideString(lpicon), fmShareDenyWrite);

  if (Assigned(FileStream)) then
  begin
    if (FileStream.Read(FileHeader, SizeOf(FileHeader)) = SizeOf(FileHeader)) then
      for I := 0 to FileHeader.Count - 1 do
        if (FileStream.Read(IconHeader, SizeOf(IconHeader)) = SizeOf(IconHeader)) then
        begin
          if ((IconHeader.Width = GetSystemMetrics(SM_CXICON)) and (IconHeader.Height = GetSystemMetrics(SM_CYICON))) then
          begin
            if (IconHeader.BitCount = 8) then
              IconHeaderOffsetDefault8Bit := FileStream.Position - SizeOf(IconHeader);

            if (((uFlags and ILC_COLOR4 = ILC_COLOR4) and (IconHeader.BitCount = 4))
              or ((uFlags and ILC_COLOR8 = ILC_COLOR8) and (IconHeader.BitCount = 8))
              or ((uFlags and ILC_COLOR16 = ILC_COLOR16) and (IconHeader.BitCount = 16))
              or ((uFlags and ILC_COLOR24 = ILC_COLOR24) and (IconHeader.BitCount = 24))
              or ((uFlags and ILC_COLOR32 = ILC_COLOR32) and (IconHeader.BitCount = 32))) then
              IconHeaderOffsetDefault := FileStream.Position - SizeOf(IconHeader);
          end;

          if ((IconHeader.Width = IconSize.X) and (IconHeader.Height = IconSize.Y)) then
          begin
            if (IconHeader.BitCount = 8) then
              IconHeaderOffset8Bit := FileStream.Position - SizeOf(IconHeader);

            if (((uFlags and ILC_COLOR4 = ILC_COLOR4) and (IconHeader.BitCount = 4))
              or ((uFlags and ILC_COLOR8 = ILC_COLOR8) and (IconHeader.BitCount = 8))
              or ((uFlags and ILC_COLOR16 = ILC_COLOR16) and (IconHeader.BitCount = 16))
              or ((uFlags and ILC_COLOR24 = ILC_COLOR24) and (IconHeader.BitCount = 24))
              or ((uFlags and ILC_COLOR32 = ILC_COLOR32) and (IconHeader.BitCount = 32))) then
              IconHeaderOffset := FileStream.Position - SizeOf(IconHeader);
          end;
        end;

    if (IconHeaderOffset = 0) then
      IconHeaderOffset := IconHeaderOffset8Bit;
    if (IconHeaderOffset = 0) then
      IconHeaderOffset := IconHeaderOffsetDefault;
    if (IconHeaderOffset = 0) then
      IconHeaderOffset := IconHeaderOffsetDefault8Bit;

    if (FileStream.Seek(IconHeaderOffset, soBeginning) = IconHeaderOffset) then
    begin
      FileStream.Read(IconHeader, SizeOf(IconHeader));
      FileStream.Seek(IconHeader.FileOffset, soBeginning);

      IconStream := TMemoryStream.Create();

      if (Assigned(IconStream)) then
      begin
        FileHeader.Count := 1;
        IconStream.Write(FileHeader, SizeOf(FileHeader));

        IconHeader.FileOffset := SizeOf(FileHeader) + SizeOf(IconHeader);
        IconStream.Write(IconHeader, SizeOf(IconHeader));

        IconStream.CopyFrom(FileStream, IconHeader.Size);

        Icon := TIcon.Create();
        if (Assigned(Icon)) then
        begin
          IconStream.Seek(0, soBeginning);
          Icon.LoadFromStream(IconStream);

          Result := ImageList_AddIcon(ImageList, Icon.Handle);

          Icon.Free();
        end;

        IconStream.Free();
      end;
    end;

    FileStream.Free();
  end;
end;

HeinBlöd 22. Dez 2007 13:02

Re: ImageList mit Alpha Channel
 
Format description of the .ico files:
http://www.daubnet.com/formats/ICO.html


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:40 Uhr.

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