![]() |
Bitmap32 auf ZielBitmap32 malen
Hallo, ich hab hier grad ein Verständnisproblem bei folgendem:
3 PNG's die in drei verschiedene Bitmap32 geladen werden sollen. 1. PNG = linker Bereich (linker Rahmen) 2. PNG = mittlerer Bereich (mittlerer Bereich der Grafik) 3. PNG = rechter Bereich (rechter Rahmen) Grundidee ist folgende, ich würde gerne die 3 PNG's erstmal in 3 Bitmap32 Objekte konvertieren und danach auf eine bestimmte Größe bringen. Das klappt soweit sehr gut mit den Resamplern der Gr32. Jetzt aber kommt das Problem, ich habe jetzt ein ZielBitmap32, in dem ich meine 3 teiligen Bitmap32 Objekte wieder zusammensetzen möchte, also erst den mittleren Bereich drauf zeichen und dann halt den linken sowie rechten Bereich auf das Zielbitmap32. Das Problem ist egal was ich mache das Zielbitmap32 ist / bleibt immer leer?! ich hatte es so versucht:
Delphi-Quellcode:
Könnte mir jemand vielleicht kurz zeigen, wie ich das Zielbitmap32 mit den Teilen aus den 3 Bitmap32 Objekten zu einem zusammensetzen kann?
OutMiddle.Draw(0, OutMiddle.Width, TheBar); // thebar = zielbitmap32; outmiddle = middlepart resampled
Vielen Dank s! |
Re: Bitmap32 auf ZielBitmap32 malen
Setzt du die Größe des Zielbitmaps bevor du darin zeichnest?
|
Re: Bitmap32 auf ZielBitmap32 malen
Und zeichnest Du sicher auf das richtige Bitmap mit den korrekten Koordinaten? Sieht etwas komisch aus.
|
Re: Bitmap32 auf ZielBitmap32 malen
Zitat:
Ok ist gesetzt nun, aber nu hab ich nen schwarzes Rechteck ohne Grafik drin :-( |
Re: Bitmap32 auf ZielBitmap32 malen
Delphi-Quellcode:
Wie DeddyH schon sagte, sehen deine Koordinaten seltsam aus. Warum setzt du einen Wert mit Bezug auf die X-Achse für die Y-Position ein?
OutMiddle.Draw(0, OutMiddle.Width, TheBar); // thebar = zielbitmap32; outmiddle = middlepart resampled
Ich vermute, dass die Zeile in etwa so lauten müsste:
Delphi-Quellcode:
OutMiddle.Draw(OutLeft.Width+1, 0, TheBar);
|
Re: Bitmap32 auf ZielBitmap32 malen
Zitat:
Jo ich glaub ich hab da was durcheinander gewürfelt, gleich wieder da :-) |
Re: Bitmap32 auf ZielBitmap32 malen
Ne also irgendwas läuft hier völlig schief.
Eigentlich sollte es so sein, ClientWidth sagen wir mal beträgt 400, die Grafik "Left" ist 2 px breit und ClientHeight hoch, gleiches gilt für die Grafik Outright... Der Mittlere Bereich der Grafik in Outmiddle muss genau zwischen outleft + outright. Oder aber, eigentlich würde es glaub ich auch reichen erst Outmiddle in den gesamten ClientWidth Bereich zu zeichen und darauf dann outleft + outright, irgendwie klappt das aber nie... Irgendwie ist mir bei Graphics32 unklar wer in welcher Reihenfolge wo was draufmalen muss. Normalerweise würde ich folgerderßen vorgehen: MittlereGrafik.Draw(0,0, Zielgrafik); LinkeGrafik.Draw(0,0, Zielgrafik); RechteGrafik.Draw(399, 0, Zielgrafik); ??? |
Re: Bitmap32 auf ZielBitmap32 malen
Zitat:
Sind alle Teile passgenau, ist die Zeichenreihenfolge egal, ansonsten das zuletzt zeichnen, was "zu oberst" bzw. unverdeckt bleiben soll - alles andere wäre einfach unlogisch. Spezifiziere doch nochmal "irgendwas läuft hier völlig schief". Was siehst du, und zeige doch mal den tatsächlichen Code incl. der Stellen, an denen du die Bitmaps createst, und vor allem auch wie du die Anzeige realisierst. |
Re: Bitmap32 auf ZielBitmap32 malen
Liste der Anhänge anzeigen (Anzahl: 1)
Ok hier erstmal die Idee,
ich wollte mir die sehr komplexe Gradienterstellung sparen, die man benötigen würde um z.B. den Office2007 "orange" Gradient nachzubauen, die M$ benutzt für Selektionen in Menus oder anderen GUI Elementen. Daher dachte ich mir, könnte man ggf. in einem Grafikprogram malen, in 3 Teile unterteilen, also wie gesagt den linken, mittleren und rechten Teil und dann wenn nötig in den Canvas stretchen, z.B. in den Canvas einer Listbox und das dann als Selektionsrahmen benutzen... Damit es relativ gut aussieht, dachte ich mir ich nehm mal PNG's als Ausgangsgrafik bastel mir die in Bitmap32 um damit ich den Resamplingfilter bentuzen kann und gut iss?! Die PNG's im Anhang (die sind so eigentlich auch nicht richtig, normalerweise müßte ich die noch öfter unterteilen, da sonst im mittleren Bereich beim resizen, der Radial Gradient Effekt verloren geht, wäre aber schon froh wenns mal so klappen würde)... Die Unterteilung war generell notwendig, da wenn nicht der runde Randbereich, der eine andere Farbe hat als der mittlere Teil natürlich mit gestreckt würde, was in dem Fall sehr übel aussieht.
Delphi-Quellcode:
Was ich sehe, wenn ich an Outmiddle etwas anders einstelle (Größe verkleinern, sowie Position, damit ich die linke und rechte Grafik neben, den Mittelteil malen kann und nicht drüber, dann sehe ich nur 2 schwarze Ränder) Wenn ich auf dem Mittelteil malen will, sehe ich nur die rechten oder linken Grafik auf den mittleren Bereich aber nie beide!)SelectionLeft := TBitmap32.Create; SelectionMiddle := TBitmap32.Create; SelectionRight := TBitmap32.Create; LoadPNGintoBitmap32(SelectionLeft, ExtractFilePath(ParamStr(0)) + 'left.png', Alpha); LoadPNGintoBitmap32(SelectionMiddle, ExtractFilePath(ParamStr(0)) + 'middle.png', Alpha); LoadPNGintoBitmap32(SelectionRight, ExtractFilePath(ParamStr(0)) + 'right.png', Alpha); OutLeft := TBitmap32.Create; Outleft.Width := 2; Outleft.Height := Listbox1.ItemHeight; OutMiddle := TBitmap32.Create; Outmiddle.Width := Listbox1.ClientWidth; Outmiddle.Height := Listbox1.ItemHeight; OutRight := TBitmap32.Create; OutRight.Width := 2; OutRight.Height := Listbox1.ItemHeight; // rescale srcBitmap32, dstBtimap32, hight, width) RescalePic(SelectionLeft, OutLeft, Listbox1.ItemHeight, 2); RescalePic(SelectionMiddle, OutMiddle, Listbox1.ItemHeight, Listbox1.ClientWidth); RescalePic(SelectionRight, OutRight, Listbox1.ItemHeight, 2); TheBar := TBitmap32.Create; TheBar.Width := Listbox1.ClientWidth; TheBar.Height := Listbox1.ItemHeight; OutMiddle.Draw(0, 0, OutLeft); OutMiddle.Draw(Listbox1.ClientWidth, 0, OutRight); TheBar.Draw(0, 0, OutMiddle); { später wollte ich dann, wenn benötigt TheBar.DrawTo(Listbox1.Canvas.Handle ,Rect.left, Rect.Top); benutzen um die zusammengesetze Grafik anzuzeigen. } |
Re: Bitmap32 auf ZielBitmap32 malen
Ich weiß jetzt nicht, wie das bei TBitmap32 aussieht, aber es sollte doch im Prinzip so gehen:
- Setze Breite der Zielbitmap auf Gesamtbreite der 3 Quellbitmaps und Höhe auf die der höchsten Quellbitmap - Zeichne an Position 0,0 die linke Quellbitmap - Zeichne an Position linke Quellbitmap.Breite, 0 die mittlere - Zeichne an Position Gesamtbreite(linke und mittlere) die rechte - Speichere die Zielbitmap |
Re: Bitmap32 auf ZielBitmap32 malen
Zitat:
// Thebar??? also Zielbitmap? und SourceBitmap ist was in welchem Fall? ich hab ja 3! TheBar.Draw(0,0, SourceBitmap) |
Re: Bitmap32 auf ZielBitmap32 malen
Wenn das Ergebnis anschließend in TheBar sein soll, musst Du auch auf TheBar zeichnen.
|
Re: Bitmap32 auf ZielBitmap32 malen
Zitat:
Delphi-Quellcode:
Geht nich :-(
TheBar.Draw(0, 0, OutLeft);
TheBar.Draw(outleft.Width + Outmiddle.Width, 0, OutRight); TheBar.Draw(0, 0, OutMiddle); |
Re: Bitmap32 auf ZielBitmap32 malen
Was heißt geht nich? Kommt nix oder an der falschen Stelle? Wird bei TBitmap32 Draw direkt aufgerufen oder über Canvas? Anbei mal ein Beispiel mit "normalen" Bitmaps (achte mal auf die Koordinaten beim Zeichnen auf Ziel):
Delphi-Quellcode:
procedure TForm1.FormPaint(Sender: TObject);
var qb1, qb2, qb3, ziel: TBitmap; begin //Erzeugen und Zeichnen der 3 Quellbitmaps qb1 := TBitmap.Create; try qb1.Width := 20; qb1.Height := 40; qb1.Canvas.Brush.Color := clRed; qb1.Canvas.FillRect(Rect(0,0,20,40)); qb2 := TBitmap.Create; try qb2.Width := 20; qb2.Height := 40; qb2.Canvas.Brush.Color := clYellow; qb2.Canvas.FillRect(Rect(0,0,20,40)); qb3 := TBitmap.Create; try qb3.Width := 20; qb3.Height := 40; qb3.Canvas.Brush.Color := clBlue; qb3.Canvas.FillRect(Rect(0,0,20,40)); //Erzeugen und Zeichnen der Zielbitmap ziel := TBitmap.Create; try ziel.Width := 60; ziel.Height := 40; //linke Quellbitmap ziel.Canvas.Draw(0,0,qb1); //mittlere Quellbitmap ziel.Canvas.Draw(qb1.Width,0,qb2); //rechte Quellbitmap ziel.Canvas.Draw((qb1.Width + qb2.Width),0,qb3); self.Canvas.Draw(10,10,ziel); finally ziel.Free; end; finally qb3.Free; end; finally qb2.Free; end; finally qb1.Free; end; end; |
Re: Bitmap32 auf ZielBitmap32 malen
Zitat:
|
Re: Bitmap32 auf ZielBitmap32 malen
Moin, Moin.
Ist vielleicht BitBlt() eine Alternative? Damit können doch die 3 einzelnen Bitmaps ruck-zuck in das Zielbitmap kopiert werden... |
Re: Bitmap32 auf ZielBitmap32 malen
Delphi-Quellcode:
Und so?
TheBar.Width := OutLeft.Width + OutMiddle.Width + OutRight.Width;
TheBar.Draw(0, 0, OutLeft); TheBar.Draw(OutLeft.Width, 0, OutMiddle); TheBar.Draw(outleft.Width + Outmiddle.Width, 0, OutRight); |
Re: Bitmap32 auf ZielBitmap32 malen
Zitat:
Ich würd dir ja gerne das gesamte Project senden zum testen nur du hast kein Graphics32??? |
Re: Bitmap32 auf ZielBitmap32 malen
Zitat:
|
Re: Bitmap32 auf ZielBitmap32 malen
Zitat:
Kannste dir die Graphics32 nicht bei SourceForge holen? ich mein Einbindung dauert ja grad mal 10 - 15 Sekunden, sind ja nur units:-) |
Re: Bitmap32 auf ZielBitmap32 malen
Ich könnte es zu Hause mal versuchen (ca. gegen 18:00).
|
Re: Bitmap32 auf ZielBitmap32 malen
Will ja nicht nerven, aber ist
Zitat:
|
Re: Bitmap32 auf ZielBitmap32 malen
Zitat:
Schick mir einfach ne PM, wenn Du soweit bist ich sende dir dann alles was du brauchst zu! Viele Grüße Marc |
Re: Bitmap32 auf ZielBitmap32 malen
Zitat:
|
Re: Bitmap32 auf ZielBitmap32 malen
BitBlt ignoriert das "Reserwed"-Byte eines Bitmaps welches bei der GR32 als Alphakanal verwenet wird.
Das sind Altlasten der Windowsvorgänger ni nichts mit Transpatenzen zu schaffen haben "wollten".
Delphi-Quellcode:
... was klappt da jetzt nicht ?
procedure TForm1.FormPaint(Sender: TObject);
var qb1, qb2, qb3, ziel: TBitmap32; begin //Erzeugen und Zeichnen der 3 Quellbitmaps qb1 := TBitmap32.Create; try qb1.Width := 20; qb1.Height := 40; qb1.FillRect(0,0,20,40, clRed32); // Oder // DrawTo(Dst: TBitmap32; DstX, DstY: Integer; const SrcRect: TRect); qb2 := TBitmap32.Create; try qb2.Width := 20; qb2.Height := 40; qb2.FillRect(0,0,20,40, clYellow32); qb3 := TBitmap32.Create; try qb3.Width := 20; qb3.Height := 40; qb3.FillRect(0,0,20,40, clBlue32); //Erzeugen und Zeichnen der Zielbitmap ziel := TBitmap32.Create; try ziel.Width := 60; ziel.Height := 40; //linke Quellbitmap ziel.Draw(0,0 ,qb1); //mittlere Quellbitmap ziel.Draw(qb1.Width,0,qb2); //rechte Quellbitmap ziel.Draw((qb1.Width + qb2.Width),0,qb3); ziel.DrawTo(Self.Canvas.Handle, 10, 10); finally ziel.Free; end; finally qb3.Free; end; finally qb2.Free; end; finally qb1.Free; end; end; |
Re: Bitmap32 auf ZielBitmap32 malen
@turboPASCAL: Vielen Dank für den Hinweis!
|
Re: Bitmap32 auf ZielBitmap32 malen
Hallo Turbo :-)
Naja das drawing klappt nun so wie es sollte nuuuuur (links und rechts die grafiken sind nu nicht mehr transparent) *heul Die linke und rechte Grafik dient eigentlich nur dazu um das Rechteck abzurunden, daher haben diese beiden Grafiken oben sowie unten jeweils einen Transparenten Pixel, der nicht zu sehen sein sollte nur das ist er aber, was ziemlich bescheuert aussieht jetzt, da könnte ich mir die linke un d rechte Grafik direkt sparen und nen Rechtangle malen :-( |
Re: Bitmap32 auf ZielBitmap32 malen
Mach ma 'n Bild btte wie es ist und wie es sein soll.
|
Re: Bitmap32 auf ZielBitmap32 malen
Liste der Anhänge anzeigen (Anzahl: 2)
Zitat:
Ich hoffe man kanns erkennen, bei dem "Sonicht" sind man relativ klein diese dunklen Rechtecke. 4 Stück an der Zahl bei Outleft, OutRight. |
Re: Bitmap32 auf ZielBitmap32 malen
Ich gehe mal davon aus, dass die Maske im PNG hinterlegt ist. Probier mal den DrawMode der Bitmaps auf dmBlend zu setzen.
Wenn das nicht hilft, kann mir gut vorstellen, dass der Tranfer des Alphakanals von der PNG Kompo zum Bitmap32 nicht so geht. In dem Fall wäre es praktisch, wenn man die Maske des PNGs als Bitmap bekommen könnte, da man sie dann mit IntensityToAlpha() den jeweiligen Bitmaps zu Fuß eintrichtern kann. Aber ich tippe zunächst mal auf den DrawMode. |
Re: Bitmap32 auf ZielBitmap32 malen
Zitat:
Zitat:
|
Re: Bitmap32 auf ZielBitmap32 malen
Liste der Anhänge anzeigen (Anzahl: 1)
Ich häng mal :-)
Obwohl ich schon mal mit dmBlend sowie Combinemode oder so, mein ich mich zu erinnern, rumgefummelt hab, was auch nicht geholfen hatte, jedenfalls nicht bei mir :-( Viele Grüße Marc |
Re: Bitmap32 auf ZielBitmap32 malen
Es wäre ja interessant zu ergründen, wann dieses Pixel erscheint. Testhalber würde ich zunächst die konvertierten TBitmap32 (vor dem Skalieren) einmal zusammenfügen und als Datei speichern. Kommt es da schon, dürfte es bereits am Konvertieren liegen.
|
Re: Bitmap32 auf ZielBitmap32 malen
Zitat:
In einen anderen Forum sprach jemand von einem ähnlichem Problem ich zitiere mal: Zitat:
Zitat:
|
Re: Bitmap32 auf ZielBitmap32 malen
Zu aller erst: Deine Variable "Alpha" ist nicht initialisiert, wodurch du nicht sicher sein kannst ob du nun das PNG mit oder ohne Alphakanal liest!
Dann sollte der DrawMode des Bitmaps auf dmBlend gesetzt werden, welches als Quelle dient. Also entweder das, das in der Methode Draw() als Parameter benutzt wird, bzw. das dessen Methode DrawTo() aufgerufen wird. Im Zweifel einfach bei allen. Das nächste Problem ist, dass dein Alphakanal durch das Strecken ebenfalls gestreckt wird, und somit "verwischt", so dass du nachher in den Ecken nicht mehr den Aplhawert 0 hast, sondern irgendetwas leicht höheres. Andere Stretchfilter als Mitchell könnten hier stabiliere Ergebnisse liefern, aber du wirst vermutlich immer einen dunklen Schimmer in den Ecken zurück behalten. Und zu guter letzt scheint die G32 beim Zeichnen auf nicht-G32 Canvases den ALphawert nicht korrekt zu berücksichtigen. In dem Fall kann es evtl. helfen den DrawMode dmCustom zu benutzen, und das OnPixelCombine Event selbst zu implementieren. Weil in den Pixeldaten der Bitmaps steht der Alphakanal drin, er wird offenbar nur in diesem Fall nicht beachtet. Aber egal wie du es anstellst, wirst du mit dieser Methode immer Probleme mit dem verwischen des Aplhakanals zu kämpfen haben, ausser du benutzt den NearestNeighbor Filter der nur leider reichlich hässlich ist =) Ich würde dir daher emfehlen den Verlauf incl. des Alphakanals zur Laufzeit in Delphi zu zeichnen, und zwar in genau der gebrauchten Größe. Das musst du ja zudem nur ein einziges Mal machen wenn sich die größe der Listbox Items verändert, und kannst es dann wie jetzt auch aus einem Puffer-Bitmap immer wieder schnell zeichnen. (Dafür muss nur das Problem mit dem Zeichnen mit Alpha gelöst werden (dmCustom).) |
Re: Bitmap32 auf ZielBitmap32 malen
Öhm ja,
da trifft es sich doch wieder extrem gut, dass ich davon 0 in worten null Ahnung hab :-( Kannst Du mir für deine letzten Worte: Zitat:
Viele Grüsse Marc |
Re: Bitmap32 auf ZielBitmap32 malen
Na, Du erstellst Dir eine Bitmap im Speicher und zeichnest darauf. OnPaint zeichnest Du diese Bitmap nun "in einem Rutsch" auf den Zielcanvas. Wenn sich dessen Größe ändert (und das ist auch nur dann notwendig), erstellst Du diese Bitmap in der passenden Größe neu. Dasselbe Prinzip habe ich z.B. bei meinem
![]() |
Re: Bitmap32 auf ZielBitmap32 malen
Zitat:
Abgesehen davon ich hab grad die beiden Ecken nicht gestretched trotzdem das gleiche, es sieht also so aus: Zitat:
Btw. Sagmal dann kennst Du dich doch bestimmt super mit GDI+ aus oder? Wegen deinem runden Button, ich meine ich muss ja nicht Gr32 nehmen? Ginge das nicht auch so, dass man sich über die GDI erstmal sowas wie ein RoundRect baut mit einer bestimmten Rahmanfarbe halt oder man füllt es halt mit entsprechender Farbe, dann lässt man nen Pixel frei, und zeichnet darin dann per GDI+ den Gradient? Viel mir grad so ein weil mich zwingt ja keiner ne Grafik zu nehmen ich dachte nur es wäre vielleicht leichter?! |
Re: Bitmap32 auf ZielBitmap32 malen
Super auskennen wäre nun wirklich zuviel gesagt. Ich würde Dir empfehlen, Dir aus meinem Button-Thread den kompletten Source zu laden, da sind reichlich Beispiele dabei (nicht von mir). Die hatte ich mir auch ausgiebig angesehen und dann mit den Möglichkeiten herumgespielt.
|
Re: Bitmap32 auf ZielBitmap32 malen
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:49 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