Nadesłany przez Dariusz Rorat, 23 lipca 2010 16:35
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.Pobierz pełne rozwiązanie.
Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.
effects.pas:
{ Copyright (C) 2010 Daro www.algorytm.org ***************************************************************************** * * * See the file COPYING.modifiedLGPL, included in this distribution, * * for details about the copyright. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * * ***************************************************************************** } unit effects; interface uses Classes, SysUtils, Graphics, ComCtrls, ExtCtrls, Windows; type TEffect = (efNegative,efSolarize,efFalseColors,efGrayScale,efSepia); TGraphicEffects = class (TComponent) private FEffect: TEffect; FImage: TImage; FLuminance: byte; FDepth: integer; private procedure SolarizeOrInvert(const Solarize: boolean;const lum: byte); procedure FalseColors; procedure ConvertToGrayScaleSepia(const dpt: integer;const sepia: boolean); protected public Inbmp: Graphics.TBitmap; Outbmp: Graphics.TBitmap; constructor Create(AOwner: TComponent); override; destructor Destroy; override; procedure AssignImage; procedure Convert; published property Effect: TEffect read FEffect write FEffect; property Image: TImage read FImage write FImage; property Luminance: byte read FLuminance write FLuminance; property Depth: integer read FDepth write FDepth; end; procedure Register; implementation var LUT: Array[0..255] of Double; procedure TGraphicEffects.SolarizeOrInvert(const Solarize: boolean;const lum: byte); var i, j, rvalue, gvalue, bvalue: Integer; col: TColor; begin if solarize then begin for i:=0 to lum do LUT[i]:=i; //solaryzacja for i:=(lum+1) to 255 do LUT[i]:=255-i; end else for i:=0 to 255 do LUT[i]:=255-i; //negatyw outbmp.Width:=Inbmp.Width; outbmp.Height:=Inbmp.Height; for j := 0 to Inbmp.Height-1 do for i := 0 to Inbmp.Width-1 do begin col := InBmp.Canvas.Pixels[i,j]; rvalue := GetRValue(col); gvalue := GetGValue(col); bvalue := GetBValue(col); //zmien wartosc wedlug tablicy LUT col := Round(LUT[rvalue]) + (Round(LUT[gvalue]) shl 8) + (Round(LUT[bvalue]) shl 16); OutBmp.Canvas.Pixels[i,j] := col; end; Image.Picture.Assign(outbmp); end; procedure TGraphicEffects.FalseColors; var i, j, rvalue, gvalue, bvalue: Integer; col: TColor; begin outbmp.Width:=Inbmp.Width; outbmp.Height:=Inbmp.Height; for j := 0 to Inbmp.Height-1 do for i := 0 to Inbmp.Width-1 do begin col := InBmp.Canvas.Pixels[i,j]; rvalue := GetRValue(col); gvalue := GetGValue(col); bvalue := GetBValue(col); //fałszuj col := bvalue + (gvalue shl 8) + (rvalue shl 16); OutBmp.Canvas.Pixels[i,j] := col; end; Image.Picture.Assign(outbmp); end; procedure TGraphicEffects.ConvertToGrayScaleSepia(const dpt: integer;const sepia: boolean); var color1,color2:longint; r,g,b,rr,gg:byte; h,w:integer; begin outbmp.Width:=Inbmp.Width; outbmp.Height:=Inbmp.Height; for h := 0 to inbmp.height-1 do begin for w := 0 to inbmp.width-1 do begin //first convert the bitmap to greyscale color1:=colortorgb(inbmp.Canvas.pixels[w,h]); r:=getrvalue(color1); g:=getgvalue(color1); b:=getbvalue(color1); color2:=(r+g+b) div 3; outbmp.canvas.Pixels[w,h]:=RGB(color2,color2,color2); //then convert it to sepia if sepia then begin color1:=colortorgb(outbmp.Canvas.pixels[w,h]); r:=getrvalue(color1); g:=getgvalue(color1); b:=getbvalue(color1); rr:=r+(dpt*2); gg:=g+dpt; if rr <= ((dpt*2)-1) then rr:=255; if gg <= (dpt-1) then gg:=255; outbmp.canvas.Pixels[w,h]:=RGB(rr,gg,b); end; end; end; Image.Picture.Assign(outbmp); end; constructor TGraphicEffects.Create(AOwner:TComponent); begin inherited Create(AOwner); Inbmp:=Graphics.Tbitmap.Create; Outbmp:=Graphics.Tbitmap.Create; FDepth:=20; FLuminance:=127; end; destructor TGraphicEffects.Destroy; begin Inbmp.Free; Outbmp.Free; inherited Destroy; end; procedure TGraphicEffects.AssignImage; begin Inbmp.Assign(Image.Picture.Bitmap); end; procedure TGraphicEffects.Convert; begin case FEffect of efNegative: begin SolarizeOrInvert(false,0); end; efSolarize: begin SolarizeOrInvert(true,FLuminance); end; efFalseColors: begin FalseColors; end; efGrayScale: begin ConvertToGrayScaleSepia(0,false); end; efSepia: begin ConvertToGrayScaleSepia(FDepth,true); end; end; end; procedure Register; begin RegisterComponents('Graphics',[TGraphicEffects]); end; end.