![]() |
nach StretchBlt schwarzer Hintergrund
Hallo,
ich nutze zum skalieren von Bitmaps diese Function:
Delphi-Quellcode:
Das Vergrößern/Verkleinern funktioniert wunderbar - nur habe ich immer nach StretchBlt einen scharzen Hintergrund.
procedure Scale_Bitmap(var Bitmap: TBitmap; DestWidth, DestHeight: Integer;
Smooth: Boolean = false); var faktor : Real; Width_Bitmap: Integer; Temp_Bitmap : TBitmap; Copy_Bitmap : TBitmap; begin If Bitmap.Empty then exit; Temp_Bitmap := TBitmap.Create; Copy_Bitmap := TBitmap.Create; Width_Bitmap := Bitmap.Width div Count_Glyphs(Bitmap); If Width_Bitmap > DestWidth then begin faktor := DestWidth / Width_Bitmap; If (Bitmap.Height * faktor) > DestHeight then faktor := DestHeight / Bitmap.Height; end else begin faktor := DestHeight / Bitmap.Height; If (Width_Bitmap * faktor) > DestWidth then faktor := DestWidth / Width_Bitmap; end; try Copy_Bitmap.PixelFormat := pf24Bit; Copy_Bitmap.Assign(Bitmap); Temp_Bitmap.Width := round(Bitmap.Width * faktor); Temp_Bitmap.Height := round(Bitmap.Height * faktor); If Smooth then SetStretchBltMode(Temp_Bitmap.Canvas.Handle, HALFTONE); StretchBlt(Temp_Bitmap.Canvas.Handle, 0, 0, Temp_Bitmap.Width, Temp_Bitmap.Height, Copy_Bitmap.Canvas.Handle, 0, 0, Copy_Bitmap.Width, Copy_Bitmap.Height, SRCCOPY); Bitmap.Assign(Temp_Bitmap); finally FreeAndNil(Temp_Bitmap); FreeAndNil(Copy_Bitmap); end; end; Das Original-Bitmap hat einen transparenten Hintergrund. Ich habe schon versucht, die Transparenz-Properties von Bitmap auf Temp_Bitmap zu übertragen - aber geholfen hat es nichts. Wie bekomm ich nach StrechBlt auch eine Transparenz? Ich habe diesen ![]() |
AW: nach StretchBlt schwarzer Hintergrund
Hast Du schon versucht mit SetStretchBltMode einen anderen Modus zu nehmen?
Statt HALFTONE eventuell COLORONCOLOR. Ich habe gerade noch gesehen, dass Du den Modus nur setzt, wenn Smooth true ist. |
AW: nach StretchBlt schwarzer Hintergrund
Zitat:
Zitat:
|
AW: nach StretchBlt schwarzer Hintergrund
Na, du setzt Pixelformat auf pf24Bit, und wunderst dich dann, dass du keinen Alpha-Kanal mehr hast? Die GDI ist allerdings generell nicht alphakanaltauglich, d.h. auch pf32Bit wird hier keine Besserung bringen.
Was du machen willst ist mit der GDI schlicht nicht möglich. Nimm Graphics32 oder GDI+. |
AW: nach StretchBlt schwarzer Hintergrund
Zitat:
|
AW: nach StretchBlt schwarzer Hintergrund
Googlen, saugen und usen:
Als Objekte werden benötigt: TGPGraphics TGPImage TColorMatrix TGPImageAttributes TGPMatrix Leider habe ich meinen Code, in dem ich das gemacht habe, nicht zur Hand; hoffe das hilft trotzdem. |
AW: nach StretchBlt schwarzer Hintergrund
Oder händisch machen. Wir haben sowas für PNGs im einsatz.
|
AW: nach StretchBlt schwarzer Hintergrund
Könnte auch mit Hilfe eines TPicture-Objektes gehen. Das verwende ich für transparente PNGs, allerdings ohne Manipulationen - nur malen. Wäre ein Experiment wert, ob es auch noch nach Dimensionsänderungen transparent malt.
|
AW: nach StretchBlt schwarzer Hintergrund
ich hab mir jetzt GUI+ von
![]() werd mich jetzt etwas damit auseinander setzen bislang bin ich schon von der automatischen Umwandlung der Bild-Formate begeistert |
AW: nach StretchBlt schwarzer Hintergrund
Werd aber nicht ZU euphorisch, denn GDI+ ist seit ein paar Jahren schon abgekündigt. (Aber wenn mich nicht alles täuscht, ist die zumindest bis Win8.1 dabei, und für Win10 habe ich auch noch nichts gegenteiliges gehört. Ist halt nur nicht mehr garantiert und wird nicht mehr weiter entwickelt.)
|
AW: nach StretchBlt schwarzer Hintergrund
dann besser mit GUI+ gar nicht erst anfangen sondern gleich auf Graphics32 umsteigen?
|
AW: nach StretchBlt schwarzer Hintergrund
Du kannst hier auch die Windows -Alphablend Funktion verwenden, die kann auch 32-Bit Bitmaps skalieren. Allerdings setzt die Funktion voraus, dass die Pixel dann Pre-multiplied sind.
|
AW: nach StretchBlt schwarzer Hintergrund
|
AW: nach StretchBlt schwarzer Hintergrund
ich hab mir jetzt mal Graphics32 angeschaut
hab jetzt aber nur die Möglichkeit gefunden, Bitmaps via TImage32 zu skalieren Gibt es auch eine Möglichkeit das direkt im Bitmap32 zu machen? |
AW: nach StretchBlt schwarzer Hintergrund
Klappt denn dein ursprünglicher Code wenn du Pixelformat auf pf32Bit stellst?
Hab nämlich letztens noch genau das selbe gemacht und das hat funktioniert. |
AW: nach StretchBlt schwarzer Hintergrund
Zitat:
Ich hab alle drei Bitmaps (Bitmap, Temp_Bitmap, Copy_Bitmap) mal testweise auf pf32Bit gesetzt, aber ohne Verbesserung des Problemes [edit] Ich glaub ich weiss wo das Problem ist Der schwarze Hintergrund ist schon im Original-Bitmap vorhanden Das Original-Bitmap beinhaltet ein Icon Test-Code:
Delphi-Quellcode:
Schon origtest.bmp hat den schwarzen Hintergrund
procedure TForm3.Button2Click(Sender: TObject);
var S: String; Bitmap: TBitmap; Icon: TIcon; begin S := ExtractFilePath(Application.ExeName); Bitmap := TBitmap.Create; Icon := TIcon.Create; try // Bitmap.LoadFromFile(S + 't.bmp'); Icon.Handle := ExtractIcon(Application.Handle, PChar(Application.ExeName), 0); Icon.SaveToFile(S + 'test.ico'); Bitmap.Assign(Icon); Bitmap.SaveToFile(S + 'origtest.bmp'); Scale_Bitmap(Bitmap, 100, 200, true); Bitmap.SaveToFile(S + 'test.bmp'); finally Bitmap.Free; Icon.Free; end; end; |
AW: nach StretchBlt schwarzer Hintergrund
Interessanter Artikel:
![]() |
AW: nach StretchBlt schwarzer Hintergrund
Zitat:
ja - ich tendier auch zu GDI+ Aber wie zukunftssicher ist das? |
AW: nach StretchBlt schwarzer Hintergrund
Um das sicher zu erfahren müsstest Du wohl bei Microsoft anfragen.
|
AW: nach StretchBlt schwarzer Hintergrund
Es gibt doch auch seit ein paar Delphi Versionen (Edit: Seit Delphi2010) ein
![]() |
AW: nach StretchBlt schwarzer Hintergrund
Zitat:
Delphi-Quellcode:
[edit]
procedure Scale_Bitmap(var Bitmap: TBitmap; DestWidth, DestHeight: Integer);
var faktor : Real; Width_Bitmap: Integer; D2DCanvas : TDirect2DCanvas; Temp_Bitmap : TBitmap; Rect : TRect; begin If Bitmap.Empty then exit; Temp_Bitmap := TBitmap.Create; Width_Bitmap := Bitmap.Width div 1; //Count_Glyphs(Bitmap); If Width_Bitmap > DestWidth then begin faktor := DestWidth / Width_Bitmap; If (Bitmap.Height * faktor) > DestHeight then faktor := DestHeight / Bitmap.Height; end else begin faktor := DestHeight / Bitmap.Height; If (Width_Bitmap * faktor) > DestWidth then faktor := DestWidth / Width_Bitmap; end; Rect.Left := 0; Rect.Top := 0; Rect.Width := round(Bitmap.Width * faktor); Rect.Height := round(Bitmap.Height * faktor); Temp_Bitmap.Width := Rect.Width; Temp_Bitmap.Height := Rect.Height; D2DCanvas := TDirect2DCanvas.Create(Temp_Bitmap.Canvas, Rect); D2DCanvas.BeginDraw; try D2DCanvas.StretchDraw(Rect, Bitmap); Bitmap.Assign(Temp_Bitmap); finally D2DCanvas.EndDraw; FreeAndNil(D2DCanvas); FreeAndNil(Temp_Bitmap); end; end; Mist - jetzt hab ich anstatt eines schwarzen Hintergrundes einen weissen Hintergrund :-( |
AW: nach StretchBlt schwarzer Hintergrund
Hallo..
Habe mal ne ganz blöde Frage: Seit wann hat ein TBitmap Transparenz? Meines Wissens wird eine Transparenz erst vom TImage erzeugt,indem es eine definierte Farbe (zumeist aus der Ecke des Bitmaps) bei der Visualisierung transparent darstellt, aber mit ist nicht bekannt, das TBitmap überhaupt eine Transparenz hat. Wenn Du Transparenz nutzen willst, musste wohl ein Image-Format wählen, welches das kann, wie z.B. GIF oder PNG.. .. Ein Icon hat Transparenz und beim Assign zu einem TBitmap wird hier eine Füllfarbe verwendet, da TBitmap keins hat, in deinem Beispiel schwarz! |
AW: nach StretchBlt schwarzer Hintergrund
Liste der Anhänge anzeigen (Anzahl: 2)
[QUOTE=Helmi;1291491
Schon origtest.bmp hat den schwarzen Hintergrund[/QUOTE] Du kannst die Beschaffenheit des Icons näher erkunden, indem Du das Icon oder die erzeugte Bitmap einfach mal in ein Grafikprogramm lädst, das Icons oder auch 32-bit-Bitmaps anzeigen kann. Ich habe mal das Icon und das Bitmap in mein Pixpower-Programm geladen und man erkennt, dass z.B. das Standard-Delphi-Icon einen schwarzen Hintergrund hat und bei diesen schwarzen Pixeln aber das Alpha-Pixel auf Null gesetzt ist (vgl. Anlage 1). Daneben sind noch teiltransparente Pixel vorhanden, also wo das Alpha-Pixel einen Wert zwischen 1 und 254 hat. Das gleiche Bitmap wird aber in Programmen, welche keine 32-Bit-Bitmaps (richtig) anzeigen können, mit schwarzem Hintergrund angezeigt, z.B. Die Windows Fotoanzeige (vgl. Anlage 2). Dann weiß Du nämlich schon mal, was am Ende Deiner Bemühungen als richtiges Ergebnis dabei rauskommen soll. |
AW: nach StretchBlt schwarzer Hintergrund
Zitat:
Der "Trick" mit der Ecke des Bitmaps (i.d.R. Bitmaps mit 24-Bit oder weniger) wird (z.B. auch in Delphi) verwendet, um eine bestimmte Farbe transparent erscheinen zu lassen. Damit kann man aber z.B. keine transparenten Verläufe darstellen, sondern nur eben eine Farbe transparent schalten. |
AW: nach StretchBlt schwarzer Hintergrund
Zitat:
Ich muss, glaub ich, noch etwas über das Verarbeiten nach dem Skalieren erzählen Das skalierte Bitmap wird danach in einem StringGrid angezeigt und zwar mittels diesem Code:
Delphi-Quellcode:
Und da bekomm ich immer den Hintergrund mit
StringGrid.Canvas.Draw(Rect.Left, Rect.Top, Bitmap);
[edit] Ich hab jetzt nochmal meinen Ausgangscode modifiziert und hab diese Zeilen eingefügt und eigenartigerweise funktionierts jetzt
Delphi-Quellcode:
Bitmap.TransparentColor := Bitmap.Canvas.Pixels[Bitmap.Width, Bitmap.Height];
Bitmap.Transparent := true; |
AW: nach StretchBlt schwarzer Hintergrund
Zitat:
u.a. von Helmi nur dann funktionieren, wenn A) das QuellBitmap 32Bit hat B) Temp_Bitmap entweder ebenfalls nach dem create auf 32bit gesetzt wird oder von Delphi direkt auf 32bit gesetzt ist.. Wenn ich mich recht entsinne macht Delphi als default nen 24bit, da u.a. ältere Delphi-Versionen mit 32bit garnicht umgehen konnten.. |
AW: nach StretchBlt schwarzer Hintergrund
OK, wenn das Bitmap richtig skaliert wurde und die Transparenz richtig beibehalten wurde, dann sollte die Anzeige damit korrekt möglich sein.
Wahrscheinlich ist Deine Skalierungsmethode noch nicht richtig. Ich habe zwar die Skalierung von 32-Bit Bitmaps in meinem Bildbearbeitungsprogramm integriert, leider kann ich hier keine fertige Lösung posten, da ich für die Skalierung selber verschiedene Methoden verwende und hier ein Mix zwischen eigenen Source-Code und kommerziell erworben Parts besteht. Generell habe ich es so gelöst, dass ich von dem 32-Bit-Bitmap ein 24-Bit Graustufen-Bild (als Hilfsbitmap) aus dem Alpha-Kanal erstelle. Dann wird das 32-Bit auf ein 24-Bit gesetzt und z.B. mit Stretchblt (oder eben anderen Methoden) skaliert. Auch das Graufstufen-Bild wird dann mit der gleichen Methode skaliert. Dann wird das skalierte 24-Bitmap auf 32-Bit gesetzt und der Alpha-Kanal aus dem skalierten Graustufenbild erzeugt. |
AW: nach StretchBlt schwarzer Hintergrund
Zitat:
|
AW: nach StretchBlt schwarzer Hintergrund
Zitat:
Aber ich glaub es muss so lauten:
Delphi-Quellcode:
Bitmap.TransparentColor := Bitmap.Canvas.Pixels[Bitmap.Width - 1, Bitmap.Height - 1];
|
AW: nach StretchBlt schwarzer Hintergrund
Zitat:
Mit dem bloßen Auge kannst Du es der Grafik ja nicht ansehen, da kann z.B. auf einem weißen Hintergrund ein teiltransparentes Schwarz ja wie ein voll sichtbares Grau aussehen. Du musst dann halt kontrollieren, ob einige Pixel im Alpha-Bit einen Wert zwischen 1 und 254 haben (0= Pixel ist unsichtbar bzw. voll transparent, 255= Pixel ist voll sichtbar bzw. hat 100% Deckkraft). |
AW: nach StretchBlt schwarzer Hintergrund
Ich skaliere nur noch mit dem
![]() Beispiel einer proportionalen Skalierung:
Delphi-Quellcode:
Sherlock
procedure ResizeImage(aWICImage: TWICImage; NewWidth:Integer);
var scale: IWICBitmapScaler; wicBitmap: IWICBitmap; newHeight:Integer; faktor:Double; begin if Assigned(aWICImage) then begin faktor := NewWidth / aWICImage.Width; newHeight := Round(aWICImage.Height * faktor); aWICImage.ImagingFactory.CreateBitmapScaler(scale); scale.Initialize(aWICImage.Handle, NewWidth, NewHeight, WICBitmapInterpolationModeFant); aWICImage.ImagingFactory.CreateBitmapFromSourceRect(scale, 0,0,NewWidth, NewHeight, wicBitmap); if Assigned(wicBitmap) then aWICImage.Handle := wicBitmap; end; end; |
AW: nach StretchBlt schwarzer Hintergrund
Zitat:
eine interessante Funktion Ich hab das mal für normale Bitmaps (testweise) umgestrickt:
Delphi-Quellcode:
procedure ResizeImage(Bitmap: TBitmap; NewWidth:Integer);
var WICImage : TWICImage; WICBitmap: IWICBitmap; scale : IWICBitmapScaler; newHeight: Integer; faktor : Double; begin If not Assigned(Bitmap) then exit; WICImage := TWICImage.Create; WICImage.Assign(Bitmap); try faktor := NewWidth / WICImage.Width; newHeight := round(WICImage.Height * faktor); WICImage.ImagingFactory.CreateBitmapScaler(scale); scale.Initialize(WICImage.Handle, NewWidth, NewHeight, WICBitmapInterpolationModeFant); WICImage.ImagingFactory.CreateBitmapFromSourceRect(scale, 0,0,NewWidth, NewHeight, WICBitmap); If Assigned(WICBitmap) then WICImage.Handle := WICBitmap; Bitmap.Assign(WICImage); finally // WICImage.Free; end; end; |
AW: nach StretchBlt schwarzer Hintergrund
Stimmt, das geht auch mit der Windows Imaging Component (WIC), die Transparenz bleibt da erhalten.
Kleiner Wermutstropfen ist dabei, dass WIC unter Windows erst ab Vista standardmäßig im System dabei ist. Für XP muss der Anwender Deines Programms das auf dem System evtl. nachinstallieren (allerdings ab Servicepack xp3 ist es wohl schon dabei). Aber allmählich ist die Unterstützung für XP vielleicht sowieso nicht mehr so wichtig... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:37 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