tchart

xiaoxiao2021-02-28  105

{**********************************************} {   TeeChart and TeeTree Image Filters         } {                                              } {   Copyright (c) 2006-2007 by David Berneda   } {        All Rights Reserved                   } {**********************************************} unit TeeFilters ; {$I TeeDefs.inc}   {$R-}   interface   uses    {$IFNDEF LINUX}   Windows ,    {$ENDIF}   Classes ,    {$IFDEF D6}   Types ,    {$ENDIF}    {$IFDEF CLX}   Qt , QControls , QGraphics , QStdCtrls , QExtCtrls ,    {$ELSE}   Controls , Graphics , StdCtrls , ExtCtrls ,    {$ENDIF}   TeCanvas ;   {$IFDEF CLR} {$UNSAFECODE ON} {$ENDIF}   type   TResizeFilter = class (TTeeFilter )    private     FWidth   :  Integer ;     FHeight  :  Integer ;    public      procedure Apply (Bitmap :TBitmap ;  const R :TRect ) ;  override ;        procedure CreateEditor (Creator :IFormCreator ; AChanged :TNotifyEvent ) ;  override ;      class  function Description :  String ;  override ;    published      property Width : Integer  read FWidth  write FWidth default  0 ;      property Height : Integer  read FHeight  write FHeight default  0 ;    end ;     TCropFilter = class (TResizeFilter )    private     FLeft    :  Integer ;     FSmooth  :  Boolean ;     FTop     :  Integer ;    public      procedure Apply (Bitmap :TBitmap ;  const R :TRect ) ;  override ;        procedure CreateEditor (Creator :IFormCreator ; AChanged :TNotifyEvent ) ;  override ;      class  function Description :  String ;  override ;    published      property Left : Integer  read FLeft  write FLeft default  0 ;      property Smooth : Boolean  read FSmooth  write FSmooth default  False ;      property Top : Integer  read FTop  write FTop default  0 ;    end ;     TInvertFilter = class (TTeeFilter )    public      procedure Apply (Bitmap :TBitmap ;  const R :TRect ) ;  override ;      class  function Description :  String ;  override ;    end ;     TGrayMethod = (gmSimple , gmEye , gmEye2 ) ;     TGrayScaleFilter = class (TTeeFilter )    private     FMethod  : TGrayMethod ;    public      procedure Apply (Bitmap :TBitmap ;  const R :TRect ) ;  override ;        procedure CreateEditor (Creator :IFormCreator ; AChanged :TNotifyEvent ) ;  override ;      class  function Description :  String ;  override ;    published      property Method :TGrayMethod  read FMethod  write FMethod default gmSimple ;    end ;     TFlipFilter = class (TTeeFilter )    public      procedure Apply (Bitmap :TBitmap ;  const R :TRect ) ;  override ;      class  function Description :  String ;  override ;    end ;     TReverseFilter = class (TTeeFilter )    public      procedure Apply (Bitmap :TBitmap ;  const R :TRect ) ;  override ;      class  function Description :  String ;  override ;    end ;     TAmountFilter = class (TTeeFilter )    private     FAmount   :  Integer ;     FPercent  :  Boolean ;     FScrollBar  : TScrollBar ;       IOnlyPositive  :  Boolean ;      procedure ResetScroll (Sender : TObject ) ;      function ScrollMin : Integer ;      function ScrollMax : Integer ;    public      Constructor Create (Collection :TCollection ) ;  override ;      procedure CreateEditor (Creator :IFormCreator ; AChanged :TNotifyEvent ) ;  override ;    published      property Percent : Boolean  read FPercent  write FPercent default  True ;      property Amount : Integer  read FAmount  write FAmount default  5 ;    end ;     TMosaicFilter = class (TAmountFilter )    public      Constructor Create (Collection :TCollection ) ;  override ;      procedure Apply (Bitmap :TBitmap ;  const R :TRect ) ;  override ;      class  function Description :  String ;  override ;    end ;     TBrightnessFilter = class (TAmountFilter )    public      procedure Apply (Bitmap :TBitmap ;  const R :TRect ) ;  override ;      class  function Description :  String ;  override ;    end ;     TContrastFilter = class (TAmountFilter )    public      procedure Apply (Bitmap :TBitmap ;  const R :TRect ) ;  override ;      class  function Description :  String ;  override ;    end ;     TColorFilter = class (TTeeFilter )    private     FBlue   :  Integer ;     FGreen  :  Integer ;     FRed    :  Integer ;    public      procedure Apply (Bitmap :TBitmap ;  const R :TRect ) ;  override ;      procedure CreateEditor (Creator :IFormCreator ; AChanged :TNotifyEvent ) ;  override ;      class  function Description :  String ;  override ;    published      property Red : Integer  read FRed  write FRed default  0 ;      property Green : Integer  read FGreen  write FGreen default  0 ;      property Blue : Integer  read FBlue  write FBlue default  0 ;    end ;     THueLumSatFilter = class (TTeeFilter )    private     FHue  :  Integer ;     FLum  :  Integer ;     FSat  :  Integer ;    public      procedure Apply (Bitmap :TBitmap ;  const R :TRect ) ;  override ;      procedure CreateEditor (Creator :IFormCreator ; AChanged :TNotifyEvent ) ;  override ;      class  function Description :  String ;  override ;    published      property Hue : Integer  read FHue  write FHue default  0 ;      property Luminance : Integer  read FLum  write FLum default  0 ;      property Saturation : Integer  read FSat  write FSat default  0 ;    end ;     TSharpenFilter = class (TConvolveFilter )    public      procedure Apply (Bitmap :TBitmap ;  const R :TRect ) ;  override ;      class  function Description :  String ;  override ;    end ;     TEmbossFilter = class (TConvolveFilter )    public      procedure Apply (Bitmap :TBitmap ;  const R :TRect ) ;  override ;      class  function Description :  String ;  override ;    end ;     TSoftenFilter = class (TConvolveFilter )    public      procedure Apply (Bitmap :TBitmap ;  const R :TRect ) ;  override ;      class  function Description :  String ;  override ;    end ;     TGammaCorrectionFilter = class (TAmountFilter )    public      Constructor Create (Collection :TCollection ) ;  override ;      procedure Apply (Bitmap :TBitmap ;  const R :TRect ) ;  override ;      class  function Description :  String ;  override ;    published      property Amount default  70 ;    end ;     TRotateFilter = class (TTeeFilter )    private     FAngle      :  Double ;     FAutoSize   :  Boolean ;     FBackColor  : TColor ;      procedure SetAngle ( const Value :  Double ) ;    public      Constructor Create (Collection :TCollection ) ;  override ;        procedure Apply (Bitmap :TBitmap ;  const R :TRect ) ;  override ;      procedure CreateEditor (Creator :IFormCreator ; AChanged :TNotifyEvent ) ;  override ;      class  function Description :  String ;  override ;    published      property Angle : Double  read FAngle  write SetAngle ;      property AutoSize : Boolean  read FAutoSize  write FAutoSize default  True ;      property BackColor :TColor  read FBackColor  write FBackColor default clWhite ;    end ;     TMirrorDirection = (mdDown , mdUp , mdRight , mdLeft ) ;     TMirrorFilter = class (TTeeFilter )    private     FDirection  : TMirrorDirection ;    public      Constructor Create (Collection :TCollection ) ;  override ;        procedure Apply (Bitmap :TBitmap ;  const R :TRect ) ;  override ;      procedure CreateEditor (Creator :IFormCreator ; AChanged :TNotifyEvent ) ;  override ;      class  function Description :  String ;  override ;    published      property Direction :TMirrorDirection  read FDirection  write FDirection                                 default mdDown ;    end ;     TTileFilter = class (TTeeFilter )    private     FNumCols  :  Integer ;     FNumRows  :  Integer ;    public      Constructor Create (Collection :TCollection ) ;  override ;        procedure Apply (Bitmap :TBitmap ;  const R :TRect ) ;  override ;      procedure CreateEditor (Creator :IFormCreator ; AChanged :TNotifyEvent ) ;  override ;      class  function Description :  String ;  override ;    published      property NumCols : Integer  read FNumCols  write FNumCols default  3 ;      property NumRows : Integer  read FNumRows  write FNumRows default  3 ;    end ;     TBevelFilter = class (TTeeFilter )    private     FBright  :  Integer ;     FSize    :  Integer ;    public      Constructor Create (Collection :TCollection ) ;  override ;        procedure Apply (Bitmap : TBitmap ;  const R :TRect ) ;  override ;      procedure CreateEditor (Creator :IFormCreator ; AChanged :TNotifyEvent ) ;  override ;      class  function Description :  String ;  override ;    published      property Bright : Integer  read FBright  write FBright default  64 ;      property Size : Integer  read FSize  write FSize default  15 ;    end ;     TZoomFilter = class (TTeeFilter )    private     FPercent  :  Double ;     FSmooth   :  Boolean ;    public      Constructor Create (Collection :TCollection ) ;  override ;        procedure Apply (Bitmap : TBitmap ;  const R :TRect ) ;  override ;      procedure CreateEditor (Creator :IFormCreator ; AChanged :TNotifyEvent ) ;  override ;      class  function Description :  String ;  override ;    published      property Percent : Double  read FPercent  write FPercent ;      property Smooth : Boolean  read FSmooth  write FSmooth default  False ;    end ;     TImageFiltered = class (TImage )    private     FFilters  : TFilterItems ;        function FiltersStored : Boolean ;      procedure ReadFilters (Reader : TReader ) ;      procedure SetFilters ( const Value : TFilterItems ) ;      procedure WriteFilters (Writer : TWriter ) ;    protected      procedure DefineProperties (Filer :TFiler ) ;  override ;      procedure Paint ;  override ;    public      Constructor Create (AOwner :TComponent ) ;  override ;      Destructor Destroy ;  override ;        function Filtered :TBitmap ;    published      property Filters :TFilterItems  read FFilters  write SetFilters stored  False ;    end ;   var   FilterClasses  : TList ;   procedure TeeRegisterFilters ( const FilterList : Array  of TFilterClass ) ; procedure TeeUnRegisterFilters ( const FilterList : Array  of TFilterClass ) ;   procedure ColorToHLS (Color : TColor ; out Hue , Luminance , Saturation :  Word ) ; procedure RGBToHLS ( const Color : TRGB ; out Hue , Luminance , Saturation :  Word ) ;   procedure HLSToRGB (Hue , Luminance , Saturation :  Word ; out rgb : TRGB ) ; function HLSToColor (Hue , Luminance , Saturation :  Word ) :TColor ;   // Converts ABitmap pixels into Gray Scale (levels of gray) v5.02 (v8 moved from TeCanvas.pas) Procedure TeeGrayScale (ABitmap :TBitmap ; Inverted : Boolean ; AMethod : Integer ) ;   implementation   uses   Math , SysUtils , TypInfo , TeeConst ;   procedure TeeRegisterFilters ( const FilterList : Array  of TFilterClass ) ; var t  :  Integer ; begin    if  not  Assigned (FilterClasses )  then      FilterClasses : =TList . Create ;      for t : = Low (FilterList )  to  High (FilterList )  do    if FilterClasses . IndexOf ( {$IFDEF CLR}TObject{$ENDIF} (FilterList [t ] ) ) =- 1  then    begin     FilterClasses . Add ( {$IFDEF CLR}TObject{$ENDIF} (FilterList [t ] ) ) ;      RegisterClass (FilterList [t ] ) ;    end ; end ;   procedure TeeUnRegisterFilters ( const FilterList : Array  of TFilterClass ) ; var t  :  Integer ; begin    if  Assigned (FilterClasses )  then    for t : = Low (FilterList )  to  High (FilterList )  do       FilterClasses . Remove ( {$IFDEF CLR}TObject{$ENDIF} (FilterList [t ] ) ) ; end ;   { TResizeFilter }   function SmoothBitmap (Bitmap :TBitmap ; Width ,Height : Integer ) :TBitmap ; begin   result : =TBitmap . Create ;   TeeSetBitmapSize (result ,Width ,Height ) ;   SmoothStretch (Bitmap ,result ) ; end ;   procedure TResizeFilter . Apply (Bitmap :TBitmap ;  const R :TRect ) ; var tmp  : TBitmap ; begin    if  (Width> 0 )  and  (Height> 0 )  then    begin     tmp : =SmoothBitmap (Bitmap ,Width ,Height ) ;      try       TeeSetBitmapSize (Bitmap ,Width ,Height ) ;       Bitmap . Canvas . Draw ( 0 , 0 ,tmp ) ;      finally       tmp . Free ;      end ;    end ; // Do not call inherited; end ;   procedure TResizeFilter . CreateEditor (Creator : IFormCreator ;   AChanged : TNotifyEvent ) ; begin    inherited ;   Creator . AddInteger ( 'Width' ,TeeMsg_Width , 0 , 10000 ) ;  // Do not localize   Creator . AddInteger ( 'Height' ,TeeMsg_Height , 0 , 10000 ) ;  // Do not localize end ;   class  function TResizeFilter . Description :  String ; begin   result : =TeeMsg_Resize ; end ;   { TCropFilter }   procedure TCropFilter . Apply (Bitmap : TBitmap ;  const R : TRect ) ; var tmp  : TBitmap ; begin    if  (Width> 0 )  and  (Height> 0 )  then    begin     tmp : =TBitmap . Create ;      try       tmp . PixelFormat : =Bitmap . PixelFormat ;       TeeSetBitmapSize (tmp ,Width ,Height ) ;         tmp . Canvas . CopyRect (TeeRect ( 0 , 0 ,tmp . Width ,tmp . Height ) ,          Bitmap . Canvas ,TeeRect (Left ,Top ,Left +Width - 1 ,Top +Height - 1 ) ) ;          if FSmooth  then          SmoothStretch (tmp ,Bitmap )        else          Bitmap . Canvas . StretchDraw (TeeRect ( 0 , 0 ,Bitmap . Width - 1 ,Bitmap . Height - 1 ) ,tmp ) ;      finally       tmp . Free ;      end ;    end ;   // Do not call inherited; end ;   procedure TCropFilter . CreateEditor (Creator : IFormCreator ;   AChanged : TNotifyEvent ) ; begin    inherited ;   Creator . AddInteger ( 'Left' ,TeeMsg_Left , 0 , 10000 ) ;  // Do not localize   Creator . AddInteger ( 'Top' ,TeeMsg_Top , 0 , 10000 ) ;  // Do not localize   Creator . AddCheckBox ( 'Smooth' ,TeeMsg_Smooth ) ;  // Do not localize end ;   class  function TCropFilter . Description :  String ; begin   result : =TeeMsg_Crop ; end ;   { TInvertFilter } procedure TInvertFilter . Apply (Bitmap :TBitmap ;  const R :TRect ) ; var x ,:  Integer ; begin    inherited ;      if  Length (Lines ) = 0  then       Exit ;          for y : =R . Top  to R . Bottom  do      for x : =R . Left  to R . Right  do      with Lines [y ,x ]  do      begin       Blue : = 255 -Blue ;       Green : = 255 -Green ;       Red : = 255 -Red ;      end ; end ;   class  function TInvertFilter . Description :  String ; begin   result : =TeeMsg_Invert ; end ;   { TGrayScaleFilter } procedure TGrayScaleFilter . Apply (Bitmap :TBitmap ;  const R :TRect ) ; var x ,:   Integer ;     tmp  :  Byte ; begin    inherited ;      if  Length (Lines ) = 0  then       Exit ;          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 : = (Blue +Green +Red )  div  3 ;                     Blue : =tmp ;                     Green : =tmp ;                     Red : =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 *Red )  +                                  ( 0.59 *Green )  +                                  ( 0.11 *Blue ) ) ;                       Blue : =tmp ;                     Green : =tmp ;                     Red : =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 *Red + 16 *Green + 5 *Blue )  div  32 ;                     Blue : =tmp ;                     Green : =tmp ;                     Red : =tmp ;                    end ;      end ; end ;   procedure TGrayScaleFilter . CreateEditor (Creator : IFormCreator ;   AChanged : TNotifyEvent ) ; begin    inherited ;   Creator . AddCombo ( 'Method' ) ;  // Do not localize end ;   class  function TGrayScaleFilter . Description :  String ; begin   result : =TeeMsg_GrayScale ; end ;   { TMosaicFilter } constructor TMosaicFilter . Create (Collection :TCollection ) ; begin    inherited ;   FAmount : = 8 ;   IOnlyPositive : = True ; end ;   procedure TMosaicFilter . Apply (Bitmap :TBitmap ;  const R :TRect ) ;  {$IFDEF CLR}unsafe;{$ENDIF} var   tmpAmountX  :  Integer ;   tmpAmountY  :  Integer ;   tmpDims     :  Single ;      procedure DoMosaic ( const tmpX ,tmpY : Integer ) ;  {$IFDEF CLR}unsafe;{$ENDIF}    var ar ,       ag ,       ab  :  Integer ;       xx ,       yy  :  Integer ;       a     : TRGB ;       Line  : PRGBs ;    begin     ar : = 0 ;     ag : = 0 ;     ab : = 0 ;        for yy : = 0  to tmpAmountY  do      begin       Line : =Lines [tmpY +yy ] ;          for xx : = 0  to tmpAmountX  do        with Line [tmpX +xx ]  do        begin          Inc (ar ,Red ) ;          Inc (ag ,Green ) ;          Inc (ab ,Blue ) ;        end ;      end ;       a . Red : = Round (ar *tmpDims ) ;     a . Green : = Round (ag *tmpDims ) ;     a . Blue : = Round (ab *tmpDims ) ;        for yy : = 0  to tmpAmountY  do      begin       Line : =Lines [tmpY +yy ] ;        for xx : = 0  to tmpAmountX  do           Line [tmpX +xx ] : =a ;      end ;    end ;      procedure DoMosaicRow ( const tmpY : Integer ) ;    var tmpX  :  Integer ;    begin     tmpX : =R . Left ;      while tmpX<R . Right -Amount  do      begin       DoMosaic (tmpX ,tmpY ) ;        Inc (tmpX ,Amount ) ;      end ;        // Remainder horizontal mosaic cell      if tmpX<R . Right  then      begin       tmpAmountX : =R . Right -tmpX ;       tmpDims : = 1.0 / ( Succ (tmpAmountX ) * Succ (tmpAmountY ) ) ;         DoMosaic (tmpX ,tmpY ) ;         tmpAmountX : =tmpAmountY ;       tmpDims : = 1.0 / Sqr (Amount ) ;      end ;    end ;   var tmpY  :  Integer ; begin    inherited ;      if  Length (Lines ) = 0  then       Exit ;      if Amount> 0  then    begin     tmpDims : = 1.0 / Sqr (Amount ) ;     tmpAmountX : =Amount - 1 ;     tmpAmountY : =tmpAmountX ;       tmpY : =R . Top ;      while tmpY<R . Bottom -Amount  do      begin       DoMosaicRow (tmpY ) ;        Inc (tmpY ,Amount ) ;      end ;        // Remainder vertical mosaic row cells      if tmpY<R . Bottom  then      begin       tmpAmountY : =R . Bottom -tmpY - 1 ;       tmpDims : = 1.0 / ( Succ (tmpAmountX ) * Succ (tmpAmountY ) ) ;       DoMosaicRow (tmpY ) ;      end ;    end ; end ;   class  function TMosaicFilter . Description :  String ; begin   result : =TeeMsg_Mosaic ; end ;   { TFlipFilter } procedure TFlipFilter . Apply (Bitmap :TBitmap ;  const R :TRect ) ;  {$IFDEF CLR}unsafe;{$ENDIF} var tmp  : TRGB ;     tmpH ,     tmpY ,     x ,:  Integer ; begin    inherited ;      if  Length (Lines ) = 0  then       Exit ;     tmpH : =R . Bottom -R . Top ;      for y : =R . Top  to R . Top + (tmpH  div  2 ) - 1  do        for x : =R . Left  to R . Right  do        begin         tmp : =Lines [y ,x ] ;         tmpY : =tmpH -y ;         Lines [y ,x ] : =Lines [tmpY ,x ] ;         Lines [tmpY ,x ] : =tmp ;        end ; end ;   class  function TFlipFilter . Description :  String ; begin   result : =TeeMsg_Flip ; end ;   { TReverseFilter } procedure TReverseFilter . Apply (Bitmap :TBitmap ;  const R :TRect ) ; var tmp  : TRGB ;     tmpW ,     tmpX ,     x ,:  Integer ; begin    inherited ;      if  Length (Lines ) = 0  then       Exit ;         tmpW : =R . Right -R . Left ;      for x : =R . Left  to R . Left + (tmpW  div  2 ) - 1  do        for y : =R . Top  to R . Bottom  do        begin         tmp : =Lines [y ,x ] ;         tmpX : =tmpW -x ;         Lines [y ,x ] : =Lines [y ,tmpX ] ;         Lines [y ,tmpX ] : =tmp ;        end ; end ;   class  function TReverseFilter . Description :  String ; begin   result : =TeeMsg_Reverse ; end ;   { TAmountFilter } Constructor TAmountFilter . Create (Collection :TCollection ) ; begin    inherited ;   FPercent : = True ;   FAmount : = 5 ;  // % end ;   function TAmountFilter . ScrollMin : Integer ; begin    if FPercent  then       if IOnlyPositive  then result : = 0  else result : =- 100    else       if IOnlyPositive  then result : = 0  else result : =- 255 ; end ;   function TAmountFilter . ScrollMax : Integer ; begin    if FPercent  then result : = 100                else result : = 255 ; end ;   procedure TAmountFilter . ResetScroll (Sender : TObject ) ; begin   FScrollBar . Min : =ScrollMin ;   FScrollBar . Max : =ScrollMax ; end ;   procedure TAmountFilter . CreateEditor (Creator :IFormCreator ; AChanged :TNotifyEvent ) ; begin    inherited ;   FScrollBar : =Creator . AddScroll ( 'Amount' ,ScrollMin ,ScrollMax ) ;  // Do not localize   Creator . AddCheckBox ( 'Percent' ,TeeMsg_Percent ,ResetScroll ) ;  // Do not localize end ;   { TBrightnessFilter } procedure TBrightnessFilter . Apply (Bitmap :TBitmap ;  const R : TRect ) ; var x ,y ,:   Integer ;     IPercent  :  Single ; begin    if Amount = 0  then       Exit ;      inherited ;      if  Length (Lines ) = 0  then       Exit ;      if Percent  then    begin     IPercent : =FAmount * 0.01 ;        for y : =R . Top  to R . Bottom  do          for x : =R . Left  to R . Right  do          with Lines [y ,x ]  do          begin           l : =Red + Round ( 255 *IPercent ) ;            if l< 0  then Red : = 0  else  if l> 255  then Red : = 255  else Red : =l ;             l : =Green + Round ( 255 *IPercent ) ;            if l< 0  then Green : = 0  else  if l> 255  then Green : = 255  else Green : =l ;             l : =Blue + Round ( 255 *IPercent ) ;            if l< 0  then Blue : = 0  else  if l> 255  then Blue : = 255  else Blue : =l ;          end ;    end    else    for y : =R . Top  to R . Bottom  do        for x : =R . Left  to R . Right  do        with Lines [y ,x ]  do        begin         l : =Red +Amount ;          if l< 0  then Red : = 0  else  if l> 255  then Red : = 255  else Red : =l ;           l : =Green +Amount ;          if l< 0  then Green : = 0  else  if l> 255  then Green : = 255  else Green : =l ;           l : =Blue +Amount ;          if l< 0  then Blue : = 0  else  if l> 255  then Blue : = 255  else Blue : =l ;        end ; end ;   class  function TBrightnessFilter . Description :  String ; begin   result : =TeeMsg_Brightness ; end ;   procedure ColorToHLS (Color : TColor ; out Hue , Luminance , Saturation :  Word ) ; var tmp  : TRGB ; begin   Color : =ColorToRGB (Color ) ;   tmp . Red : =GetRValue (Color ) ;   tmp . Green : =GetGValue (Color ) ;   tmp . Blue : =GetBValue (Color ) ;   RGBToHLS (tmp ,Hue ,Luminance ,Saturation ) ; 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 : TRGB ; out 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 . Red ;   G : =Color . Green ;   B : =Color . Blue ;      { calculate lightness }    if R>G  then       if R>B  then cMax : =else cMax : =B    else       if G>B  then cMax : =else cMax : =B ;      if R<G  then       if R<B  then cMin : =else cMin : =B    else       if G<B  then cMin : =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 ColoroHLS 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 ;   function HLSToColor (Hue , Luminance , Saturation :  Word ) :TColor ; var tmp  : TRGB ; begin   HLSToRGB (Hue ,Luminance ,Saturation ,tmp ) ;   result : =RGB (tmp . Red ,tmp . Green ,tmp . Blue ) ; end ;   procedure HLSToRGB (Hue , Luminance , Saturation :  Word ; out rgb : TRGB ) ;      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 :  Integer ) :  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 ( Round ( (HueToRGB (Magic1 ,Magic2 ,Hue ) *RGBMAX  + HLSMAXDiv2 ) /HLSMAX ) ) ;    end ;   begin    if Saturation  =  0  then    with rgb  do    begin             { achromatic case }     Red  : = RoundColor ( Round ( (Luminance  * RGBMAX ) /HLSMAX )  ) ;     Green : =Red ;     Blue : =Green ;      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 . Red : =RoundColor2 (Hue +HLSMAXDiv3 ) ;     rgb . Green : =RoundColor2 (Hue ) ;     rgb . Blue : =RoundColor2 (Hue -HLSMAXDiv3 ) ;    end ; end ;   { TColorFilter }   procedure TColorFilter . Apply (Bitmap :TBitmap ;  const R : TRect ) ;  {$IFDEF CLR}unsafe;{$ENDIF} var x ,y     :  Integer ;     tmpInt  :  Integer ;     Line    : PRGBs ; begin    inherited ;      if  Length (Lines ) = 0  then       Exit ;      if  (Red<> 0 )  or  (Green<> 0 )  or  (Blue<> 0 )  then    for y : =R . Top  to R . Bottom  do    begin     Line : =Lines [y ] ;        for x : =R . Left  to R . Right  do      with Line [x ]  do      begin        if  Self . FRed<> 0  then        begin         tmpInt : =Red + Self . FRed ;          if tmpInt< 0  then Red : = 0  else          if tmpInt> 255  then Red : = 255  else                            Red : =tmpInt ;        end ;          if  Self . FGreen<> 0  then        begin         tmpInt : =Green + Self . FGreen ;          if tmpInt< 0  then Green : = 0  else          if tmpInt> 255  then Green : = 255  else                            Green : =tmpInt ;        end ;          if  Self . FBlue<> 0  then        begin         tmpInt : =Blue + Self . FBlue ;          if tmpInt< 0  then Blue : = 0  else          if tmpInt> 255  then Blue : = 255  else                            Blue : =tmpInt ;        end ;      end ;    end ; end ;   procedure TColorFilter . CreateEditor (Creator : IFormCreator ;   AChanged : TNotifyEvent ) ; begin    inherited ;   Creator . AddScroll ( 'Red' , - 255 , 255 ) ;  // Do not localize   Creator . AddScroll ( 'Green' , - 255 , 255 ) ;  // Do not localize   Creator . AddScroll ( 'Blue' , - 255 , 255 ) ;  // Do not localize end ;   class  function TColorFilter . Description :  String ; begin   result : =TeeMsg_Color ; end ;   { THueLumSatFilter }   procedure THueLumSatFilter . Apply (Bitmap :TBitmap ;  const R : TRect ) ;  {$IFDEF CLR}unsafe;{$ENDIF} var x ,y     :  Integer ;     tmpInt  :  Integer ;     tmpHue  :  Word ;     tmpLum  :  Word ;     tmpSat  :  Word ;     Line    : PRGBs ; begin    inherited ;      if  Length (Lines ) = 0  then       Exit ;      if  (FHue<> 0 )  or  (FLum<> 0 )  or  (FSat<> 0 )  then    for y : =R . Top  to R . Bottom  do    begin     Line : =Lines [y ] ;        for x : =R . Left  to R . Right  do      begin       RGBToHLS (Line [x ] ,tmpHue ,tmpLum ,tmpSat ) ;          if  Self . FHue<> 0  then        begin         tmpInt : =tmpHue + Self . FHue ;          if tmpInt< 0  then tmpHue : = 0  else          if tmpInt> 255  then tmpHue : = 255  else                            tmpHue : =tmpInt ;        end ;          if  Self . FLum<> 0  then        begin         tmpInt : =tmpLum + Self . FLum ;          if tmpInt< 0  then tmpLum : = 0  else          if tmpInt> 255  then tmpLum : = 255  else                            tmpLum : =tmpInt ;        end ;          if  Self . FSat<> 0  then        begin         tmpInt : =tmpSat + Self . FSat ;          if tmpInt< 0  then tmpSat : = 0  else          if tmpInt> 255  then tmpSat : = 255  else                            tmpSat : =tmpInt ;        end ;         HLSToRGB (tmpHue ,tmpLum ,tmpSat ,Line [x ] ) ;      end ;    end ; end ;   procedure THueLumSatFilter . CreateEditor (Creator : IFormCreator ;   AChanged : TNotifyEvent ) ; begin    inherited ;   Creator . AddScroll ( 'Hue' , - 255 , 255 ) ;  // Do not localize   Creator . AddScroll ( 'Luminance' , - 255 , 255 ) ;  // Do not localize   Creator . AddScroll ( 'Saturation' , - 255 , 255 ) ;  // Do not localize end ;   class  function THueLumSatFilter . Description :  String ; begin   result : =TeeMsg_HueLumSat ; end ;   { TSharpenFilter }   procedure TSharpenFilter . Apply (Bitmap :TBitmap ;  const R : TRect ) ; const Center = 2.0 ;       Pix =- ( (Center - 1 ) / 8.0 ) ; begin   Weights [ - 1 , - 1 ] : =Pix ;  Weights [ - 1 , 0 ] : =Pix ;    Weights [ - 1 , 1 ] : =Pix ;   Weights [  0 , - 1 ] : =Pix ;  Weights [  0 , 0 ] : =Center ; Weights [  0 , 1 ] : =Pix ;   Weights [  1 , - 1 ] : =Pix ;  Weights [  1 , 0 ] : =Pix ;    Weights [  1 , 1 ] : =Pix ;     InvTotalWeight : = 1.0 / 16.0 ;      inherited ; end ;   class  function TSharpenFilter . Description :  String ; begin   result : =TeeMsg_Sharpen ; end ;   { TGammaCorrectionFilter } Constructor TGammaCorrectionFilter . Create (Collection :TCollection ) ; begin    inherited ;   FAmount : = 70 ;   IOnlyPositive : = True ; end ;   procedure TGammaCorrectionFilter . Apply (Bitmap :TBitmap ;  const R : TRect ) ; var t ,     x ,y     :  Integer ;     IGamma  :  Array [ 0 .. 255 ]  of  Byte ;     tmp     :  Single ; begin    inherited ;      if  Length (Lines ) = 0  then       Exit ;     tmp : = Max ( 0.001 , Abs (Amount ) * 0.01 ) ;     IGamma [ 0 ] : = 0 ;    for t : = 1  to  255  do       IGamma [t ] : = Round ( Exp ( Ln (t / 255.0 ) /tmp ) * 255.0 ) ;      for y : =R . Top  to R . Bottom  do      for x : =R . Left  to R . Right  do      with Lines [y ,x ]  do      begin       Red : =IGamma [Red ] ;       Green : =IGamma [Green ] ;       Blue : =IGamma [Blue ] ;      end ; end ;   class  function TGammaCorrectionFilter . Description :  String ; begin   result : =TeeMsg_GammaCorrection ; end ;   { TEmbossFilter }   procedure TEmbossFilter . Apply (Bitmap :TBitmap ;  const R : TRect ) ; begin   Weights [ - 1 , - 1 ] : =  0 ;  Weights [ - 1 , 0 ] : =- 1 ;    Weights [ - 1 , 1 ] : = 0 ;   Weights [  0 , - 1 ] : =- 1 ;  Weights [  0 , 0 ] : = 1 ;     Weights [  0 , 1 ] : = 1 ;   Weights [  1 , - 1 ] : =  0 ;  Weights [  1 , 0 ] : =- 1 ;    Weights [  1 , 1 ] : = 0 ;     InvTotalWeight : = 1.0 / 1.0 ;      inherited ; end ;   class  function TEmbossFilter . Description :  String ; begin   result : =TeeMsg_Emboss ; end ;   { TContrastFilter }   procedure TContrastFilter . Apply (Bitmap :TBitmap ;  const R : TRect ) ; var x ,y ,:   Integer ;     IPercent  :  Single ; begin    inherited ;      if  Length (Lines ) = 0  then       Exit ;      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 : =Red + ( Round (Red *IPercent ) * (Red - 128 )  div  256 )                     else l : =Red + (Amount * (Red - 128 )  div  256 ) ;            if l< 0  then Red : = 0  else  if l> 255  then Red : = 255  else Red : =l ;            if Percent  then l : =Green + ( Round (Green *IPercent ) * (Green - 128 )  div  256 )                     else l : =Green + (Amount * (Green - 128 )  div  256 ) ;            if l< 0  then Green : = 0  else  if l> 255  then Green : = 255  else Green : =l ;            if Percent  then l : =Blue + ( Round (Blue *IPercent ) * (Blue - 128 )  div  256 )                     else l : =Blue + (Amount * (Blue - 128 )  div  256 ) ;            if l< 0  then Blue : = 0  else  if l> 255  then Blue : = 255  else Blue : =l ;        end ; end ;   class  function TContrastFilter . Description :  String ; begin   result : =TeeMsg_Contrast ; end ;   { TSoftenFilter }   procedure TSoftenFilter . Apply (Bitmap :TBitmap ;  const R : TRect ) ; begin   Weights [ - 1 , - 1 ] : = 0 ;  Weights [ - 1 , 0 ] : = 0 ;    Weights [ - 1 , 1 ] : = 0 ;   Weights [  0 , - 1 ] : = 0 ;  Weights [  0 , 0 ] : = 1 ;    Weights [  0 , 1 ] : = 1 ;   Weights [  1 , - 1 ] : = 0 ;  Weights [  1 , 0 ] : = 1 ;    Weights [  1 , 1 ] : = 1 ;     InvTotalWeight : = 1.0 / 4.0 ;      inherited ; end ;   class  function TSoftenFilter . Description :  String ; begin   result : =TeeMsg_AntiAlias ; end ;   { TImageFiltered }   Constructor TImageFiltered . Create (AOwner : TComponent ) ; begin    inherited ;   FFilters : =TFilterItems . Create ( Self ,TTeeFilter ) ; end ;   Destructor TImageFiltered . Destroy ; begin   FFilters . Free ;    inherited ; end ;   function TImageFiltered . Filtered :TBitmap ; var tmpDest  : TBitmap ;     tmpR     : TRect ;     tmpW     :  Integer ;     tmpH     :  Integer ; begin   result : =TBitmap . Create ;   result . Assign (Picture . Graphic ) ;     tmpR : =DestRect ;   tmpW : =tmpR . Right -tmpR . Left ;   tmpH : =tmpR . Bottom -tmpR . Top ;      if  (tmpW<>result . Width )  or  (tmpH<>result . Height )  then    begin     tmpDest : =SmoothBitmap (result ,tmpW ,tmpH ) ;     result . Free ;     result : =tmpDest ;    end ;     FFilters . ApplyTo (result ) ; end ;   procedure TImageFiltered . SetFilters ( const Value : TFilterItems ) ; begin   FFilters . Assign (Value ) ; end ;   procedure TImageFiltered . Paint ; var tmpCanvas  : TCanvas ;     tmp        : TGraphic ; begin   tmp : =Filtered ;    try     tmpCanvas : =TControlCanvas . Create ;      try       TControlCanvas (tmpCanvas ) . Control : = Self ;       tmpCanvas . Draw ( 0 , 0 ,tmp ) ;          if csDesigning  in ComponentState  then        with tmpCanvas  do        begin         Pen . Style : =psDash ;         Brush . Style : =bsClear ;            {$IFDEF CLX}         Start ;         QPainter_setBackgroundMode (Handle ,BGMode_TransparentMode ) ;         Stop ;          {$ELSE}         SetBkMode (Handle ,Windows . TRANSPARENT ) ;          {$ENDIF}            with ClientRect  do              Rectangle (Left ,Top ,Right ,Bottom ) ;        end ;      finally       tmpCanvas . Free ;      end ;    finally     tmp . Free ;    end ; end ;   procedure TImageFiltered . ReadFilters (Reader : TReader ) ; begin   TTeePicture . ReadFilters (Reader ,Filters ) ; end ;   procedure TImageFiltered . WriteFilters (Writer : TWriter ) ; begin   TTeePicture . WriteFilters (Writer ,Filters ) ; end ;   function TImageFiltered . FiltersStored : Boolean ; begin   result : = Assigned (FFilters )  and  (FFilters . Count> 0 ) ; end ;   procedure TImageFiltered . DefineProperties (Filer : TFiler ) ; begin    inherited ;   Filer . DefineProperty ( 'FilterItems' ,ReadFilters ,WriteFilters ,FiltersStored ) ;   // Do not localize end ;   { TRotateFilter }   Constructor TRotateFilter . Create (Collection :TCollection ) ; begin    inherited ;   FBackColor : =clWhite ;   FAutoSize : = True ; end ;   procedure TRotateFilter . Apply (Bitmap : TBitmap ;  const R : TRect ) ;  {$IFDEF CLR}unsafe;{$ENDIF} const   TeePiStep : Single = Pi / 180.0 ;   var tmp  : TBitmap ;     x ,     y ,     xc ,     yc ,     xxc ,     yyc ,     tmpY ,     tmpX ,     h ,     w    :  Integer ;       f2  : TTeeFilter ;       f2Lines  : PRGBs ;       xx ,     yy  :  Integer ;       tmpSin ,     tmpCos ,     tmpYSin ,     tmpYCos   :  Single ;        Sin ,      Cos  :  Extended ; begin    inherited ;      if  Length (Lines ) = 0  then       Exit ;      while Angle> 360  do         FAngle : =Angle - 360 ;      if Angle = 180  then    begin     TFlipFilter . ApplyTo (Bitmap ) ;     TReverseFilter . ApplyTo (Bitmap ) ;    end    else    if Angle<> 0  then    begin     tmp : =TBitmap . Create ;      try       h : =Bitmap . Height ;       w : =Bitmap . Width ;          if  (Angle = 90 )  or  (Angle = 270 )  then          TeeSetBitmapSize (tmp ,h ,w )        else        begin          SinCos ( ( 360 -Angle ) *TeePiStep , Sin , Cos ) ;            if AutoSize  then          begin            if  Sin *Cos> 0  then              TeeSetBitmapSize (tmp , Abs ( Round (w * Cos +h * Sin ) ) ,                                    Abs ( Round (w * Sin +h * Cos ) ) )            else              TeeSetBitmapSize (tmp , Abs ( Round (w *Cos -h * Sin ) ) ,                                    Abs ( Round (w *Sin -h * Cos ) ) ) ;          end          else           TeeSetBitmapSize (tmp ,w ,h ) ;        end ;          if  (w> 1 )  and  (h> 1 )  then        begin          if BackColor =clNone  then            tmp . Transparent : = True          else          if BackColor<>clWhite  then          with tmp . Canvas  do          begin           Brush . Style : =bsSolid ;           Brush . Color : =FBackColor ;           FillRect (TeeRect ( 0 , 0 ,tmp . Width ,tmp . Height ) ) ;          end ;           f2 : =TTeeFilter . Create ( nil ) ;          try           f2 . Apply (tmp ) ;              if Angle = 90  then            begin              for y : = 0  to h - 1  do                  for x : = 0  to w - 1  do                     f2 . Lines [x ,h -y - 1 ] : =Lines [y ,x ] ;            end            else            if Angle = 270  then            begin              for y : = 0  to h - 1  do                  for x : = 0  to w - 1  do                     f2 . Lines [w -x - 1 ,y ] : =Lines [y ,x ] ;            end            else            begin             xxc : =tmp . Width  div  2 ;             yyc : =tmp . Height  div  2 ;               xc : =div  2 ;             yc : =div  2 ;               tmpSin : = Sin ;             tmpCos : = Cos ;               tmpY : =-yyc - 1 ;                for y : = 0  to tmp . Height - 1  do              begin                Inc (tmpY ) ;               tmpYSin : = (tmpY *tmpSin ) -xc ;               tmpYCos : = (tmpY *tmpCos ) +yc ;                 f2Lines : =f2 . Lines [y ] ;                 tmpX : =-xxc - 1 ;                  for x : = 0  to tmp . Width - 1  do                begin                  Inc (tmpX ) ;                   xx : = Round (tmpX *tmpCos -tmpYSin ) ;                    if  (xx> = 0 )  and  (xx<w )  then                  begin                   yy : = Round (tmpX *tmpSin +tmpYCos ) ;                      if  (yy> = 0 )  and  (yy<h )  then                      f2Lines [x ] : =Lines [yy ,xx ] ;                  end ;                end ;              end ;            end ;             Bitmap . FreeImage ;           Bitmap . Assign (tmp ) ;          finally           f2 . Free ;          end ;        end ;      finally       tmp . Free ;      end ;    end ; end ;   class  function TRotateFilter . Description :  String ; begin   result : =TeeMsg_Rotate ; end ;   procedure TRotateFilter . SetAngle ( const Value :  Double ) ; begin    if FAngle<>Value  then    begin     FAngle : =Value ;      // Repaint;    end ; end ;   procedure TRotateFilter . CreateEditor (Creator :IFormCreator ; AChanged : TNotifyEvent ) ; begin    inherited ;   Creator . AddScroll ( 'Angle' , 0 , 360 ) ;  // Do not localize   Creator . AddColor ( 'BackColor' ,TeeMsg_Back ) ;  // Do not localize   Creator . AddCheckBox ( 'AutoSize' ,TeeMsg_Autosize ) ;  // Do not localize end ;   { TMirrorFilter }   Constructor TMirrorFilter . Create (Collection : TCollection ) ; begin    inherited ;   AllowRegion : = False ; end ;   procedure TMirrorFilter . Apply (Bitmap : TBitmap ;  const R : TRect ) ; var tmp  : TBitmap ; begin    inherited ;      if  Length (Lines ) = 0  then       Exit ;     tmp : =TBitmap . Create ;    try      if  (Direction =mdDown )  or  (Direction =mdUp )  then      begin       TeeSetBitmapSize (tmp ,Bitmap . Width ,Bitmap . Height * 2 ) ;          if Direction =mdDown  then          tmp . Canvas . Draw ( 0 , 0 ,Bitmap )        else          tmp . Canvas . Draw ( 0 ,Bitmap . Height ,Bitmap ) ;         TFlipFilter . ApplyTo (Bitmap ) ;          if Direction =mdDown  then          tmp . Canvas . Draw ( 0 ,Bitmap . Height ,Bitmap )        else          tmp . Canvas . Draw ( 0 , 0 ,Bitmap ) ;         Bitmap . Height : =Bitmap . Height * 2 ;      end      else      begin       TeeSetBitmapSize (tmp ,Bitmap . Width * 2 ,Bitmap . Height ) ;          if Direction =mdRight  then          tmp . Canvas . Draw ( 0 , 0 ,Bitmap )        else          tmp . Canvas . Draw (Bitmap . Width , 0 ,Bitmap ) ;         TReverseFilter . ApplyTo (Bitmap ) ;          if Direction =mdRight  then          tmp . Canvas . Draw (Bitmap . Width , 0 ,Bitmap )        else          tmp . Canvas . Draw ( 0 , 0 ,Bitmap ) ;         Bitmap . Width : =Bitmap . Width * 2 ;      end ;       Bitmap . Canvas . Draw ( 0 , 0 ,tmp ) ;    finally     tmp . Free ;    end ; end ;   procedure TMirrorFilter . CreateEditor (Creator : IFormCreator ;   AChanged : TNotifyEvent ) ; begin    inherited ;   Creator . AddCombo ( 'Direction' ) ;  // Do not localize end ;   class  function TMirrorFilter . Description :  String ; begin   result : =TeeMsg_Mirror ; end ;   { TTileFilter }   Constructor TTileFilter . Create (Collection : TCollection ) ; begin    inherited ;   FNumCols : = 3 ;   FNumRows : = 3 ; end ;   procedure TTileFilter . Apply (Bitmap : TBitmap ;  const R : TRect ) ; var tmpCol ,     tmpRow ,     tmpW ,     tmpH  :  Integer ;     tmp   : TBitmap ; begin    inherited ;      if  Length (Lines ) = 0  then       Exit ;      if FNumCols< 1  then FNumCols : = 1 ;    if FNumRows< 1  then FNumRows : = 1 ;     tmpW : = (R . Right -R . Left )  div FNumCols ;   tmpH : = (R . Bottom -R . Top )  div FNumRows ;      if  (tmpW> 0 )  and  (tmpH> 0 )  then    begin     tmp : =SmoothBitmap (Bitmap ,tmpW ,tmpH ) ;      try        for tmpCol : = 0  to FNumCols - 1  do            for tmpRow : = 0  to FNumRows - 1  do               Bitmap . Canvas . Draw (tmpCol *tmpW ,tmpRow *tmpH ,tmp ) ;      finally       tmp . Free ;      end ;    end ; end ;   procedure TTileFilter . CreateEditor (Creator : IFormCreator ;   AChanged : TNotifyEvent ) ; begin    inherited ;   Creator . AddInteger ( 'NumCols' ,TeeMsg_Columns , 1 , 1000 ) ;  // Do not localize   Creator . AddInteger ( 'NumRows' ,TeeMsg_Rows , 1 , 1000 ) ;  // Do not localize end ;   class  function TTileFilter . Description :  String ; begin   result : =TeeMsg_Tile ; end ;   { TBevelFilter }   Constructor TBevelFilter . Create (Collection : TCollection ) ; begin    inherited ;   FBright : = 64 ;   FSize : = 15 ; end ;   procedure TBevelFilter . Apply (Bitmap : TBitmap ;  const R : TRect ) ; var t ,     x ,y ,     h2 ,w2 ,     x1 ,x2 ,     y1 ,y2  :  Integer ; begin    inherited ;      if  Length (Lines ) = 0  then       Exit ;     x1 : =R . Left ;   x2 : =R . Right ;   y1 : =R . Top ;   y2 : =R . Bottom ;     w2 : = (R . Right -R . Left )  div  2 ;   h2 : = (R . Bottom -R . Top )  div  2 ;      for t : = 0  to FSize - 1  do    begin      if t<h2  then      for x : =R . Left +to R . Right -do      begin        with Lines [y1 ,x ]  do        begin          if Red +Bright> 255  then Red : = 255                            else  Inc (Red ,Bright ) ;          if Green +Bright> 255  then Green : = 255                              else  Inc (Green ,Bright ) ;          if Blue +Bright> 255  then Blue : = 255                             else  Inc (Blue ,Bright ) ;        end ;          with Lines [y2 ,x ]  do        begin          if Red -Bright< 0  then Red : = 0                          else  Dec (Red ,Bright ) ;          if Green -Bright< 0  then Green : = 0                            else  Dec (Green ,Bright ) ;          if Blue -Bright< 0  then Blue : = 0                           else  Dec (Blue ,Bright ) ;        end ;        end ;        Inc (y1 ) ;      Dec (y2 ) ;        if t<w2  then      for y : =R . Top +t + 1  to R . Bottom -do      begin        with Lines [y ,x1 ]  do        begin          if Red +Bright> 255  then Red : = 255                            else  Inc (Red ,Bright ) ;          if Green +Bright> 255  then Green : = 255                              else  Inc (Green ,Bright ) ;          if Blue +Bright> 255  then Blue : = 255                             else  Inc (Blue ,Bright ) ;        end ;          with Lines [y ,x2 ]  do        begin          if Red -Bright< 0  then Red : = 0                          else  Dec (Red ,Bright ) ;          if Green -Bright< 0  then Green : = 0                            else  Dec (Green ,Bright ) ;          if Blue -Bright< 0  then Blue : = 0                           else  Dec (Blue ,Bright ) ;        end ;      end ;        Inc (x1 ) ;      Dec (x2 ) ;    end ; end ;   procedure TBevelFilter . CreateEditor (Creator : IFormCreator ;   AChanged : TNotifyEvent ) ; begin    inherited ;   Creator . AddScroll ( 'Bright' , 1 , 255 ) ;  // Do not localize   Creator . AddScroll ( 'Size' , 1 , 1000 ) ;  // Do not localize end ;   class  function TBevelFilter . Description :  String ; begin   result : =TeeMsg_Bevel ; end ;   { TZoomFilter }   Constructor TZoomFilter . Create (Collection : TCollection ) ; begin    inherited ;   FPercent : = 10 ; end ;   procedure TZoomFilter . Apply (Bitmap : TBitmap ;  const R : TRect ) ; var w ,h ,     wp ,hp  :  Integer ;      procedure DoCrop (ALeft ,ATop : Integer ; ABitmap :TBitmap ) ;    begin      with TCropFilter . Create ( nil )  do      try       Left : =ALeft +wp ;       Top : =ATop +hp ;       Width : = Max ( 1 ,w - 2 *wp ) ;       Height : = Max ( 1 ,h - 2 *hp ) ;       Smooth : = Self . Smooth ;       Apply (ABitmap ,R ) ;      finally       Free ;      end ;    end ;   var tmp  : TBitmap ; begin   w : =R . Right -R . Left + 1 ;   h : =R . Bottom -R . Top + 1 ;   wp : = Round (FPercent *w * 0.005 ) ;   hp : = Round (FPercent *h * 0.005 ) ;      if  (Bitmap . Width =w )  and  (Bitmap . Height =h )  then      DoCrop (R . Left ,R . Top ,Bitmap )    else    begin     tmp : =TBitmap . Create ;      try       TeeSetBitmapSize (tmp ,w ,h ) ;       tmp . Canvas . CopyRect (TeeRect ( 0 , 0 ,w ,h ) ,Bitmap . Canvas ,R ) ;         DoCrop ( 0 , 0 ,tmp ) ;         Bitmap . Canvas . Draw (R . Left ,R . Top ,tmp ) ;      finally       tmp . Free ;      end ;    end ; end ;   procedure TZoomFilter . CreateEditor (Creator : IFormCreator ;   AChanged : TNotifyEvent ) ; begin    inherited ;   Creator . AddScroll ( 'Percent' , 0 , 100 ) ;  // Do not localize   Creator . AddCheckBox ( 'Smooth' ,TeeMsg_Smooth ) ;  // Do not localize end ;   class  function TZoomFilter . Description :  String ; begin   result : =TeeMsg_Zoom ; end ;   procedure RotateGradient (Gradient :TCustomTeeGradient ; ABitmap :TBitmap ) ; begin    with TRotateFilter . Create ( nil )  do    try     Angle : =Gradient . Angle ;     Apply (ABitmap ) ;    finally     Free ;    end ; end ;   // This procedure will convert all pixels in ABitmap to levels of gray Procedure TeeGrayScale (ABitmap :TBitmap ; Inverted : Boolean ; AMethod : Integer ) ; var tmp  : TGrayScaleFilter ; begin   tmp : =TGrayScaleFilter . Create ( nil ) ;    try      if AMethod<> 0  then tmp . Method : =gmEye ;     tmp . Apply (ABitmap ) ;    finally     tmp . Free ;    end ;      if Inverted  then      TInvertFilter . ApplyTo (ABitmap ) ; end ;   initialization   TeeRegisterFilters ( [ TInvertFilter ,                        TGrayScaleFilter ,                        TMosaicFilter ,                        TFlipFilter ,                        TReverseFilter ,                        TBrightnessFilter ,                        TContrastFilter ,                        TColorFilter ,                        THueLumSatFilter ,                        TBlurFilter ,                        TSharpenFilter ,                        TGammaCorrectionFilter ,                        TEmbossFilter ,                        TSoftenFilter ,                        TCropFilter ,                        TResizeFilter ,                        TRotateFilter ,                        TMirrorFilter ,                        TTileFilter ,                        TBevelFilter ,                        TZoomFilter  ] ) ;     TeeGradientRotate : =RotateGradient ; finalization   TeeGradientRotate : = nil ;    FreeAndNil (FilterClasses ) ; end .    
转载请注明原文地址: https://www.6miu.com/read-50540.html

最新回复(0)