📄 teefilters.pas
字号:
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:=w div 2;
yc:=h 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+t to R.Right-t 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-t 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.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -