unit sepiaf01; interface uses Windows, Graphics; type TRGBColor = record R: Double; {Red : 0..1} G: Double; {Green : 0..1} B: Double; {Blue : 0..1} end; TYUVColor = record Y: Double; {Brightness : 0..1 } U: Double; {Color Difference : -0.5..0.5 } V: Double; {Color Difference : -0.5..0.5 } end; TRGBTripleArray = Array[0 .. $FFFF] of TRGBTriple; PRGBTripleArray = ^TRGBTripleArray; function NormalizeRGB(C: TRGBColor): TRGBTriple; function RGB2YUV(C: TRGBColor): TYUVColor; function YUV2RGB(C: TYUVColor): TRGBColor; procedure SepiaFilter(Bmp: TBitmap); implementation procedure SepiaFilter(Bmp: TBitmap); var P: PRGBTripleArray; X, Y: Integer; RGBColor: TRGBColor; YUVColor: TYUVColor; begin for Y := 0 to Bmp.Height - 1 do begin P := Bmp.Scanline[Y]; for X := 0 to Bmp.Width - 1 do begin RGBColor.B := P[X].rgbtBlue / 255; RGBColor.G := P[X].rgbtGreen / 255; RGBColor.R := P[X].rgbtRed / 255; YUVColor := RGB2YUV(RGBColor); YUVColor.U := -0.080; //-0.091 YUVColor.V := 0.071; //0.056 RGBColor := YUV2RGB(YUVColor); P[X] := NormalizeRGB(RGBColor); end; end; end; function NormalizeRGB(C: TRGBColor): TRGBTriple; var R, G, B: Integer; begin R := Trunc(C.R * 255 + 0.5); G := Trunc(C.G * 255 + 0.5); B := Trunc(C.B * 255 + 0.5); if R > 255 then R := 255 else if R < 0 then R := 0; if G > 255 then G := 255 else if G < 0 then G := 0; if B > 255 then B := 255 else if B < 0 then B := 0; Result.rgbtBlue := B; Result.rgbtGreen := G; Result.rgbtRed := R; end; function YUV2RGB(C: TYUVColor): TRGBColor; begin Result.R := C.Y + 1.4026 * C.V; Result.G := C.Y - 0.3444 * C.U - 0.7114 * C.V; result.B := C.Y + 1.7330 * C.U ; end; function RGB2YUV(C: TRGBColor): TYUVColor; begin Result.Y := 0.2990 * C.R + 0.5870 * C.G + 0.1140 * C.B; Result.U := -0.1686 * C.R - 0.3311 * C.G + 0.4997 * C.B; Result.V := 0.4998 * C.R - 0.4185 * C.G - 0.0813 * C.B; end; end.