![]() |
Konvertieren eines TBitmap zu einem TPngImage tut später komische Dinge
Szenario: Ich habe eine
Delphi-Quellcode:
-Komponente auf ein Formular geworfen. Es ist ein Png-Bild. Da das Standard-Resizen eines
TImage
Delphi-Quellcode:
ziemlich hässlich aussieht wollte ich es noch einmal schöner berechnen wenn der Benutzer mit dem Resizing aufgehört hat.
TImage
Das tue ich: (Lokale Objekte zerstören habe ich weggelassen)
Delphi-Quellcode:
Im Klartext:
uses GraphUtil;
// originalImage ist ein TPngImage was das hochaufgelöste Bild enthält // imageComponent ist die TImage-Komponente auf dem Formular procedure TFrame6.smoothScaledImage(const imageComponent: TImage); var originalBitmap: TBitmap; // Bitmap copy von originalImage (TPngImage) resultingBitmap: TBitmap; // Bitmap-Ergebnis von GrpahUtils.ScaleImage pngImage: TPngImage; // PNG-Konvertierung von resultingBitmap scaleAmount: Double; begin originalBitmap := TBitmap.Create(); originalBitmap.SetSize(originalImage.Width, originalImage.Height); originalBitmap.Canvas.Draw(0, 0, originalImage); resultingBitmap := TBitmap.Create(); resultingBitmap.SetSize(imageComponent.Width, imageComponent.Height); resultingBitmap.Transparent := True; // Das hier ist böse if imageComponent.Height < imageComponent.Width then scaleAmount := imageComponent.Height / originalImage.Height else scaleAmount := imageComponent.Width / originalImage.Width; GraphUtil.ScaleImage(originalBitmap, resultingBitmap, scaleAmount); pngImage := TPngImage.Create(); pngImage.Assign(resultingBitmap); imageComponent.Picture.Assign(pngImage); end;
Nun das Problem: Die Zeile
Delphi-Quellcode:
sorgt dafür dass später das konvertierte PNG-Bild auf dem Formular flackert wie Bolle. Auch das Skalieren sieht stellenweise extrem komisch aus.
resultingBitmap.Transparent := True;
Kann jemand erkennen, warum das so ist? Irgendwas ist mit dem erzeugten PNG-Bild falsch. Würde ein eingestelltes Beispielprojekt helfen? |
AW: Konvertieren eines TBitmap zu einem TPngImage tut später komische Dinge
Du könntest alternativ mal die Funktion
Delphi-Quellcode:
aus der Unit
ConvertToPNG
Delphi-Quellcode:
der
PngFunctions
![]()
Delphi-Quellcode:
. Ob das allerdings besser ist bzw. dein Problem löst, kann ich nicht sagen.
TPngImage.Assign
|
AW: Konvertieren eines TBitmap zu einem TPngImage tut später komische Dinge
Mir ist Dein "transparentes Bitmap" aufgestoßen. Meines Wissens gibt es so etwas doch gar nicht. Um die Transparenz zu simulieren wurde bei meinen Delphis immer ein bestimmtes Pixel (oben links?) genommen und dessen Farbe wurde dann zum Berechnen der Transparenz benutzt. Wenn Du das Bild skalierst werden diverse Mischfarben erzeugt. In der Folge sind dann die "transparenten" Pixel zumeist wild über das Bild verstreut. Um eine echte Transparenz zu erzeugen braucht man ein Bild das eine entsprechende Maske enthält (wie z.B. Icons) oder eine wirklich eindeutige Transparenz-Farbe.
|
AW: Konvertieren eines TBitmap zu einem TPngImage tut später komische Dinge
Das Transparenzpixel ist links unten.
Und auch beim Skalieren kann man die Semitransparenz des PNG erhalten. Unter ![]() |
AW: Konvertieren eines TBitmap zu einem TPngImage tut später komische Dinge
Unter Windows? Bleib bei dem PNG, schreib es in ein TWICImage und skaliere das.
![]() Sherlock |
AW: Konvertieren eines TBitmap zu einem TPngImage tut später komische Dinge
Mit dem TWicImage hatte ich es schon versucht, war aber zu dumm dafür. Deine flapsige Antwort ließ es so trivial klingen dass ich es nochmal versuchen musste. Und ich glaube, jetzt habe ich's:
:bounce1:
Delphi-Quellcode:
Das sieht gut aus und flackert nicht. Vielen Dank für die Hilfe und den seelischen Beistand.
uses Winapi.Wincodec;
procedure TForm5.recalcImageNew(); const interpolationMode: WICBitmapInterpolationMode = WICBitmapInterpolationModeFant; var wicImage: TWICImage; bitmapScaler: IWicBitmapScaler; aspectRatio: Double; newSize: TPoint; begin wicImage := TWICImage.Create(); wicImage.ImageFormat := TWICImageFormat.wifPng; wicImage.LoadFromFile('Zeichnung1.png'); aspectRatio := 1.0; if image1.Width < image1.Height then aspectRatio := image1.Width / wicImage.Width else aspectRatio := image1.Height / wicImage.Height; newSize.X := Round( wicImage.Width * aspectRatio); newSize.Y := Round( wicImage.Height * aspectRatio); wicImage.ImagingFactory.CreateBitmapScaler(bitmapScaler); bitmapScaler.Initialize(wicImage.Handle, newSize.X, newSize.Y, interpolationMode); wicImage.Handle := IWICBitmap(bitmapScaler); image1.Picture.Assign(wicImage); end; Warum aber der obige Quellcode so merkwürdige Ergebnisse produziert habe ich nicht im geringsten verstanden :gruebel: |
AW: Konvertieren eines TBitmap zu einem TPngImage tut später komische Dinge
Ich weiss doch, daß man Dir nicht mit Details kommen muss ;)
Ich habs so gemacht (proportionalies Resize):
Delphi-Quellcode:
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; Wie Du siehst, weitgehend gleich. Sherlock |
AW: Konvertieren eines TBitmap zu einem TPngImage tut später komische Dinge
Zitat:
Delphi-Quellcode:
32-Bit-Bitmaps anzeigen (TPicture.Assign() oder TPicture.Bitmap zuweisen) glättet gegen weiß und tut andere seltsame Dinge. Also nur benutzen, um sie in TImageList zu packen.
function PNGToBMP(PNG: TPngImage; Free: Boolean = False): Graphics.TBitmap;
var i, j: Integer; begin Result := Graphics.TBitmap.Create; Result.Assign(PNG); if PNG.Header.ColorType = COLOR_RGBALPHA then for i := 0 to PNG.Height - 1 do for j := 0 to PNG.Width - 1 do begin TByteArray(Result.ScanLine[i]^)[j*4] := TByteArray(PNG.Scanline[i]^)[j*3]; TByteArray(Result.ScanLine[i]^)[j*4+1] := TByteArray(PNG.Scanline[i]^)[j*3+1]; TByteArray(Result.ScanLine[i]^)[j*4+2] := TByteArray(PNG.Scanline[i]^)[j*3+2]; end; if Free then PNG.Free; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:33 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