⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 teefilterseditor.pas

📁 第三方控件:PaintGrid.pas 网格型仪表控件源文件 Mymeter.pas 圆型仪表控件源文件 Project1是这两个控件的使用范例。 该
💻 PAS
📖 第 1 页 / 共 3 页
字号:

  if Filters.Items.Count>0 then
  begin
    Filters.ItemIndex:=0;
    FiltersClick(Self);
    Preview;
  end;
end;

{ TFilter }
procedure TFilter.Apply;
begin
  Apply(Rect(0,0,Bitmap.Width-1,Bitmap.Height-1));
end;

procedure TFilter.Apply(const R:TRect);
begin
  CalcLines;
end;

class procedure TFilter.ApplyTo(Bitmap: TBitmap);
var tmp : TFilter;
begin
  tmp:=Create(nil);
  try
    tmp.Bitmap:=Bitmap;
    tmp.Apply;
  finally
    tmp.Free;
  end;
end;

class function TFilter.Description:String;
begin
  result:=ClassName;
end;

procedure TFilter.CalcLines;
var y   : Integer;
    Dif : Integer;
    tmp : Integer;
begin
  Bitmap.PixelFormat:=pf24Bit;
  tmp:=Bitmap.Height;
  SetLength(Lines,tmp);

  if tmp>1 then
  begin
    Lines[0]:=Bitmap.ScanLine[0];
    Lines[1]:=Bitmap.ScanLine[1];
    Dif:=Integer(Lines[1])-Integer(Lines[0]);

    for y:=2 to tmp-1 do
        Lines[y]:=Pointer(Integer(Lines[y-1])+Dif);
  end;
end;

procedure TFilter.CreateEditor(AParent:TWinControl; AChanged:TNotifyEvent);
begin // No properties (abstract)
  FChanged:=AChanged;
end;

{ TInvertFilter }
procedure TInvertFilter.Apply(const R:TRect);
var x,y : Integer;
begin
  inherited;

  for y:=R.Top to R.Bottom do
    for x:=R.Left to R.Right do
    with Lines[y,x] do
    begin
      rgbtBlue:=255-rgbtBlue;
      rgbtGreen:=255-rgbtGreen;
      rgbtRed:=255-rgbtRed;
    end;
end;

class function TInvertFilter.Description: String;
begin
  result:='Invert';
end;

{ TGrayScaleFilter }
procedure TGrayScaleFilter.Apply(const R:TRect);
var x,y :  Integer;
    tmp : Byte;
begin
  inherited;

  case Method of
    gmSimple: for y:=R.Top to R.Bottom do
                  for x:=R.Left to R.Right do
                  with Lines[y,x] do
                  begin
                    tmp:=(rgbtBlue+rgbtGreen+rgbtRed) div 3;
                    rgbtBlue:=tmp;
                    rgbtGreen:=tmp;
                    rgbtRed:=tmp;
                  end;
       gmEye: for y:=R.Top to R.Bottom do
                  for x:=R.Left to R.Right do
                  with Lines[y,x] do
                  begin
                    tmp:=Round( (0.30*rgbtRed) +
                                (0.59*rgbtGreen) +
                                (0.11*rgbtBlue));

                    rgbtBlue:=tmp;
                    rgbtGreen:=tmp;
                    rgbtRed:=tmp;
                  end;
      gmEye2: for y:=R.Top to R.Bottom do
                  for x:=R.Left to R.Right do
                  with Lines[y,x] do
                  begin
                    tmp:=(11*rgbtRed+16*rgbtGreen+5*rgbtBlue) div 32;
                    rgbtBlue:=tmp;
                    rgbtGreen:=tmp;
                    rgbtRed:=tmp;
                  end;
    end;
end;

class function TGrayScaleFilter.Description: String;
begin
  result:='Gray scale';
end;

{ TMosaicFilter }
constructor TMosaicFilter.Create(Collection:TCollection);
begin
  inherited;
  FAmount:=8;
  IOnlyPositive:=True;
end;

procedure TMosaicFilter.Apply(const R:TRect);
var x, y,
    xx,yy : Integer;
    tmpDims : Single;
    tmpX,
    tmpY : Integer;
    ar,
    ag,
    ab   : Integer;
    Line : PRGBTriples;
begin
  inherited;

  if Amount=0 then exit;

  tmpDims:=1.0/Sqr(Amount);

  for y:=0 to ((R.Bottom-R.Top) div Amount)-1 do
    for x:=0 to ((R.Right-R.Left) div Amount)-1 do
    begin
      tmpY:=Amount*y;
      tmpX:=Amount*x;

      ar:=0;
      ag:=0;
      ab:=0;

      for yy:=0 to Amount-1 do
      begin
        Line:=Lines[tmpY+yy+R.Top];

        for xx:=0 to Amount-1 do
        with Line^[tmpX+xx+R.Left] do
        begin
          Inc(ar,rgbtRed);
          Inc(ag,rgbtGreen);
          Inc(ab,rgbtBlue);
        end;
      end;

      ar:=Round(ar*tmpDims);
      ag:=Round(ag*tmpDims);
      ab:=Round(ab*tmpDims);

      if ar>255 then ar:=255;
      if ag>255 then ag:=255;
      if ab>255 then ab:=255;

      for yy:=0 to Amount-1 do
      begin
        Line:=Lines[tmpY+yy+R.Top];

        for xx:=0 to Amount-1 do
        with Line^[tmpX+xx+R.Left] do
        begin
          rgbtBlue:=ab;
          rgbtGreen:=ag;
          rgbtRed:=ar;
        end;
      end;
    end;
end;

class function TMosaicFilter.Description: String;
begin
  result:='Mosaic';
end;

{ TFlipFilter }
procedure TFlipFilter.Apply(const R:TRect);
var tmp : TRGBTriple;
    tmpH,
    tmpY,
    x,y : Integer;
begin
  inherited;

  tmpH:=R.Bottom-R.Top;

  {$R-}
  
  for y:=0 to (tmpH div 2)-1 do
      for x:=R.Left to R.Right do
      begin
        tmp:=Lines[R.Top+y]^[x];
        tmpY:=R.Top+tmpH-1-y;
        Lines[R.Top+y]^[x]:=Lines[tmpY]^[x];
        Lines[tmpY]^[x]:=tmp;
      end;
end;

class function TFlipFilter.Description: String;
begin
  result:='Flip';
end;

{ TReverseFilter }
procedure TReverseFilter.Apply(const R:TRect);
var tmp : TRGBTriple;
    tmpW,
    tmpX,
    x,y : Integer;
begin
  inherited;

  tmpW:=R.Right-R.Left;

  for x:=0 to (tmpW div 2)-1 do
      for y:=R.Top to R.Bottom do
      begin
        tmp:=Lines[y,R.Left+x];
        tmpX:=R.Left+tmpW-1-x;
        Lines[y,R.Left+x]:=Lines[y,tmpX];
        Lines[y,tmpX]:=tmp;
      end;
end;

class function TReverseFilter.Description: String;
begin
  result:='Reverse';
end;

procedure InstallHook;
{$IFDEF CLR}
var p: TTeeOnCreateEditor;
{$ENDIF}
begin
  {$IFDEF CLR}
  p:=TeeFiltersShowEditor;
  TeeOnShowEditor.Add(@p);
  {$ELSE}
  TeeOnShowEditor.Add(@TeeFiltersShowEditor);
  {$ENDIF}
end;

procedure RemoveHook;
{$IFDEF CLR}
var p: TTeeOnCreateEditor;
{$ENDIF}
begin
  {$IFDEF CLR}
  p:=TeeFiltersShowEditor;
  TeeOnShowEditor.Remove(@p);
  {$ELSE}
  TeeOnShowEditor.Remove(@TeeFiltersShowEditor);
  {$ENDIF}
end;

{ TAmountFilter }
Constructor TAmountFilter.Create(Collection:TCollection);
begin
  inherited;
  FPercent:=True;
  FAmount:=5; // %
end;

procedure TAmountFilter.ScrollChanged(Sender: TObject);
begin
  FAmount:=(Sender as TScrollBar).Position;
  FChanged(Self);
end;

procedure TAmountFilter.ResetScroll;
begin
  with FScrollBar do
  if FPercent then
  begin
    if IOnlyPositive then Min:=0 else Min:=-100;
    Max:=100;
  end
  else
  begin
    if IOnlyPositive then Min:=0 else Min:=-255;
    Max:=255;
  end;
end;

procedure TAmountFilter.CheckClick(Sender: TObject);
begin
  FPercent:=(Sender as TCheckBox).Checked;
  ResetScroll;
  FChanged(Self);
end;

procedure TAmountFilter.CreateEditor(AParent:TWinControl; AChanged:TNotifyEvent);
begin
  inherited;

  FScrollBar:=TScrollBar.Create(AParent);
  with FScrollBar do
  begin
    Parent:=AParent;
    SetBounds(4,8,AParent.Width-8,16);
    ResetScroll;
    Position:=Self.FAmount;
    OnChange:=ScrollChanged;
  end;

  with TCheckBox.Create(AParent) do
  begin
    Parent:=AParent;
    SetBounds(4,28,75,16);
    Caption:=TeeMsg_Percent;
    Checked:=Self.Percent;
    OnClick:=CheckClick;
  end;
end;

{ TBrightnessFilter }
procedure TBrightnessFilter.Apply(const R: TRect);
var x,y,l :  Integer;
    IPercent : Single;
begin
  inherited;

  if Percent then
     IPercent:=FAmount*0.01
  else
     IPercent:=1;

  for y:=R.Top to R.Bottom do
      for x:=R.Left to R.Right do
      with Lines[y,x] do
      begin
        if Percent then l:=rgbtRed+Round(rgbtRed*IPercent)
                   else l:=rgbtRed+Amount;

        if l<0 then rgbtRed:=0 else if l>255 then rgbtRed:=255 else rgbtRed:=l;

        if Percent then l:=rgbtGreen+Round(rgbtGreen*IPercent)
                   else l:=rgbtGreen+Amount;

        if l<0 then rgbtGreen:=0 else if l>255 then rgbtGreen:=255 else rgbtGreen:=l;

        if Percent then l:=rgbtBlue+Round(rgbtBlue*IPercent)
                   else l:=rgbtBlue+Amount;

        if l<0 then rgbtBlue:=0 else if l>255 then rgbtBlue:=255 else rgbtBlue:=l;
      end;
end;

class function TBrightnessFilter.Description: String;
begin
  result:='Brightness';
end;

type
  Float=Single;

const
  // HLSMAX BEST IF DIVISIBLE BY 6.  RGBMAX, HLSMAX must each fit in a byte.
  HLSMAX = 240;  // H,L, and S vary over 0-HLSMAX
  RGBMAX = 255;  // R,G, and B vary over 0-RGBMAX

  RGBMAX2 = 2.0*RGBMAX;
  InvRGBMAX2 = 1.0/RGBMAX2;

  HLSMAXDiv2=HLSMAX/2;
  HLSMAXDiv3=HLSMAX/3;
  HLSMAXDiv6=HLSMAX/6;
  HLSMAXDiv12=HLSMAX/12;
  HLSMAX2=HLSMAX*2;
  HLSMAX3=HLSMAX*3;
  HLSMAX2Div3=HLSMAX2/3;

  { Hue is undefined if Saturation is 0 (grey-scale)
    This value determines where the Hue scrollbar is
    initially set for achromatic colors }
  HLSUndefined = 160; // HLSMAX2Div3;

procedure RGBToHLS(const Color:TRGBTriple; var Hue, Luminance, Saturation: Word);
var
  H, L, S: Float;
  R, G, B: Word;
  dif : Integer;
  sum, cMax, cMin: Word;
  Rdelta, Gdelta, Bdelta: Extended; { intermediate value: % of spread from max }
begin
  R:=Color.rgbtRed;
  G:=Color.rgbtGreen;
  B:=Color.rgbtBlue;

  { calculate lightness }
  if R>G then
     if R>B then cMax:=R else cMax:=B
  else
     if G>B then cMax:=G else cMax:=B;

  if R<G then
     if R<B then cMin:=R else cMin:=B
  else
     if G<B then cMin:=G else cMin:=B;

  sum:=(cMax + cMin);

  L := ( (sum * HLSMAX) + RGBMAX ) / ( 2 * RGBMAX);

  if cMax = cMin then  { r=g=b --> achromatic case }
  begin                { saturation }
    Hue := Round(HLSUndefined);
//    pwHue := 160;      { MS's ColorRGBToHLS always defaults to 160 in this case }
    Luminance := Round(L);
    Saturation := 0;
  end
  else                 { chromatic case }
  begin
    dif:=cMax-cMin;

    { saturation }
    if L <= HLSMAXDiv2 then
       S := ( (dif*HLSMAX) + (sum*0.5) ) / sum
    else
       S := ( (dif*HLSMAX) + ( RGBMAX-(sum*0.5) )) / (2*RGBMAX-sum);

    { hue }
    Rdelta := ( ((cMax-R)*HLSMAXDiv6) + (dif*0.5) ) / dif;
    Gdelta := ( ((cMax-G)*HLSMAXDiv6) + (dif*0.5) ) / dif;
    Bdelta := ( ((cMax-B)*HLSMAXDiv6) + (dif*0.5) ) / dif;

    if R = cMax then
       H := Bdelta - Gdelta
    else
    if G = cMax then
       H := HLSMAX3 + Rdelta - Bdelta
    else // B == cMax
       H := HLSUndefined + Gdelta - Rdelta;

    if H < 0 then H := H + HLSMAX
    else
    if H > HLSMAX then H := H - HLSMAX;

    Hue := Round(H);
    Luminance := Round(L);
    Saturation := Round(S);
  end;
end;

procedure HLSToRGB(Hue, Luminance, Saturation: Word; var rgb: TRGBTriple);

  function HueToRGB(const Lum, Sat:Float; Hue: Float): Integer;
  begin
    { range check: note values passed add/subtract thirds of range }
    if hue < 0 then hue:=hue+HLSMAX;
    if hue > HLSMAX then hue:=hue-HLSMAX;

    { return r,g, or b value from this tridrant }
    if hue < HLSMAXDiv6 then
        Result := Round( Lum + (((Sat-Lum)*hue+HLSMAXDiv12)/HLSMAXDiv6))
    else
    if hue < HLSMAXDiv2 then
        Result := Round( Sat)
    else
    if hue < HLSMAX2Div3 then
        Result := Round( Lum + (((Sat-Lum)*(HLSMAX2Div3-hue)+HLSMAXDiv12)/HLSMAXDiv6) )
    else
        Result := Round( Lum );
  end;

  function RoundColor(const Value: Float): Integer;
  begin
    if Value > 255 then Result := 255 else Result := Round(Value);
  end;

var
  Magic1, Magic2: Float;       { calculated magic numbers (really!) }

  function RoundColor2(const Hue: Float): Integer;
  begin
    result:=RoundColor((HueToRGB(Magic1,Magic2,Hue)*RGBMAX + HLSMAXDiv2)/HLSMAX);
  end;

begin
  if Saturation = 0 then
  with rgb do
  begin            { achromatic case }
    rgbtRed := RoundColor( (Luminance * RGBMAX)/HLSMAX );
    rgbtGreen:=rgbtRed;
    rgbtBlue:=rgbtGreen;
    if Hue <> HLSUndefined then ;{ ERROR }
  end
  else
  begin            { chromatic case }
    { set up magic numbers }
    if Luminance <= HLSMAXDiv2 then
       Magic2 := (Luminance * (HLSMAX + Saturation) + HLSMAXDiv2) / HLSMAX
    else
       Magic2 := Luminance + Saturation - ((Luminance * Saturation) + HLSMAXDiv2) / HLSMAX;

    Magic1 := 2 * Luminance - Magic2;

    { get RGB, change units from HLSMAX to RGBMAX }
    rgb.rgbtRed:=RoundColor2(Hue+HLSMAXDiv3);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -