Nadesłany przez Tomasz Lubiński, 19 sierpnia 2010 10:00
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.
Color Accent - Delphi/color_accent.pas:
//--------------------------------------------------------------------------- //Akcent koloru //www.algorytm.org //(c) 2010 by Tomasz Lubinski unit color_accent; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, StdCtrls, ExtCtrls, Math; type TForm1 = class(TForm) Src: TImage; Dst: TImage; Label1: TLabel; Label2: TLabel; Range: TEdit; UpDown1: TUpDown; procedure SrcMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); private { Private declarations } public { Public declarations } end; PPixelRec = ^TPixelRec; TPixelRec = packed record B: Byte; G: Byte; R: Byte; end; var Form1: TForm1; implementation {$R *.DFM} function fmod(x: double; y: double): double; begin Result := x - Int(x / y) * y; end; procedure rgb2hsv(var hue: double; var sat: double; var val: double; red: double;grn: double; blu:double); var x, f, i: double; begin x := MIN(MIN(red, grn), blu); val := MAX(MAX(red, grn), blu); if x = val then begin hue := 0; sat := 0; end else begin if red = x then f := grn-blu else if grn = x then f := blu-red else f := red-grn; if red = x then i := 3 else if grn = x then i := 5 else i := 1; hue := fmod((i-f/(val-x))*60, 360); sat := ((val-x)/val); end; end; procedure TForm1.SrcMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var color: TColor; Psrc, Pdst: PPixelRec; hsrc, ssrc, vsrc, hdst, sdst, vdst, hfrom, hto : double; range, i, j: Integer; begin Dst.Canvas.Brush.Color := clWhite; Dst.Canvas.Rectangle(0, 0, Src.Picture.Bitmap.Width, Src.Picture.Bitmap.Height); Dst.Picture.Bitmap.PixelFormat := pf24bit; color := Src.Canvas.Pixels[X, Y]; RGB2HSV(hsrc, ssrc, vsrc, (color and $FF) / 255.0, ((color and $FF00) shr 8) / 255.0, ((color and $FF0000) shr 16) / 255.0); range := StrToInt(Form1.Range.Text); hfrom := fmod((hsrc - (range / 2)) + 360, 360); hto := fmod(hsrc + (range / 2), 360); for i:=0 to Src.Picture.Bitmap.Height-1 do begin Psrc := Src.Picture.Bitmap.ScanLine[i]; Pdst := Dst.Picture.Bitmap.ScanLine[i]; for j:=0 to Src.Picture.Bitmap.Width-1 do begin RGB2HSV(hdst, sdst, vdst, Psrc.r/255.0, Psrc.g/255.0, Psrc.b/255.0); if (( (hfrom <= hto) and (hfrom <= hdst) and (hto >= hdst) ) or ( (hfrom > hto) and ( (hfrom <= hdst) or (hto >= hdst) ))) then Pdst^ := Psrc^ else begin Pdst.r := Round(0.299 * Psrc.r + 0.587 * Psrc.g + 0.114 * Psrc.b); Pdst.g := Round(0.299 * Psrc.r + 0.587 * Psrc.g + 0.114 * Psrc.b); Pdst.b := Round(0.299 * Psrc.r + 0.587 * Psrc.g + 0.114 * Psrc.b); end; Inc(Psrc); Inc(Pdst); end; end; end; end.