AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

PNG verschmelzen

Ein Thema von creehawk · begonnen am 9. Jun 2023 · letzter Beitrag vom 22. Jun 2023
 
Renate Schaaf

Registriert seit: 25. Jun 2020
Ort: Lippe
114 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: PNG verschmelzen

  Alt 10. Jun 2023, 18:41
Zitat:
Aber jetzt: Der Stern wird auf dem Icon nur da gezeichnet, wo der Hintergrund NICHT transparent ist..... Vielleicht noch eine Idee?
Dazu muss man erst einen Hintegrund erstellen. Leider kann man nicht einfach ein TPngImage erzeugen und auf dessen Canvas malen. Da braucht man eine TBitmap. Die Alpha-Unterstützung und die Unterstützung der verschiedenen Graphik-Formate ist in Delphi ziemlich hauruck-artig umgesetzt. Will man was machen, was etwas außer der Reihe ist, muss man frickeln. Dein Problem ist ein wunderbares Beispiel dafür.

Hier ist die erste Methode, die aber nicht ganz geht, siehe Kommentare:

Code:
procedure TForm1.btnIconWithStarClick(Sender: TObject);
var
  png: TPngImage;
  bm: TBitmap;
begin
  png := TPngImage.Create;
  try
    // png für die richtige Größe erstellen. Das 128,128 garantiert nicht, dass das
    // png wirklich eine Größe von 128x128 hat. Es wird nur das nächstbeste genommen.
    png.Assign(ImageCollection.GetSourceImage(ImageCollection.GetIndexByName
      ('Icon'), 128, 128));

    // Eine Bitmap für schwarzen Hintergrund machen
    // pf32bit wird für den alpha-channel gebraucht.
    bm := TBitmap.Create;
    try
      bm.PixelFormat := pf32bit;
      bm.SetSize(png.Width, png.height);
      bm.Canvas.Brush.Color := clBlack;
      bm.Canvas.FillRect(Rect(0, 0, bm.Width, bm.height));
      // png per alpha-blend auf den canvas von bm zeichen
      bm.Canvas.Draw(0, 0, png);
      // 'Star' auf bm zeichnen per ImageCollection.Draw
      // Das Rect kann bei Bedarf angepasst werden
      ImageCollection.Draw(bm.Canvas, Rect(0, 2 * bm.height div 3,
        bm.Width div 3, bm.height), 'Star');
      // bm enthält als alpha die durchsichtigen Teile von icon und star kombiniert.
      // Jetzt nur noch dieses alpha anwenden:
      bm.Alphaformat := afDefined;

      // Kombiniertes Bild anzeigen
      Image1.Picture.Graphic := bm;
      // Image1 zeigt jetzt wahrscheinlich die richtige Kombination an.

      // Das folgende geht aber nicht, weil VCL.Graphics nicht das alpha von bm auf png überträgt,
      // sondern die transparente Farbe, wahrscheinlich weil darüber die wenigsten Leute
      // meckern würden. Und wenn man bm erst transparent macht, gibt das immer hässliche Resultate.
      png.Assign(bm);
      // Das kombinierte Bild speichern
      png.SaveToFile('IconWithStar.png');
    finally
      bm.Free;
    end;
  finally
    png.Free;
  end;
end;
Um das Ergebnis nun auch korrekt abzuspeichern, brauchst du nun wirklich ein TWicImage.

Code:
procedure TForm2.btnIconWithStarTheRightWayClick(Sender: TObject);
var
  png: TPngImage;
  bm: TBitmap;
  wic: TWicImage;
begin
  png := TPngImage.Create;
  try
    // png für die richtige Größe erstellen. Das 128,128 garantiert nicht, dass das
    // png wirklich eine Größe von 128x128 hat. Es wird nur das nächstbeste genommen.
    png.Assign(ImageCollection.GetSourceImage(ImageCollection.GetIndexByName
      ('Icon'), 128, 128));

    // Eine Bitmap für schwarzen Hintergrund machen
    // pf32bit wird für den alpha-channel gebraucht.
    bm := TBitmap.Create;
    try
      bm.PixelFormat := pf32bit;
      bm.SetSize(png.Width, png.height);
      bm.Canvas.Brush.Color := clBlack;
      bm.Canvas.FillRect(Rect(0, 0, bm.Width, bm.height));
      // png per alpha-blend auf den canvas von bm zeichen
      bm.Canvas.Draw(0, 0, png);
      // 'Star' auf bm zeichnen per ImageCollection.Draw
      // Das Rect kann bei Bedarf angepasst werden
      ImageCollection.Draw(bm.Canvas, Rect(0, 2 * png.height div 3,
        png.Width div 3, png.height), 'Star');
      // bm enthält als alpha die durchsichtigen Teile von icon und star kombiniert.
      // Jetzt nur noch dieses alpha anwenden:
      bm.Alphaformat := afDefined;

      // Wenn du jetzt die Kombination als png mit dem richtigen Alpha speichern willst,
      // brauchst du ein TWicImage:
      wic := TWicImage.Create;
      try
        wic.Assign(bm);
        wic.ImageFormat := wifPng;
        //Das vorige Bild aus image1 löschen, sonst werden die übereinander gemalt, was dich irritiert hat
        image1.Picture:=nil;
        //kombiniertes Bild anzeigen
        Image1.Picture.Graphic:=wic;
        // Das kombinierte Bild speichern
        wic.SaveToFile('IconWithStar.png');
      finally
        wic.Free;
      end;
    finally
      bm.Free;
    end;
  finally
    png.Free;
  end;
end;
Edit: Jetzt fällt mir auf, dass man png.canvas gar nicht mehr braucht. Kann man also von vornherein mit TWicImage statt TPngImage arbeiten.
Renate

Geändert von Renate Schaaf (10. Jun 2023 um 19:54 Uhr)
  Mit Zitat antworten Zitat
 


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:42 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-2025 by Thomas Breitkreuz