unit sepiaf02; interface uses Windows, Graphics; type TRGBColor = record R: Integer; {Red } G: Integer; {Green} B: Integer; {Blue } end; TYUVColor = record Y: Integer; {Brightness : 0..1024 } U: Integer; {Color Difference : -512..+512 } V: Integer; {Color Difference : -512..+512 } 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; RGBColor.G := P[X].rgbtGreen; RGBColor.R := P[X].rgbtRed; YUVColor := RGB2YUV(RGBColor); YUVColor.U := Trunc(-0.080 * 1024 * 255 + 0.5); //-0.091 YUVColor.V := Trunc(0.071 * 1024 * 255 + 0.5); //0.056 RGBColor := YUV2RGB(YUVColor); P[X] := NormalizeRGB(RGBColor); end; end; end; function NormalizeRGB(C: TRGBColor): TRGBTriple; begin with C do begin 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; end; function YUV2RGB(C: TYUVColor): TRGBColor; begin Result.R := (1024 * C.Y + 1436 * C.V) div (1024 * 1024); Result.G := (1024 * C.Y - 353 * C.U - 728 * C.V) div (1024 * 1024); result.B := (1024 * C.Y + 1775 * C.U ) div (1024 * 1024); end; { 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 ; } function RGB2YUV(C: TRGBColor): TYUVColor; begin Result.Y := 306 * C.R + 601 * C.G + 117 * C.B; Result.U := -172 * C.R - 339 * C.G + 512 * C.B; Result.V := 512 * C.R - 429 * C.G - 83 * C.B; end; { 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.