📄 fcdbimager.pas
字号:
unit fcdbimager;
{
//
// Components : TfcImager
//
// Copyright (c) 1999 by Woll2Woll Software
// 4/21/99 - RSW - Added CopyToClipboard method
// 8/2/99 - Check if parent is nil in BitmapChange event.
}
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
fcCommon, fcBitmap, fcChangeLink;
{$i fcIfDef.pas}
type
TfcImagerDrawStyle = (dsNormal, dsCenter, dsStretch, dsTile, dsProportional);
TfcBitmapOptions = class;
TfcRotate = class(TPersistent)
private
FBitmapOptions: TfcBitmapOptions;
FCenterX: Integer;
FCenterY: Integer;
FAngle: Integer;
procedure SetAngle(Value: Integer);
procedure SetCenterX(Value: Integer);
procedure SetCenterY(Value: Integer);
public
constructor Create(BitmapOptions: TfcBitmapOptions);
published
property CenterX: Integer read FCenterX write SetCenterX;
property CenterY: Integer read FCenterY write SetCenterY;
property Angle: Integer read FAngle write SetAngle;
end;
TfcAlphaBlend = class(TPersistent)
private
FBitmapOptions: TfcBitmapOptions;
FAmount: Byte;
FBitmap: TfcBitmap;
FChanging: Boolean;
function GetTransparent: Boolean;
procedure SetAmount(Value: Byte);
procedure SetBitmap(Value: TfcBitmap);
procedure SetTransparent(Value: Boolean);
protected
procedure BitmapChanged(Sender: TObject); virtual;
public
constructor Create(BitmapOptions: TfcBitmapOptions);
destructor Destroy; override;
published
property Amount: Byte read FAmount write SetAmount;
property Bitmap: TfcBitmap read FBitmap write SetBitmap;
property Transparent: Boolean read GetTransparent write SetTransparent;
end;
TfcWave = class(TPersistent)
private
FBitmapOptions: TfcBitmapOptions;
FXDiv, FYDiv, FRatio: Integer;
FWrap: Boolean;
procedure SetXDiv(Value: Integer);
procedure SetYDiv(Value: Integer);
procedure SetRatio(Value: Integer);
procedure SetWrap(Value: Boolean);
public
constructor Create(BitmapOptions: TfcBitmapOptions);
published
property XDiv: Integer read FXDiv write SetXDiv;
property YDiv: Integer read FYDiv write SetYDiv;
property Ratio: Integer read FRatio write SetRatio;
property Wrap: Boolean read FWrap write SetWrap;
end;
TfcBitmapOptions = class(TPersistent)
private
FComponent: TComponent;
FAlphaBlend: TfcAlphaBlend;
FColor: TColor;
FContrast: Integer;
FEmbossed: Boolean;
FTintColor: TColor;
FGaussianBlur: Integer;
FGrayScale: Boolean;
FHorizontallyFlipped: Boolean;
FInverted: Boolean;
FLightness: Integer;
FRotation: TfcRotate;
FSaturation: Integer;
FSharpen: Integer;
FSponge: Integer;
FTile: Boolean;
FVerticallyFlipped: Boolean;
FWave: TfcWave;
FOnChange: TNotifyEvent;
FOrigPicture: TPicture;
FDestBitmap: TfcBitmap;
FUpdateLock: Integer;
// Property Access methods;
procedure SetColor(Value: TColor);
procedure SetBooleanProperty(Index: Integer; Value: Boolean);
procedure SetTintColor(Value: TColor);
procedure SetIntegralProperty(Index: Integer; Value: Integer);
public
constructor Create(AComponent: TComponent);
destructor Destroy; override;
procedure BeginUpdate; virtual;
procedure Changed; virtual;
procedure EndUpdate;
property DestBitmap: TfcBitmap read FDestBitmap write FDestBitmap;
property OrigPicture: TPicture read FOrigPicture write FOrigPicture;
property Tile: Boolean read FTile write FTile;
property OnChange: TNotifyEvent read FOnChange write FOnChange;
published
property AlphaBlend: TfcAlphaBlend read FAlphaBlend write FAlphaBlend;
property Color: TColor read FColor write SetColor;
property Contrast: Integer index 4 read FContrast write SetIntegralProperty;
property Embossed: Boolean index 0 read FEmbossed write SetBooleanProperty;
property TintColor: TColor read FTintColor write SetTintColor;
property GaussianBlur: Integer index 3 read FGaussianBlur write SetIntegralProperty;
property GrayScale: Boolean index 2 read FGrayScale write SetBooleanProperty;
property HorizontallyFlipped: Boolean index 3 read FHorizontallyFlipped write SetBooleanProperty;
property Inverted: Boolean index 1 read FInverted write SetBooleanProperty;
property Lightness: Integer index 0 read FLightness write SetIntegralProperty;
property Rotation: TfcRotate read FRotation write FRotation;
property Saturation: Integer index 1 read FSaturation write SetIntegralProperty;
property Sharpen: Integer index 5 read FSharpen write SetIntegralProperty;
property Sponge: Integer index 2 read FSponge write SetIntegralProperty;
property VerticallyFlipped: Boolean index 4 read FVerticallyFlipped write SetBooleanProperty;
property Wave: TfcWave read FWave write FWave;
end;
TfcCustomImager = class(TGraphicControl)
private
{ Private declarations }
FAutoSize: Boolean;
FBitmapOptions: TfcBitmapOptions;
FDrawStyle: TfcImagerDrawStyle;
FEraseBackground: Boolean;
FPreProcess: Boolean;
FWorkBitmap: TfcBitmap;
// FBitmap: TfcBitmap;
FPicture: TPicture;
FChangeLinks: TList;
FRespectPalette: boolean;
function GetRespectPalette: Boolean;
function GetSmoothStretching: Boolean;
function GetTransparent: Boolean;
function GetTransparentColor: TColor;
procedure SetAutoSize(Value: Boolean);
// procedure SetBitmap(Value: TfcBitmap);
procedure SetDrawStyle(Value: TfcImagerDrawStyle);
procedure SetEraseBackground(Value: Boolean);
procedure SetPreProcess(Value: Boolean);
procedure SetPicture(Value: TPicture);
procedure SetRespectPalette(Value: Boolean);
procedure SetSmoothStretching(Value: Boolean);
procedure SetTransparent(Value: Boolean);
procedure SetTransparentColor(Value: TColor);
function GetDrawRect: TRect;
procedure NotifyChanges;
protected
procedure SetParent(Value: TWinControl); override;
procedure BitmapOptionsChange(Sender: TObject); virtual;
procedure BitmapChange(Sender: TObject);
procedure UpdateAutoSize; virtual;
procedure Loaded; override;
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
procedure Paint; override;
procedure WndProc(var Message: TMessage); override;
// procedure ParentMessages(var Message: TMessage; var ProcessMessage: Boolean); virtual;
property EraseBackground: Boolean read FEraseBackground write SetEraseBackground default True;
public
UpdatingAutoSize: Boolean;
InSetBounds: boolean;
Patch: Variant;
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function PictureEmpty: Boolean; virtual;
procedure Invalidate; override;
procedure RegisterChanges(ChangeLink: TfcChangeLink); virtual;
procedure Resized; virtual;
procedure UpdateWorkBitmap; virtual;
procedure UnRegisterChanges(ChangeLink: TfcChangeLink); virtual;
procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
procedure CopyToClipboard; virtual;
property Align;
property AutoSize: Boolean read FAutoSize write SetAutoSize;
property BitmapOptions: TfcBitmapOptions read FBitmapOptions write FBitmapOptions;
property DrawStyle: TfcImagerDrawStyle read FDrawStyle write SetDrawStyle;
property PreProcess: Boolean read FPreProcess write SetPreProcess;
// property Bitmap: TfcBitmap read FBitmap write SetBitmap;
property Picture: TPicture read FPicture write SetPicture;
property RespectPalette: Boolean read GetRespectPalette write SetRespectPalette default True;
property SmoothStretching: Boolean read GetSmoothStretching write SetSmoothStretching;
property Transparent: Boolean read GetTransparent write SetTransparent;
property TransparentColor: TColor read GetTransparentColor write SetTransparentColor;
property WorkBitmap: TfcBitmap read FWorkBitmap;
end;
TfcImager = class(TfcCustomImager)
published
{ Published declarations }
property Align;
property AutoSize;
// property Bitmap;
property BitmapOptions;
property DrawStyle;
// property EraseBackground;
property Picture;
property PreProcess;
property RespectPalette;
property SmoothStretching;
property Transparent;
property TransparentColor;
property Visible;
{$ifdef fcDelphi4Up}
property Anchors;
property Constraints;
property OnEndDock;
property OnStartDock;
{$endif}
property OnClick;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEndDrag;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnStartDrag;
end;
implementation
uses clipbrd;
constructor TfcRotate.Create(BitmapOptions: TfcBitmapOptions);
begin
inherited Create;
FCenterX := -1;
FCenterY := -1;
FBitmapOptions := BitmapOptions;
end;
procedure TfcRotate.SetCenterX(Value: Integer);
begin
if FCenterX <> Value then
begin
FCenterX := Value;
FBitmapOptions.Changed;
end;
end;
procedure TfcRotate.SetCenterY(Value: Integer);
begin
if FCenterY <> Value then
begin
FCenterY := Value;
FBitmapOptions.Changed;
end;
end;
procedure TfcRotate.SetAngle(Value: Integer);
begin
if FAngle <> Value then
begin
FAngle := Value;
FBitmapOptions.Changed;
end;
end;
constructor TfcAlphaBlend.Create(BitmapOptions: TfcBitmapOptions);
begin
inherited Create;
FBitmapOptions := BitmapOptions;
FBitmap := TfcBitmap.Create;
// FBitmap.OnChange := BitmapChanged;
end;
destructor TfcAlphaBlend.Destroy;
begin
FBitmap.Free;
inherited;
end;
procedure TfcAlphaBlend.BitmapChanged(Sender: TObject);
begin
if FChanging then Exit;
FChanging := True;
FBitmapOptions.Changed;
FChanging := False;
end;
function TfcAlphaBlend.GetTransparent: Boolean;
begin
result := Bitmap.Transparent;
end;
procedure TfcAlphaBlend.SetTransparent(Value: Boolean);
begin
Bitmap.Transparent := Value;
end;
procedure TfcAlphaBlend.SetAmount(Value: Byte);
begin
if FAmount <> Value then
begin
FAmount := Value;
FBitmapOptions.Changed;
end;
end;
procedure TfcAlphaBlend.SetBitmap(Value: TfcBitmap);
begin
FBitmap.Assign(Value);
end;
constructor TfcWave.Create(BitmapOptions: TfcBitmapOptions);
begin
inherited Create;
FBitmapOptions := BitmapOptions;
end;
procedure TfcWave.SetXDiv(Value: Integer);
begin
if FXDiv <> Value then
begin
FXDiv := Value;
FBitmapOptions.Changed;
end;
end;
procedure TfcWave.SetYDiv(Value: Integer);
begin
if FYDiv <> Value then
begin
FYDiv := Value;
FBitmapOptions.Changed;
end;
end;
procedure TfcWave.SetRatio(Value: Integer);
begin
if FRatio <> Value then
begin
FRatio := Value;
FBitmapOptions.Changed;
end;
end;
procedure TfcWave.SetWrap(Value: Boolean);
begin
if FWrap <> Value then
begin
FWrap := Value;
FBitmapOptions.Changed;
end;
end;
constructor TfcBitmapOptions.Create(AComponent: TComponent);
begin
inherited Create;
FComponent := AComponent;
FAlphaBlend := TfcAlphaBlend.Create(self);
FRotation := TfcRotate.Create(self);
FColor := clNone;
FTintColor := clNone;
FSaturation := -1;
FWave := TfcWave.Create(self);
end;
destructor TfcBitmapOptions.Destroy;
begin
FAlphaBlend.Free;
FRotation.Free;
FWave.Free;
inherited;
end;
procedure TfcBitmapOptions.Changed;
var TmpBitmap: TfcBitmap;
begin
if (csLoading in FComponent.ComponentState) or DestBitmap.Empty or ((OrigPicture.Graphic = nil) or OrigPicture.Graphic.Empty) or (FUpdateLock > 0) then Exit;
if (DestBitmap.Width = OrigPicture.Width) and (DestBitmap.Height = OrigPicture.Height) then
DestBitmap.Assign(OrigPicture.Graphic)
else begin
if Tile then fcTileDraw(OrigPicture.Graphic, DestBitmap.Canvas, Rect(0, 0, DestBitmap.Width, DestBitmap.Height))
else begin
TmpBitmap := TfcBitmap.Create;
TmpBitmap.Assign(OrigPicture.Graphic);
TmpBitmap.SmoothStretching := TfcCustomImager(FComponent).SmoothStretching;
try
DestBitmap.Canvas.StretchDraw(Rect(0, 0, DestBitmap.Width, DestBitmap.Height), TmpBitmap);
finally
TmpBitmap.Free;
end;
end;
end;
if FGrayScale then DestBitmap.GrayScale;
if FLightness <> 0 then DestBitmap.Brightness(FLightness);
if (FAlphaBlend.Amount <> 0) and not FAlphaBlend.Bitmap.Empty then
DestBitmap.AlphaBlend(FAlphaBlend.Bitmap, FAlphaBlend.Amount, True);
if FColor <> clNone then with fcGetColor(ColorToRGB(FColor)) do
DestBitmap.Colorize(r, g, b);
if FTintColor <> clNone then with fcGetColor(ColorToRGB(FTintColor)) do
DestBitmap.ColorTint(r div 2, g div 2, b div 2);
if FSponge <> 0 then DestBitmap.Sponge(FSponge);
if FSaturation <> -1 then DestBitmap.Saturation(FSaturation);
if FGaussianBlur <> 0 then DestBitmap.GaussianBlur(FGaussianBlur);
if FEmbossed then DestBitmap.Emboss;
if FInverted then DestBitmap.Invert;
if FContrast <> 0 then DestBitmap.Contrast(FContrast);
if FSharpen <> 0 then DestBitmap.Sharpen(FSharpen);
if FHorizontallyFlipped then DestBitmap.Flip(True);
if FVerticallyFlipped then DestBitmap.Flip(False);
with FWave do if (Ratio <> 0) and (XDiv <> 0) and (YDiv <> 0) then
DestBitmap.Wave(XDiv, YDiv, Ratio, Wrap);
if FRotation.Angle <> 0 then with Rotation do
DestBitmap.Rotate(Point(CenterX, CenterY), Angle);
if Assigned(FOnChange) then FOnChange(self);
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -