![]() |
Bild Qualität nach der Rotation Problem
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo
ich versuche ein Bild zu rotieren ohne viel Verlust der Qualität Ich habe diese Funktion verwendet : ![]() Wenn der Winkel 90, 180, 270 dann sieht man das Problem natürlich nicht sondern nur wenn man einen beliebigen Winkel für die Rotation nehmt z.B. 45° oder 33° Ich weiß jetzt nicht ob es an die Funktion liegt oder an eine andere Sache ! Wenn ich aber das selbe Bild mit einem anderen Programm rotiere dann wird das Bild nicht schlecht (sehe Anhang) |
Re: Bild Qualität nach der Rotation Problem
Es kommt natürlich auf den Dreh-Algorithmus an.
|
Re: Bild Qualität nach der Rotation Problem
Mein
![]() Ansonsten kannst das ja auch mal selbst implementieren, so schwer ist das nicht. |
Re: Bild Qualität nach der Rotation Problem
Die beste Qualität würdest du beim Wandeln in eine Vektorgrafik erhalten
|
Re: Bild Qualität nach der Rotation Problem
Zitat:
Was aber mir bei deinem Demo gut finde, bei der Rotation wird die Maße des canvas optimal angepasst Zitat:
Die Funktion rotiert aber das Bild nur wenn es eine Bitmap ist Jemand empfehlt mir PlgBlt zu verwenden, habe ich leider keine Ahnung wie es damit geht, mehr davon : ![]() _ |
Re: Bild Qualität nach der Rotation Problem
Das Problem das du hast ist ja die Mangelnde Kantenglättung.
Gehe her und mache das Bild vorm Drehen doppelt so groß mittels Stretchdraw, dann drehe und verkleinere es wieder. Das müste helfen. Reicht das nicht gehe über immer größere zwischenbilder.. |
Re: Bild Qualität nach der Rotation Problem
Mein Tipp lautet auch hier wieder Graphics32 :zwinker:
|
Re: Bild Qualität nach der Rotation Problem
Und wenn es dennoch Eigenbau sein soll: Es lohnt sich hier die Drehung so zu bauen, dass du nicht das Ausgangsbild vorwärts transformiertst, sondern die Rücktransformation nimmst, und Pixel im Zielbild auf Float-Pixel im Original abbildest. Wenn du dann nicht stumpf rundest, sondern einen interpolierten Farbwert aus den vier betroffenen des Originals nimmst (
![]() |
Re: Bild Qualität nach der Rotation Problem
Sieht ganz ordentlich aus:
![]() |
Re: Bild Qualität nach der Rotation Problem
Liste der Anhänge anzeigen (Anzahl: 2)
Ja, das von der französischen Seite sieht ganz gut aus. Was mit GDI so alles geht...
Ich hab' auch mal eben schnell was geschrieben, aber auf so eine einfache Lösung bin ich nicht gekommen. Allerdings habe ich es endlich mal mit linearer Interpolation anstatt immer nur mit "Nearest neighbour" umgesetzt. Das wollte ich eh schon immer mal machen. Falls es jemand interessiert (Aber nur für 24bit Bilder!):
Delphi-Quellcode:
Eine Gegenüberstellung kann man sich mit dem Demo-Projekt im Anhang verschaffen.
PROCEDURE RotateImage24LinearInterpolation(SourceBMP, DestBMP: TBitmap; Degree: double; BackCol : TColor);
TYPE TByteArray = ARRAY[0..655360] OF byte; pByteArray = ^TByteArray; VAR X, Y, iX : integer; RX, RY : integer; dRX, dRY : double; SCX, SCY : integer; DCX, DCY : integer; W, H : integer; // Width and Height of Source Bitmap s, c : extended; fX, fY, d: double; pDest : pByteArray; pSource : ARRAY OF pByteArray; RGBBack : integer; c11, c12, c13, c21, c22, c23 : double; BEGIN IF Degree = 0 then begin DestBMP.Assign(SourceBMP); EXIT; end; IF SourceBMP.PixelFormat <> pf24bit then exit; RGBBack := BackCol; // Now switch Blue and Red RGBBack := ((RGBBack and $00FF0000) shr 16) or ((RGBBack and $0000FF00) ) or ((RGBBack and $000000FF) ) shl 16; W := SourceBMP.Width; H := SourceBMP.Height; SCX := W div 2; SCY := H div 2; SinCos(Degree*Pi/180, s, c); // Calculate new size for Destinatio image DestBMP.PixelFormat := pf24bit; DestBMP.Height := round(Abs(c * H) + Abs(s * W)); DestBMP.Width := round(Abs(s * H) + Abs(c * W)); DCX := DestBMP.Width div 2; DCY := DestBMP.Height div 2; SetLength(pSource, H); FOR Y := 0 TO H-1 DO pSource[Y] := SourceBMP.Scanline[Y]; //--- Linear interpolation. Slower, but looks much better... FOR Y := DestBMP.Height-1 DOWNTO 0 DO BEGIN pDest := DestBMP.ScanLine[Y]; iX := 0; FOR X := 0 TO DestBMP.Width-1 DO BEGIN dRX := SCX + ( c * (X-DCX) - s * (Y-DCY)); dRY := SCY + ( s * (X-DCX) + c * (Y-DCY)); IF (dRX >= 1) and (dRY >= 1) and (dRX < W-1) and (dRY < H-1) then begin fX := frac(dRX); fY := frac(dRY); RX := trunc(dRX)*3; // "*3" because of 24 bit images RY := trunc(dRY); d := 1-fX; c11 := pSource[RY]^[ RX ]*(d) + pSource[RY]^[ RX+3 ]*(fX); c12 := pSource[RY]^[RX+1]*(d) + pSource[RY]^[RX+3+1]*(fX); c13 := pSource[RY]^[RX+2]*(d) + pSource[RY]^[RX+3+2]*(fX); Inc(RY); c21 := pSource[RY]^[ RX ]*(d) + pSource[RY]^[ RX+3 ]*(fX); c22 := pSource[RY]^[RX+1]*(d) + pSource[RY]^[RX+3+1]*(fX); c23 := pSource[RY]^[RX+2]*(d) + pSource[RY]^[RX+3+2]*(fX); d := 1-fY; pDest^[iX] := trunc(c11*(d) + c21*fY); Inc(iX); pDest^[iX] := trunc(c12*(d) + c22*fY); Inc(iX); pDest^[iX] := trunc(c13*(d) + c23*fY); Inc(iX); end else begin RX := trunc(dRX); RY := trunc(dRY); // No linear interpolation for pixels at the outer rim // Those pixels were copied like in the nearest neighbour algorithm. IF (RX >= 0) and (RY >= 0) and (RX < W) and (RY < H) then begin move(pSource[RY]^[RX*3], pDest^[iX], 3); end else begin // Pixel completely outside of the original image move(RGBBack, pDest^[iX], 3); end; Inc(iX, 3); end; END; END; SetLength(pSource, 0); END; Gruß Michael |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12: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 by Thomas Breitkreuz