AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi Bild Qualität nach der Rotation Problem
Thema durchsuchen
Ansicht
Themen-Optionen

Bild Qualität nach der Rotation Problem

Ein Thema von thomas2009 · begonnen am 7. Sep 2008 · letzter Beitrag vom 8. Sep 2008
 
grizzly

Registriert seit: 10. Dez 2004
150 Beiträge
 
Delphi XE4 Professional
 
#10

Re: Bild Qualität nach der Rotation Problem

  Alt 7. Sep 2008, 19:58
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:
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;
Eine Gegenüberstellung kann man sich mit dem Demo-Projekt im Anhang verschaffen.

Gruß
Michael
Angehängte Grafiken
Dateityp: jpg screen01_423.jpg (78,5 KB, 44x aufgerufen)
Angehängte Dateien
Dateityp: zip rotateimage_source_131.zip (47,5 KB, 23x aufgerufen)
  Mit Zitat antworten Zitat
 


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:16 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