![]() |
PNG verschmelzen
Moin Moin.
Ich habe 1396 teiltransparente PNG Grafiken in der Grösse 128x128. Verschiedentlich möchte ich per Programm unten links einen teiltransparenten Stern 'einbauen', 36x36 gross. Beide Grafiken in ein TImage einlesen, erst die Grafik, dann den Stern, beides aus einer ImageCollection.
Delphi-Quellcode:
Visuell genau das was ich wollte, speichern lässt sich das aber nicht bzw. es kommt nur die an zweiter Stelle geladene Grafik.
Form1.Image1.Picture.Graphic := Form1.ImageCollection.GetSourceImage(Form1.ImageCollection.GetIndexByName('Icon'),128,128);
Form1.Image1.Picture.Graphic := Form1.ImageCollection.GetSourceimage(Form1.ImageCollection.GetIndexByName('Star'),128,128); Also sage ich mal ich muss die beiden verschmelzen. Das geht wahrscheinlich alles anders, tja, aber wie? creehawk |
AW: PNG verschmelzen
Der gezeigte Code soll wirklich genau das machen, was du denkst zu wollen?
Kann ich mir irgendwie nicht vorstellen. Beide Bilder auf ein Canvas eines TBitmaps oder besser eines TPNGImages malen. Oder zuerst das eine Bild rein laden und da dann das Andere drauf/drüber malen. |
AW: PNG verschmelzen
Moin Moin!
Delphi-Quellcode:
Dieser Code ist alles was ich dachte zu brauchen. Und er tut genau das was ich möchte. Ich lade Bild1, ich lade Bild2, eindeutig sind beide zu sehen, speichern kann ich das Bild nicht.
unit Unit1;
interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls, Vcl.Buttons, Vcl.Imaging.pngimage, Vcl.BaseImageCollection, Vcl.ImageCollection; type TForm1 = class(TForm) Image1: TImage; LoadMainImageBtn: TBitBtn; LoadStarImageBtn: TBitBtn; ImageCollection: TImageCollection; SaveImageBtn: TBitBtn; Image2: TImage; procedure LoadMainImageBtnClick(Sender: TObject); procedure LoadStarImageBtnClick(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.LoadStarImageBtnClick(Sender: TObject); begin Form1.Image1.Picture.Graphic := Form1.ImageCollection.GetSourceimage(Form1.ImageCollection.GetIndexByName('Star'),128,128); end; procedure TForm1.LoadMainImageBtnClick(Sender: TObject); begin Form1.Image1.Picture.Graphic := Form1.ImageCollection.GetSourceImage(Form1.ImageCollection.GetIndexByName('Icon'),128,128); end; Okay. Muss ich also anders machen. Bis heute habe ich noch nie eine Grafik via Canvas 'gemalt'. Ich arbeite im Datenbankbereich und habe keinen Schimmer. Wo AUSSER der Hilfe kann man das lernen oder verständlich nachlesen? Google liefert allerlei Ergebniss aber da taucht dann fast jedesmal die Sache mit Bitmap und Transparenz (Alpha Kanal) auf. creehawk |
AW: PNG verschmelzen
emm
Zitat:
Erst ein Bild laden und dann das andere und Du erwartest, das die sich von Zauberhand verbinden? Ok, mal etwas produktiver, Workflow: 1.) Bild 1 laden 2.) Bild 2 laden, aber in ein anderes Image 3.) Bild 2 auf den Canvas von Bild 1 "malen" Kann man sicherlich auch in einem OneLiner machen... aber ich würde vorschlagen, das Schritt für Schritt zu machen. Mavarik :coder: |
AW: PNG verschmelzen
Guck mal, wie weit Du mit diesem Beispiel kommst.
Bitte, benutze nicht die Variable Form1 in Methoden von TForm1. Dein Form kennt sich selber, und könnte u.U. mal einen anderen Namen als Form1 haben.
Code:
"Malen" kann man per TCanvas.Draw oder TImageCollection.Draw oder TGraphic.DrawTo. Vorschlag: Unter Hilfe nachgucken, was das so macht.
uses Vcl.Imaging.pngimage;
procedure TForm1.btnIconWithStarClick(Sender: TObject); var png: TPngImage; begin png := TPngImage.Create; try //Erstmal ein gültiges TPngImage erstellen png.Assign(ImageCollection.GetSourceImage(ImageCollection.GetIndexByName ('Icon'), 128, 128)); //'Star' auf 'Icon' malen per ImageCollection.Draw //Das Rect kann bei Bedarf verkleinert werden ImageCollection.Draw(png.Canvas, Rect(0, 0, png.Width, png.height), 'Star'); //Kombiniertes Bild anzeigen Image1.Picture.Graphic := png; //Das kombinierte Bild speichern png.SaveToFile('IconWithStar.png'); //ImageCollection.Add('IconWithStar', 'IconWithStar.png'); finally png.Free; end; Renate |
AW: PNG verschmelzen
@ Renate Schaaf
Nachdem ich rausgefunden hatte das die ImageCollection mit TWICImage arbeitet habe ich das so gemacht:
Delphi-Quellcode:
Perfect! Ich danke vielmals für den richtigen Schubs in die richtige Richtung.
procedure TForm1.TestBtnClick(Sender: TObject);
var Png1: TWicImage; Png2: TPngImage; begin Png1 := TWicImage.Create; Png2 := TPngImage.Create; try png1.Assign(ImageCollection.GetSourceImage(ImageCollection.GetIndexByName('Icon'), 128, 128)); Png1.SaveToFile('Icon.png'); Png2.LoadFromFile('Icon.png'); ImageCollection.Draw(png2.Canvas, Rect(0, 0,128,128), 'Star'); Image1.Picture.Graphic := png2; Image1.picture.Graphic.SaveToFile('IconWithStar.png'); finally png1.Free; png2.Free; end; end; Aber jetzt: Der Stern wird auf dem Icon nur da gezeichnet, wo der Hintergrund NICHT transparent ist..... Vielleicht noch eine Idee? @mavarik Echt jetzt !!!! Habe ich gedacht! :-D Wie bei anderen Grafikprogrammen auch! Bild1 laden, Bild2 laden und ... und generös darüber hinwegsehen, das man auch da das Bild2 kopieren muss und in Bild1 einfügt, also "malt"... Auf dem Bildschirm sieht es jedenfalls genau richtig aus. creehawk |
AW: PNG verschmelzen
Zitat:
Hier ist die erste Methode, die aber nicht ganz geht, siehe Kommentare:
Code:
Um das Ergebnis nun auch korrekt abzuspeichern, brauchst du nun wirklich ein TWicImage.
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;
Code:
Edit: Jetzt fällt mir auf, dass man png.canvas gar nicht mehr braucht. Kann man also von vornherein mit TWicImage statt TPngImage arbeiten.
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; |
AW: PNG verschmelzen
Sorry, ich bin's schon wieder.
So geht es am kürzesten und besten, finde ich:
Code:
So, jetzt hast du 3 Versionen zur Auswahl :).
procedure TForm1.btnIconWithStarTheRightWayClick(Sender: TObject);
var bm: TBitmap; wic: TWicImage; begin wic := TWicImage.Create; try wic.Assign(ImageCollection.GetSourceImage(ImageCollection.GetIndexByName ('Icon'), 128, 128)); bm := TBitmap.Create; try //Durch assign ist automatisch bm.pixelformat=pf32bit und bm.Alphaformat=afDefined bm.Assign(wic); ImageCollection.Draw(bm.Canvas, Rect(0, 2 * wic.height div 3, wic.Width div 3, wic.height), 'Star'); wic.Assign(bm); wic.ImageFormat := wifPng; Image1.Picture := nil; Image1.Picture.Graphic := wic; wic.SaveToFile('IconWithStar.png'); finally bm.Free; end; finally wic.Free; end; end; |
AW: PNG verschmelzen
Moin Moin!
zuerst mal sagenhaften vielfältigen Dank. :thumb: Ich hatte bis gestern abend auch schon ein paar Dinge enträtseln können, bin dann aber am Alphaformat=afDefined hängengeblieben. Die Zeile mit
Delphi-Quellcode:
habe ich noch umgeändert in
ImageCollection.Draw(bm.Canvas, Rect(0, 2 * wic.height div 3,wic.Width div 3, wic.height), 'Star');
Delphi-Quellcode:
damit der Stern etwas größer wird.
ImageCollection.Draw(bm.Canvas, Rect(0, 0, wic.height,wic.Width), 'Star');
Nochmal: Vielen herzlichen Dank für deine Hilfe oder eigentlich schon fürs mitprogrammieren - und dann noch mitten in der Nacht wie ich eben sehe! Hut ab! creehawk |
AW: PNG verschmelzen
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:12 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