Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi IconToBitmap mit weißem Hintergrund (https://www.delphipraxis.net/123108-icontobitmap-mit-weissem-hintergrund.html)

qb-tim 27. Okt 2008 20:55


IconToBitmap mit weißem Hintergrund
 
Meine Frage bezieht sich auf diesen Code-Library Eintrag.

Sämtliche Bitmaps, die mit der IconToBitmap Funktion erzeugt werden, haben schwarze Hintergründe. Ich habe versucht einfach alle Pixel mit clBlack in clWhite umzuwandeln. Leider funktioniert das nicht so leicht, da der Hintergrund vom Anwenden des Alpha-Kanals verfärbt wurde. Meine Frage lautet also:

Was muss ich an der Funktion (siehe Link oben) ändern, um Bitmaps mit weißen Hintergründen zu erhalten?

r29d43 29. Okt 2008 17:21

Re: IconToBitmap mit weißem Hintergrund
 
Das was da immer schwarz wird sind diejenigen Pixels, für die weder Rot noch Grün noch Blau einen Wert >0 hat. Ergo sind sie eigentlich auch tatsächlich schwarz. Gleichzeitig sind diese Pixels in einer Ikone gemäß deren bmMask aber für gewöhnlich auch wieder auf transparent geschaltet, werden also sowieso nicht ausgegeben. Sie beim Transfer auf das Bitmap mit clWhite zu laden geht schon, allerdings sollte dann bei der Ausgabe dieses Bitmaps dieser AlphaKanal ignoriert werden (denn da ist ja jetzt als Spezialität dieser Routine auch diese mbMask mit eingearbeitet worden), was aber meistens auch der Fall ist.


Pixels auf clWhite-Landen:

Delphi-Quellcode:
...
for x := 0 to result.Width-1 do
  for y := 0 to result.Height-1 do begin
    pRGBALine(result.Scanline[y])^[x].rgbReserved := NOT pRGBALine(mask.Scanline[y])^[x].rgbRed;
    if pRGBALine(mask.Scanline[y])^[x].rgbRed = 255 then result.Canvas.Pixels[X,Y] := clWhite; // die transparenten Pixels werden im Ziel-Bitmap weiß!
  end;
...
Aufruf und Anzeigen der-Ikone/des-Bitmaps, z.B.:

Delphi-Quellcode:
Image1.Picture.Bitmap := IconToBitmap(Application.Icon.Handle);

Wenn du die Ikone nur auf einem Bitmap anzeigen möchtest, ohne die Icon-bmMask danach wirklich noch zu benötigen, dann könnte man statt der Proc "IconToBitmap" einfacherweise auch die ApiFunktion "DrawIcon" benutzen:

Delphi-Quellcode:
DrawIcon(ABitmap.Canvas.Handle,0,0,Application.Icon.Handle);
Image1.Picture.Bitmap := ABitmap;

qb-tim 29. Okt 2008 18:40

Re: IconToBitmap mit weißem Hintergrund
 
Hmm... :gruebel:

Nun habe ich das Problem, dass bei Stellen mit z.B. 50% Alpha immer noch auf Schwarz angewendet wird. Beispiel: Das MSPaint Icon in XP. Der Schatten des Bechers (Alpha!!!) wird nicht heller, sondern dunkler. Beispiel2: Das QuickTime Icon hat einige Stellen, wo ein niederiger Alpha-wert ist, und bei dem Code oben tauchen störende schwarze Pixel auf.

Was nun :wall:

r29d43 29. Okt 2008 20:09

Re: IconToBitmap mit weißem Hintergrund
 
Ok, bei bmMask-Werten jenseits der 255 (z.B. 240 o. 150 etc.) kann ich den Pixel natürlich nicht so einfach mit clWhite überladen, sondern da müsste wohl ein mathematisches Verfahren her, mit dem eben das entsprechend richtige Vermischungsprodukt zwischen der Vordergrundfarbe und einem Hintergrundweiß herauskommt...

Ein diesbezüglich korrektes optisches Ergebnis bekommst du auf die Schnelle jetzt aber wahrscheinlich nur, wenn du die Ikone mittels dieser DrawIcon-ApiFunktion auf ein anderes vorab weiß gefärbtes Bitmap draufmalst. Und auf dieses so dann entstandene Bitmap könntest du ja dann (wenns denn unbedingt sein muss) nachträglich den Alpha-Kanal immer nochmal zusätzlich rübertransferieren.

Allerdings weiß ich im Moment nicht, ob beim resultierenden Bitmap ein dort dann auch noch rübertransferierte Alpha-Kanal noch irgendeinen besonderen Sinn ergeben würde. Schließlich hast du ja dann die einzelnen Farb-Bytes mit deiner dort eingearbeiteten Hintergrundfarbe schon direkt verfälscht. Diese Hintergrundsfarbe wirst du dann jedenfalls nicht mehr so einfach wieder rauskriegen und z.B. durch eine andere ersetzen können. Das Beste ist wohl, man lässt die ganz aus dem Bitmap draußen und wann immer man das Bitmap dann mal temporär ausgeben möchte, dann sollte man das einfach immer wieder mittels dieser DrawIcon-ApiFunktion anstellen (bzw. mittels einer Funktion, die das gleiche dann mit einem Bitmap+AlphaKanal macht). Viel Aufwand wäre das ja eigentlich auch nie. (Bin in diesen Sachen jetzt aber auch nicht unbedingt so der absolute Profi :-))

qb-tim 30. Okt 2008 18:51

Re: IconToBitmap mit weißem Hintergrund
 
Ich kriege das leider einfach nicht hin :wall: . Bei mir scheitert's einfach an der Programmiererfahrung... :coder2:

Theoretisch müsste man folgendes machen (ein Pixel als Beispiel).

Delphi-Quellcode:
...

var r, g, b: Byte; // Farbwerte ohne Maske
    rr, gg, bb: Byte; // Zu berechnende Farbwerte
    m: Byte; // Maske

...

rr := Round(Abs(1 - m / 256) * r);
gg := Round(Abs(1 - m / 256) * g);
bb := Round(Abs(1 - m / 256) * b);

...

...
Ich weiß aber nicht, wie ich die RGB Werte auslese und sie schnell wieder einsetze... :(

r29d43 30. Okt 2008 19:46

Re: IconToBitmap mit weißem Hintergrund
 
Zitat:

Zitat von qb-tim
Ich weiß aber nicht, wie ich die RGB Werte auslese und sie schnell wieder einsetze... :(

vielleicht auch mal so z.B.?

Delphi-Quellcode:
type
  ColorRec = packed record
    case byte of
     1: (RGBColor : TColor);
     2: (Red,Green,Blue,AKanal : Byte);
  end;

var AColor : ColorRec;
    X,Y : integer;

  .
  .
  .

  for X := 0 to ABitmap.Width - 1 do
    for Y := 0 to ABitmap.Height - 1 do

      with AColor do begin
        RGBColor := ABitmap.Canvas.Pixels[X,Y];

        Red := Red +50;
        Green := Green +100;
        Blue := Blue +150;

        ABitmap.Canvas.Pixels[X,Y] := RGBColor;
      end;

qb-tim 2. Nov 2008 19:51

Re: IconToBitmap mit weißem Hintergrund
 
Ich kann leider auf keinem Weg, den ich mir vorstellen kann, fertigbringen, was ich erreichen will. Hier sind nun mehr Details zu meinem "Problem".

Ich erstelle eingene TMenuItem, die dann in ein PopupMenu übertragen werden. Zu diesen TMenuItem gehören Bitmaps.

Delphi-Quellcode:
var MI: Array of TMenuItem
MI[x].Bitmap := IconToBitmap(...);
PopupMenu1.Items.Add(MI[x]);
Die MenuItems funktionieren, nur die Bitmaps haben, egal, wie ich die Prozedur IconToBitmap verändere, keinen Alpha, nur einen schwarzen Hintergrund, der aber nicht komplett clBlack ist - wahrscheinlich wegen der Verkleinerung...

r29d43 3. Nov 2008 11:33

Re: IconToBitmap mit weißem Hintergrund
 
Diese von dir oben gelinkte IconToBitmap-Routine ist eher bloß eine ganz spezielle Sache, ...mittels der man nämlich bei einem Icon-Transfer auf ein Bitmap auch noch dessen Icon-Mask mit in den Alpha-Kanal dieses Bitmaps mit übertragen kann. Imo benötigst Du hier so etwas aber gar nicht extra. Wenn Du einfach nur die eine oder andere Icon am linken Rand einer PopUp-Menuezeile platzieren möchtest, dann reicht diese oben ebenfalls schon mal kurz erwähnte ApiRoutine "DrawIcon" bzw. "DrawIconEx" auch völlig dazu aus:


Delphi-Quellcode:
// jeweiliger Ausgangspunkt: Ein Bitmap das du mit der clBtnFace-Color füllst
ABitmap.Canvas.Brush.Color := clBtnFace;
ABitmap.Canvas.FillRect(ABitmap.Canvas.ClipRect);

// anschließend: Draufmalen der Icon
DrawIconEx(ABitmap.Canvas.Handle,0,0,Application.Icon.Handle,ABitmap.Width,ABitmap.Height,0,0,DI_NORMAL);

// zum Schluss: Verknüpfen des Bitmaps mit der PopUp-Menuezeile
IconTest1.Bitmap := ABitmap;
klappt perfekt, probier's mal

qb-tim 3. Nov 2008 19:48

Re: IconToBitmap mit weißem Hintergrund
 
Delphi-Quellcode:
function GetIconBitmap(sFile: String; iIndex: Integer): TBitmap;
var ABitmap: TBitmap;
begin
  ABitmap := TBitmap.Create;
  // jeweiliger Ausgangspunkt: Ein Bitmap das du mit der clBtnFace-Color füllst
  ABitmap.Canvas.Brush.Color := clBtnFace;
  ABitmap.Canvas.FillRect(ABitmap.Canvas.ClipRect);
  // anschließend: Draufmalen der Icon
  DrawIconEx(ABitmap.Canvas.Handle,0,0,Application.Icon.Handle,ABitmap.Width,ABitmap.Height,0,0,DI_NORMAL);
  // zum Schluss: Verknüpfen des Bitmaps mit der PopUp-Menuezeile
  Result := ABitmap;
end;
Ich sehe nichts im Menu..... :gruebel:

BTW: Wie lese ich aus der Datei sFile den Icon iIndex aus?

r29d43 4. Nov 2008 08:03

Re: IconToBitmap mit weißem Hintergrund
 
Wenn Du dem Bitmap noch eine Größe gibst, dann sollte es eigentlich klappen, z.B.:

Delphi-Quellcode:
...
ABitmap.width := 32;
ABitmap.height := 32;
ABitmap.PixelFormat := pf24bit; // um auch ggf. alle Farben richtig zu sehen
...
Um mehrere Icons aus einem einzigen Icon-File herauszuholen, würde ich die Api-Funktion Bei Google suchenExtractIconEx benutzen (habe das selbst bisher aber noch nicht gemacht). Irgendwo in der Funktionsbeschreibung wird dann auch deine Frage beantwortet.


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:42 Uhr.
Seite 1 von 2  1 2      

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