AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

5x5-Blur bzw. "Antialiasing"

Ein Thema von dizzy · begonnen am 26. Nov 2003 · letzter Beitrag vom 4. Dez 2003
 
Phantom1

Registriert seit: 20. Jun 2003
282 Beiträge
 
Delphi 10.4 Sydney
 
#9

Re: 5x5-Blur bzw. "Antialiasing"

  Alt 3. Dez 2003, 15:37
Hi,

erstmal muss ich sagen das du den code wirklich gut optimiert hast, allerdings ist das ganze etwas unflexibel und die matrix muss man leider immer von hand eingeben. Da ich vor einigen monaten eine ähnliche prozedure geschrieben habe, möchte ich dir diese nicht vorenthalten, vieleicht kannst du sie ja gebrauchen ;O)

Die Procedure arbeit ähnlich wie GaussianBlur, man kann sie aber auch fürs Soften/Blurren/AntiAliasing benutzten.
Man kann einen Pixelradius angeben (von 0.0000001 bis 50 pixel). Je größer der Wert desto mehr wird geblurrt. (achtung große werte können sehr viel rechenzeit beanspruchen!)

Die Matrix und der divisor wird ebenfalls automatisch berechnet, hier mal zwei beispiele:

bei einem radius von 2,0

0,17|0,76|1,00|0,76|0,17
0,76|1,60|2,00|1,60|0,76
1,00|2,00|3,00|2,00|1,00
0,76|1,60|2,00|1,60|0,76
0,17|0,76|1,00|0,76|0,17


und radius 3,6

0,00|0,00|0,13|0,48|0,60|0,48|0,13|0,00|0,00
0,00|0,36|0,99|1,40|1,60|1,40|0,99|0,36|0,00
0,13|0,99|1,80|2,40|2,60|2,40|1,80|0,99|0,13
0,48|1,40|2,40|3,20|3,60|3,20|2,40|1,40|0,48
0,60|1,60|2,60|3,60|4,60|3,60|2,60|1,60|0,60
0,48|1,40|2,40|3,20|3,60|3,20|2,40|1,40|0,48
0,13|0,99|1,80|2,40|2,60|2,40|1,80|0,99|0,13
0,00|0,36|0,99|1,40|1,60|1,40|0,99|0,36|0,00
0,00|0,00|0,13|0,48|0,60|0,48|0,13|0,00|0,00

Desweiteren habe ich die procedure ebenfalls sogut ich konnte optimiert (ich kann leider auch kein assembler).
Die Randpixel werden bei meiner procedure mitgerechnet!

So und hier der sourcecode:

Delphi-Quellcode:
procedure BmpGBlur(Bmp: TBitmap; radius: Single);
Type
  TRGB = Packed Record b, g, r: Byte End;
  ArrTRGB = Array of TRGB;
  ArrSingle = Array of Single;
Var
  MatrixDim, MatrixRadius: Byte;
  Matrix : Array of ArrSingle;
  MatrixY : ^ArrSingle;
  Faktor : ^Single;
  BmpCopy : Array of ArrTRGB;
  BmpCopyY : ^ArrTRGB;
  BmpRGB, BmpCopyRGB: ^TRGB;
  BmpWidth, BmpHeight, x, y, dx, dy: Integer;
  StartDx, CountDx, StartDy, CountDy: Integer;
  R, G, B, Divisor: Single;

  Procedure CalculateMatrix;
  Var x,y: Integer; MxRadius, f: Single;
  Begin
    radius:=radius+1; // der mittel/nullpunkt muss mitgerechnet werden
    If Frac(radius)=0 Then MatrixDim:=Pred(Trunc(radius)*2) Else MatrixDim:=Succ(Trunc(radius)*2);
    SetLength(Matrix,MatrixDim,MatrixDim);
    MxRadius:=MatrixDim div 2;
    For y:=0 To Pred(MatrixDim) Do
      For x:=0 To Pred(MatrixDim) Do begin
        f:=radius-Sqrt(Sqr(x-MxRadius)+Sqr(y-MxRadius));
        If f<0 Then f:=0; // punkte die außerhalb des radius liegen löschen
        Matrix[y,x]:=f;
      end;
  End;

Begin
  Bmp.PixelFormat:=pf24bit;
  If radius<=0 Then radius:=1 Else If radius>=50 Then radius:=50; // radius bereich 0.0 < radius < 50.0
  CalculateMatrix;
  BmpWidth:=Bmp.Width;
  BmpHeight:=Bmp.Height;
  SetLength(BmpCopy,BmpHeight,BmpWidth);
  // Kopie des Bitmaps erstellen im zweidimensionalen Array (BmpCopy)
  For y:=0 To Pred(BmpHeight) Do
    Move(Bmp.ScanLine[y]^,BmpCopy[y,0],BmpWidth*3);
  MatrixRadius:=Pred(MatrixDim) Div 2;
  For y:=0 To Pred(BmpHeight) Do Begin
    BmpRGB:=Bmp.ScanLine[y];
    For x:=0 to Pred(BmpWidth) Do Begin
      R:=0; G:=0; B:=0; Divisor:=0;
      // Matrixpixel außerhalb des Bitmaps weglassen
      If y<MatrixRadius Then StartDy:=y Else StartDy:=MatrixRadius;
      If y>Pred(BmpHeight)-MatrixRadius Then CountDy:=Pred(BmpHeight)-y+StartDy
      Else CountDy:=MatrixRadius+StartDy;
      If x<MatrixRadius Then StartDx:=x Else StartDx:=MatrixRadius;
      If x>Pred(BmpWidth)-MatrixRadius Then CountDx:=Pred(BmpWidth)-x+StartDx
      Else CountDx:=MatrixRadius+StartDx;
      // Bildpunkte mit der Matrix multiplizieren
      MatrixY:=@Matrix[MatrixRadius-StartDy];
      BmpCopyY:=@BmpCopy[y-StartDy];
      For dy:=0 To CountDy Do Begin
        Faktor:=@MatrixY^[MatrixRadius-StartDx];
        BmpCopyRGB:=@BmpCopyY^[x-StartDx];
        For dx:=0 To CountDx Do Begin
          B:=B+BmpCopyRGB^.b*Faktor^; // blau
          G:=G+BmpCopyRGB^.g*Faktor^; // grün
          R:=R+BmpCopyRGB^.r*Faktor^; // rot
          Divisor:=Divisor+Faktor^;
          Inc(BmpCopyRGB);
          Inc(Faktor);
        End;
        Inc(MatrixY);
        Inc(BmpCopyY);
      End;
      // neuen berechneten Bildpunkt schreiben
      BmpRGB.b:=Round(B/Divisor);
      BmpRGB.g:=Round(G/Divisor);
      BmpRGB.r:=Round(R/Divisor);
      Inc(BmpRGB);
    End;
  End;
End;
  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 05: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