Home » Tipps & Tricks » Grafik » Grafikbearbeitung » Grafik glätten
Grafik glätten
Folgender Code glättet ein Bitmap, wie es die diversen Grafikprogramme vormachen. Der Code ist nicht optimiert, soll heißen langsam, aber funktionsfähig. Außerdem werden die jeweils äußeren Pixel einer Grafik nicht mitgeglättet, was aber vom interessierten Nutzer ohne Probleme behoben werden können sollte.
Der Code geht wie folgt vor: Es errechnet für jeden Bildpunkt den Mittelwert aus den umliegenden Bildpunkten und errechnet so den Farbwert neu. Um eine größere Glättung zu erreichen, muss man nur die einzubeziehenden Bildpunkte erweitern.
var x, y: integer; r, b, g: byte; begin with Image3.picture.Bitmap.canvas do begin for x:=1 to Image3.picture.Bitmap.Width-1 do for Y:=1 to Image3.picture.Bitmap.height-1 do begin r:=(GetRValue(Pixels[x-1,y-1])+ GetRValue(Pixels[x,y-1])+ GetRValue(Pixels[x+1,y-1])+ GetRValue(Pixels[x-1,y])+ GetRValue(Pixels[x+1,y])+ GetRValue(Pixels[x-1,y+1])+ GetRValue(Pixels[x,y+1])+ GetRValue(Pixels[x+1,y+1])+ GetRValue(Pixels[x,y])) div 9; g:=(GetGValue(Pixels[x-1,y-1])+ GetGValue(Pixels[x,y-1])+ GetGValue(Pixels[x+1,y-1])+ GetGValue(Pixels[x-1,y])+ GetGValue(Pixels[x+1,y])+ GetGValue(Pixels[x-1,y+1])+ GetGValue(Pixels[x,y+1])+ GetGValue(Pixels[x+1,y+1])+ GetGValue(Pixels[x,y])) div 9; b:=(GetBValue(Pixels[x-1,y-1])+ GetBValue(Pixels[x,y-1])+ GetBValue(Pixels[x+1,y-1])+ GetBValue(Pixels[x-1,y])+ GetBValue(Pixels[x+1,y])+ GetBValue(Pixels[x-1,y+1])+ GetBValue(Pixels[x,y+1])+ GetBValue(Pixels[x+1,y+1])+ GetBValue(Pixels[x,y])) div 9; Pixels[x,y]:=RGB(r,g,b); end; end; end;
Eine schnellere Methode, mittels Scanline, wurde von Markus Nakhlah eingesandt:
type TRGBTripleArray = array[0..32768] of TRGBTriple; // 32768 = maximale Anzahl der Pixel in der Breite eines Bildes (also eine "ScanLine") pRGBTripleArray = ^TRGBTripleArray; // Pointer auf TRGBTripleArray ... procedure Antialiasing(const DC: TCanvas; const Rectangle: TRect); var cx, cy: Smallint; r, g, b: Byte; Row1: pRGBTripleArray; Row2: pRGBTripleArray; Row3: pRGBTripleArray; TEMP: TBitmap; CurRect: TRect; begin TEMP := TBitmap.Create; try with TEMP do begin Width := Rectangle.Right - Rectangle.Left; Height := Rectangle.Bottom - Rectangle.Top; CurRect := Rect(0, 0, Width, Height); PixelFormat := pf24Bit; Canvas.CopyRect(CurRect, DC, Rectangle); with Canvas do begin for cy := 1 to (Height - 2) do begin Row1 := ScanLine[cy - 1]; Row2 := ScanLine[cy]; Row3 := ScanLine[cy + 1]; for cx := 1 to (Width - 2) do begin r := (Row1[cx - 1].rgbtRed+Row1[cx].rgbtRed+ Row1[cx + 1].rgbtRed+ Row2[cx - 1].rgbtRed+ Row2[cx + 1].rgbtRed+ Row2[cx - 1].rgbtRed+ Row3[cx].rgbtRed+ Row3[cx + 1].rgbtRed+ Row3[cx].rgbtRed) div 9; g := (Row1[cx - 1].rgbtGreen+ Row1[cx].rgbtGreen+ Row1[cx + 1].rgbtGreen+ Row2[cx - 1].rgbtGreen+ Row2[cx + 1].rgbtGreen+ Row2[cx - 1].rgbtGreen+ Row3[cx].rgbtGreen+ Row3[cx + 1].rgbtGreen+ Row3[cx].rgbtGreen) div 9; b := (Row1[cx - 1].rgbtBlue+ Row1[cx].rgbtBlue+ Row1[cx + 1].rgbtBlue+ Row2[cx - 1].rgbtBlue+ Row2[cx + 1].rgbtBlue+ Row2[cx - 1].rgbtBlue+ Row3[cx].rgbtBlue+ Row3[cx + 1].rgbtBlue+ Row3[cx].rgbtBlue) div 9; Row2[cx].rgbtBlue := b; Row2[cx].rgbtGreen := g; Row2[cx].rgbtRed := r; end; end; end; DC.CopyRect(Rectangle, Canvas, CurRect); end; finally TEMP.Free; end; end;