Graphics32 简单绘图图层缩放
Graphics32 Simple drawing layer scaling
出于学习目的,我正在尝试构建一个应用程序,它的行为方式与 Graphics32 示例应用程序基本相同 "ImgView_Layers" 并且我正在做一些细微的更改。现在我陷入了简单绘图层的问题。我以与示例应用程序相同的方式创建了一个。在 PaintSimpleDrawingHandler 中,我试图绘制一些其他形状,而不是默认的螺旋形。问题来了。 "default" 螺旋线随图像缩放 - 缩小时,螺旋线也会缩小,反之亦然。当图层大小改变时,螺旋的大小也会改变。如果我画其他东西,缩放或改变图层大小时它保持不变。
这是菱形、正方形和螺旋形的示例。螺旋线"works"好,其他的不行。
procedure TfrmMain.PaintSimpleDrawingHandler(Sender: TObject; Buffer: TBitmap32);
var
Cx, Cy: Single;
W2, H2: Single;
I: Integer;
yy, xx, yyy, xxx: integer;
const
CScale = 1 / 200;
begin
if Sender is TPositionedLayer then
with TPositionedLayer(Sender).GetAdjustedLocation do
begin
W2 := (Right - Left) * 0.5;
H2 := (Bottom - Top) * 0.5;
Cx:= Left + W2;
Cy:= Top + H2;
W2 := W2 * CScale;
H2 := H2 * CScale;
Buffer.PenColor := clGreen32;
// square
xx := Round(Cx + W2 - 10);
yy := Round(Cy + H2 - 10);
xxx := Round(Cx + W2 + 10);
yyy := Round(Cy + H2 + 10);
Buffer.FrameRectS(xx, yy, xxx, yyy, clRoyalBlue32);
///square
// diamond
Buffer.MoveToF(Cx - 10, Cy);
Buffer.LineToFS(Cx + W2, Cy + H2 - 10);
Buffer.MoveToF(Cx, Cy - 10);
Buffer.LineToFS(Cx + W2 + 10, Cy + H2);
Buffer.MoveToF(Cx + 10, Cy);
Buffer.LineToFS(Cx + W2, Cy + H2 + 10);
Buffer.MoveToF(Cx, Cy + 10);
Buffer.LineToFS(Cx + W2 - 10, Cy + H2);
///diamond
// spiral
Buffer.MoveToF(Cx, Cy);
for I := 0 to 240 do
Buffer.LineToFS(
Cx + W2 * I * Cos(I * 0.125),
Cy + H2 * I * Sin(I * 0.125));
end;
end;
我尝试了几种不同的形状,不同的绘制方法,但仍然得到相同的结果。谁能解释一下螺旋线和其他螺旋线的区别,并帮助我绘制自定义形状,这些形状将以与螺旋线相同的方式缩放和缩放?
我用的是Delphi XE7。这是完整的来源:
unit Test;
interface
{$I GR32.inc}
uses
Windows,
Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Menus, GR32_Image, Vcl.ExtCtrls,
AdvToolBar, AdvShapeButton, AdvAppStyler, AdvToolBarStylers, AdvPreviewMenu,
AdvPreviewMenuStylers, AdvPanel, DataModule, AdvGlassButton, Vcl.StdCtrls,
AeroButtons, AdvGlowButton, GR32, GR32_Layers, GR32_RangeBars,
GR32_Filters, GR32_Transforms, GR32_Resamplers, AdvTrackBar;
type
TfrmMain = class(TForm)
pnlMain: TPanel;
AdvToolBarPager1: TAdvToolBarPager;
AdvToolBarPager11: TAdvPage;
AdvToolBarPager12: TAdvPage;
AdvToolBarPager13: TAdvPage;
pnlMainRight: TAdvPanel;
pnlMainLeft: TAdvPanel;
pnlMainCenter: TAdvPanel;
AdvShapeButton1: TAdvShapeButton;
pnlMainBottom: TAdvPanel;
iwMain: TImgView32;
btManImgPick: TAdvGlowButton;
tbZoom: TAdvTrackBar;
btZoom: TAdvGlowButton;
btAddMark: TAdvGlowButton;
procedure FormCreate(Sender: TObject);
procedure FormResize(Sender: TObject);
procedure btManImgPickClick(Sender: TObject);
procedure OpenImage(const FileName: string);
procedure iwMainMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer);
procedure iwMainMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer);
procedure iwMainMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer);
procedure iwMainResize(Sender: TObject);
procedure tbZoomChange(Sender: TObject);
procedure btZoomClick(Sender: TObject);
procedure iwMainMouseWheelUp(Sender: TObject; Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
procedure iwMainMouseWheelDown(Sender: TObject; Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
procedure btAddMarkClick(Sender: TObject);
private
FSelection: TPositionedLayer;
FDragging: Boolean;
FFrom: TPoint;
procedure SetSelection(Value: TPositionedLayer);
public
property Selection: TPositionedLayer read FSelection write SetSelection;
protected
RBLayer: TRubberbandLayer;
procedure WMNCHitTest(var Message: TWMNCHitTest); message WM_NCHITTEST;
procedure RBResizing(Sender: TObject; const OldLocation: TFloatRect;
var NewLocation: TFloatRect; DragState: TRBDragState; Shift: TShiftState);
procedure LayerDblClick(Sender: TObject);
procedure iwAutofit;
function CreatePositionedLayer: TPositionedLayer;
procedure LayerMouseDown(Sender: TObject; Buttons: TMouseButton; Shift: TShiftState; X, Y: Integer);
procedure PaintSimpleDrawingHandler(Sender: TObject; Buffer: TBitmap32);
procedure drawMark();
end;
var
frmTest: TfrmMain;
DataModule: TDataModule;
implementation
{$R *.dfm}
uses
JPEG,
NewImageUnit, RGBALoaderUnit, Math, Printers, GR32_LowLevel, GR32_Paths,
GR32_VectorUtils, GR32_Backends, GR32_Text_VCL, GR32_ColorGradients,
GR32_Polygons, GR32_Geometry;
procedure TfrmMain.OpenImage(const FileName: string);
begin
with iwMain do
try
Selection := nil;
RBLayer := nil;
Layers.Clear;
Scale := 1;
Bitmap.LoadFromFile(FileName);
finally
//pnlImage.Visible := not Bitmap.Empty;
end;
end;
procedure TfrmMain.PaintSimpleDrawingHandler(Sender: TObject;
Buffer: TBitmap32);
var
Cx, Cy: Single;
W2, H2: Single;
I: Integer;
yy, xx, yyy, xxx: integer;
const
CScale = 1 / 200;
begin
if Sender is TPositionedLayer then
with TPositionedLayer(Sender).GetAdjustedLocation do
begin
W2 := (Right - Left) * 0.5;
H2 := (Bottom - Top) * 0.5;
Cx:= Left + W2;
Cy:= Top + H2;
W2 := W2 * CScale;
H2 := H2 * CScale;
Buffer.PenColor := clGreen32;
xx := Round(Cx + W2 - 10);
yy := Round(Cy + H2 - 10);
xxx := Round(Cx + W2 + 10);
yyy := Round(Cy + H2 + 10);
Buffer.FrameRectS(xx, yy, xxx, yyy, clRoyalBlue32);
Buffer.MoveToF(Cx - 10, Cy);
Buffer.LineToFS(Cx + W2, Cy + H2 - 10);
Buffer.MoveToF(Cx, Cy - 10);
Buffer.LineToFS(Cx + W2 + 10, Cy + H2);
Buffer.MoveToF(Cx + 10, Cy);
Buffer.LineToFS(Cx + W2, Cy + H2 + 10);
Buffer.MoveToF(Cx, Cy + 10);
Buffer.LineToFS(Cx + W2 - 10, Cy + H2);
Buffer.MoveToF(Cx, Cy);
for I := 0 to 240 do
Buffer.LineToFS(
Cx + W2 * I * Cos(I * 0.125),
Cy + H2 * I * Sin(I * 0.125));
end;
end;
procedure TfrmMain.RBResizing(Sender: TObject;
const OldLocation: TFloatRect; var NewLocation: TFloatRect;
DragState: TRBDragState; Shift: TShiftState);
var
w, h, cx, cy: Single;
nw, nh: Single;
begin
if DragState = dsMove then Exit; // we are interested only in scale operations
if Shift = [] then Exit; // special processing is not required
if ssCtrl in Shift then
begin
{ make changes symmetrical }
with OldLocation do
begin
cx := (Left + Right) / 2;
cy := (Top + Bottom) / 2;
w := Right - Left;
h := Bottom - Top;
end;
with NewLocation do
begin
nw := w / 2;
nh := h / 2;
case DragState of
dsSizeL: nw := cx - Left;
dsSizeT: nh := cy - Top;
dsSizeR: nw := Right - cx;
dsSizeB: nh := Bottom - cy;
dsSizeTL: begin nw := cx - Left; nh := cy - Top; end;
dsSizeTR: begin nw := Right - cx; nh := cy - Top; end;
dsSizeBL: begin nw := cx - Left; nh := Bottom - cy; end;
dsSizeBR: begin nw := Right - cx; nh := Bottom - cy; end;
end;
if nw < 2 then nw := 2;
if nh < 2 then nh := 2;
Left := cx - nw;
Right := cx + nw;
Top := cy - nh;
Bottom := cy + nh;
end;
end;
end;
procedure TfrmMain.SetSelection(Value: TPositionedLayer);
begin
if Value <> FSelection then
begin
if RBLayer <> nil then
begin
RBLayer.ChildLayer := nil;
RBLayer.LayerOptions := LOB_NO_UPDATE;
//pnlBitmapLayer.Visible := False;
//pnlButtonMockup.Visible := False;
//pnlMagnification.Visible := False;
iwMain.Invalidate;
end;
FSelection := Value;
if Value <> nil then
begin
if RBLayer = nil then
begin
RBLayer := TRubberBandLayer.Create(iwMain.Layers);
RBLayer.MinHeight := 1;
RBLayer.MinWidth := 1;
end
else
RBLayer.BringToFront;
RBLayer.ChildLayer := Value;
RBLayer.LayerOptions := LOB_VISIBLE or LOB_MOUSE_EVENTS or LOB_NO_UPDATE;
RBLayer.OnResizing := RBResizing;
RBLayer.OnDblClick := LayerDblClick;
if Value is TBitmapLayer then
with TBitmapLayer(Value) do
begin
//pnlBitmapLayer.Visible := True;
//GbrLayerOpacity.Position := Bitmap.MasterAlpha;
//CbxLayerInterpolate.Checked := Bitmap.Resampler.ClassType = TDraftResampler;
end
else if Value.Tag = 2 then
begin
// tag = 2 for button mockup
//pnlButtonMockup.Visible := True;
end
else if Value.Tag = 3 then
begin
// tag = 3 for magnifiers
//pnlMagnification.Visible := True;
end;
end;
end;
end;
procedure TfrmMain.tbZoomChange(Sender: TObject);
begin
iwMain.Scale:= tbZoom.Position / 10;
btZoom.Caption:= FloatToStr(tbZoom.Position / 10 * 100) + '%';
end;
procedure TfrmMain.btAddMarkClick(Sender: TObject);
begin
drawMark();
end;
procedure TfrmMain.btManImgPickClick(Sender: TObject);
var jpg : TJPEGImage;
//bcImage : TBacmedImage;
//Center : Coordinant;
begin
with DataModule1.OpenPictureDialog do
if Execute then
begin
jpg:=TJPEGImage.Create;
jpg.LoadFromFile(FileName);
//Center.x:=round(jpg.Width/2);
//Center.y:=round(jpg.Height/2);
//bcImage:=TBacmedImage.Create(jpg,100,'AAA',1,Center,jpg.Width,23.83);
OpenImage(FileName);
end;
iwAutofit();
end;
procedure TfrmMain.btZoomClick(Sender: TObject);
begin
iwAutofit();
end;
function TfrmMain.CreatePositionedLayer: TPositionedLayer;
var
P: TPoint;
begin
// get coordinates of the center of viewport
with iwMain.GetViewportRect do
P := iwMain.ControlToBitmap(GR32.Point((Right + Left) div 2, (Top + Bottom) div 2));
Result := TPositionedLayer.Create(iwMain.Layers);
Result.Location := FloatRect(P.X - 32, P.Y - 32, P.X + 32, P.Y + 32);
Result.Scaled := True;
Result.MouseEvents := True;
Result.OnMouseDown := LayerMouseDown;
Result.OnDblClick := LayerDblClick;
end;
procedure TfrmMain.drawMark;
var
L: TPositionedLayer;
begin
L := CreatePositionedLayer;
L.OnPaint := PaintSimpleDrawingHandler;
L.Tag := 1;
Selection := L;
end;
procedure TfrmMain.FormCreate(Sender: TObject);
begin
DataModule:= TDataModule.Create(self);
end;
procedure TfrmMain.FormResize(Sender: TObject);
begin
//pnlMainRight.Width:= round(frmTest.Width / 5);
end;
procedure TfrmMain.iwAutofit;
begin
if iwMain.Bitmap.Height > 0 then //jednoducha cesta jak checknout neprirazeny obrazek. Pokud je neprirazeny, nezoomovat.
begin
tbZoom.Position:= Round(iwMain.Height / iwMain.Bitmap.Height * 10);
btZoom.Caption:= IntToStr(Round(iwMain.Height / iwMain.Bitmap.Height * 100)) + '%';
iwMain.Scale:= iwMain.Height / iwMain.Bitmap.Height;
end;
end;
procedure TfrmMain.iwMainMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer);
begin
if Button = mbMiddle then
begin
FDragging := True;
iwMain.Cursor:= crDrag;
FFrom := Point(X, Y);
end;
end;
procedure TfrmMain.iwMainMouseMove(Sender: TObject; Shift: TShiftState;
X, Y: Integer; Layer: TCustomLayer);
begin
if FDragging then
begin
iwMain.Scroll(FFrom.X - X, FFrom.Y - Y);
FFrom.X:= X;
FFrom.Y:= Y;
end;
end;
procedure TfrmMain.iwMainMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer);
begin
if Button = mbMiddle then
begin
FDragging := False;
iwMain.Cursor:= crDefault;
iwMain.SetFocus;
end;
end;
procedure TfrmMain.iwMainMouseWheelDown(Sender: TObject;
Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
begin
tbZoom.Position:= tbZoom.Position - 1;
end;
procedure TfrmMain.iwMainMouseWheelUp(Sender: TObject;
Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
begin
tbZoom.Position:= tbZoom.Position + 1;
end;
procedure TfrmMain.iwMainResize(Sender: TObject);
begin
iwAutofit();
end;
procedure TfrmMain.LayerDblClick(Sender: TObject);
begin
if Sender is TRubberbandLayer then
TRubberbandLayer(Sender).Quantize;
end;
procedure TfrmMain.LayerMouseDown(Sender: TObject;
Buttons: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
if Sender <> nil then Selection := TPositionedLayer(Sender);
end;
procedure TfrmMain.WMNCHitTest(var Message: TWMNCHitTest);
const
EDGEDETECT = 7; // adjust
var
deltaRect: TRect;
begin
inherited;
if BorderStyle = TFormBorderStyle(0) then
with Message, deltaRect do
begin
Left := XPos - BoundsRect.Left;
Right := BoundsRect.Right - XPos;
Top := YPos - BoundsRect.Top;
Bottom := BoundsRect.Bottom - YPos;
if (Top < EDGEDETECT) and (Left < EDGEDETECT) then
Result := HTTOPLEFT
else if (Top < EDGEDETECT) and (Right < EDGEDETECT) then
Result := HTTOPRIGHT
else if (Bottom < EDGEDETECT) and (Left < EDGEDETECT) then
Result := HTBOTTOMLEFT
else if (Bottom < EDGEDETECT) and (Right < EDGEDETECT) then
Result := HTBOTTOMRIGHT
else if (Top < EDGEDETECT) then
Result := HTTOP
else if (Left < EDGEDETECT) then
Result := HTLEFT
else if (Bottom < EDGEDETECT) then
Result := HTBOTTOM
else if (Right < EDGEDETECT) then
Result := HTRIGHT
end;
end;
end.
If I draw anything else, it remains unchanged when zooming, or
changing the size of the layer.
那是因为您不会通过缩放或调整大小来更改对象的大小:
// square
xx := Round(Cx + W2 - 10);
yy := Round(Cy + H2 - 10);
xxx := Round(Cx + W2 + 10);
yyy := Round(Cy + H2 + 10);
Buffer.FrameRectS(xx, yy, xxx, yyy, clRoyalBlue32);
矩形的大小由常量 -10 和 +10 定义(Cx+W2 和 Cy+H2 定义中心点)。
例如,试试这个:
xx := Round(Cx + W2 *(- 2));
yy := Round(Cy + H2 *(- 2));
xxx := Round(Cx + W2 *(+ 2));
yyy := Round(Cy + H2 *(+ 2));
出于学习目的,我正在尝试构建一个应用程序,它的行为方式与 Graphics32 示例应用程序基本相同 "ImgView_Layers" 并且我正在做一些细微的更改。现在我陷入了简单绘图层的问题。我以与示例应用程序相同的方式创建了一个。在 PaintSimpleDrawingHandler 中,我试图绘制一些其他形状,而不是默认的螺旋形。问题来了。 "default" 螺旋线随图像缩放 - 缩小时,螺旋线也会缩小,反之亦然。当图层大小改变时,螺旋的大小也会改变。如果我画其他东西,缩放或改变图层大小时它保持不变。
这是菱形、正方形和螺旋形的示例。螺旋线"works"好,其他的不行。
procedure TfrmMain.PaintSimpleDrawingHandler(Sender: TObject; Buffer: TBitmap32);
var
Cx, Cy: Single;
W2, H2: Single;
I: Integer;
yy, xx, yyy, xxx: integer;
const
CScale = 1 / 200;
begin
if Sender is TPositionedLayer then
with TPositionedLayer(Sender).GetAdjustedLocation do
begin
W2 := (Right - Left) * 0.5;
H2 := (Bottom - Top) * 0.5;
Cx:= Left + W2;
Cy:= Top + H2;
W2 := W2 * CScale;
H2 := H2 * CScale;
Buffer.PenColor := clGreen32;
// square
xx := Round(Cx + W2 - 10);
yy := Round(Cy + H2 - 10);
xxx := Round(Cx + W2 + 10);
yyy := Round(Cy + H2 + 10);
Buffer.FrameRectS(xx, yy, xxx, yyy, clRoyalBlue32);
///square
// diamond
Buffer.MoveToF(Cx - 10, Cy);
Buffer.LineToFS(Cx + W2, Cy + H2 - 10);
Buffer.MoveToF(Cx, Cy - 10);
Buffer.LineToFS(Cx + W2 + 10, Cy + H2);
Buffer.MoveToF(Cx + 10, Cy);
Buffer.LineToFS(Cx + W2, Cy + H2 + 10);
Buffer.MoveToF(Cx, Cy + 10);
Buffer.LineToFS(Cx + W2 - 10, Cy + H2);
///diamond
// spiral
Buffer.MoveToF(Cx, Cy);
for I := 0 to 240 do
Buffer.LineToFS(
Cx + W2 * I * Cos(I * 0.125),
Cy + H2 * I * Sin(I * 0.125));
end;
end;
我尝试了几种不同的形状,不同的绘制方法,但仍然得到相同的结果。谁能解释一下螺旋线和其他螺旋线的区别,并帮助我绘制自定义形状,这些形状将以与螺旋线相同的方式缩放和缩放?
我用的是Delphi XE7。这是完整的来源:
unit Test;
interface
{$I GR32.inc}
uses
Windows,
Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Menus, GR32_Image, Vcl.ExtCtrls,
AdvToolBar, AdvShapeButton, AdvAppStyler, AdvToolBarStylers, AdvPreviewMenu,
AdvPreviewMenuStylers, AdvPanel, DataModule, AdvGlassButton, Vcl.StdCtrls,
AeroButtons, AdvGlowButton, GR32, GR32_Layers, GR32_RangeBars,
GR32_Filters, GR32_Transforms, GR32_Resamplers, AdvTrackBar;
type
TfrmMain = class(TForm)
pnlMain: TPanel;
AdvToolBarPager1: TAdvToolBarPager;
AdvToolBarPager11: TAdvPage;
AdvToolBarPager12: TAdvPage;
AdvToolBarPager13: TAdvPage;
pnlMainRight: TAdvPanel;
pnlMainLeft: TAdvPanel;
pnlMainCenter: TAdvPanel;
AdvShapeButton1: TAdvShapeButton;
pnlMainBottom: TAdvPanel;
iwMain: TImgView32;
btManImgPick: TAdvGlowButton;
tbZoom: TAdvTrackBar;
btZoom: TAdvGlowButton;
btAddMark: TAdvGlowButton;
procedure FormCreate(Sender: TObject);
procedure FormResize(Sender: TObject);
procedure btManImgPickClick(Sender: TObject);
procedure OpenImage(const FileName: string);
procedure iwMainMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer);
procedure iwMainMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer);
procedure iwMainMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer);
procedure iwMainResize(Sender: TObject);
procedure tbZoomChange(Sender: TObject);
procedure btZoomClick(Sender: TObject);
procedure iwMainMouseWheelUp(Sender: TObject; Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
procedure iwMainMouseWheelDown(Sender: TObject; Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
procedure btAddMarkClick(Sender: TObject);
private
FSelection: TPositionedLayer;
FDragging: Boolean;
FFrom: TPoint;
procedure SetSelection(Value: TPositionedLayer);
public
property Selection: TPositionedLayer read FSelection write SetSelection;
protected
RBLayer: TRubberbandLayer;
procedure WMNCHitTest(var Message: TWMNCHitTest); message WM_NCHITTEST;
procedure RBResizing(Sender: TObject; const OldLocation: TFloatRect;
var NewLocation: TFloatRect; DragState: TRBDragState; Shift: TShiftState);
procedure LayerDblClick(Sender: TObject);
procedure iwAutofit;
function CreatePositionedLayer: TPositionedLayer;
procedure LayerMouseDown(Sender: TObject; Buttons: TMouseButton; Shift: TShiftState; X, Y: Integer);
procedure PaintSimpleDrawingHandler(Sender: TObject; Buffer: TBitmap32);
procedure drawMark();
end;
var
frmTest: TfrmMain;
DataModule: TDataModule;
implementation
{$R *.dfm}
uses
JPEG,
NewImageUnit, RGBALoaderUnit, Math, Printers, GR32_LowLevel, GR32_Paths,
GR32_VectorUtils, GR32_Backends, GR32_Text_VCL, GR32_ColorGradients,
GR32_Polygons, GR32_Geometry;
procedure TfrmMain.OpenImage(const FileName: string);
begin
with iwMain do
try
Selection := nil;
RBLayer := nil;
Layers.Clear;
Scale := 1;
Bitmap.LoadFromFile(FileName);
finally
//pnlImage.Visible := not Bitmap.Empty;
end;
end;
procedure TfrmMain.PaintSimpleDrawingHandler(Sender: TObject;
Buffer: TBitmap32);
var
Cx, Cy: Single;
W2, H2: Single;
I: Integer;
yy, xx, yyy, xxx: integer;
const
CScale = 1 / 200;
begin
if Sender is TPositionedLayer then
with TPositionedLayer(Sender).GetAdjustedLocation do
begin
W2 := (Right - Left) * 0.5;
H2 := (Bottom - Top) * 0.5;
Cx:= Left + W2;
Cy:= Top + H2;
W2 := W2 * CScale;
H2 := H2 * CScale;
Buffer.PenColor := clGreen32;
xx := Round(Cx + W2 - 10);
yy := Round(Cy + H2 - 10);
xxx := Round(Cx + W2 + 10);
yyy := Round(Cy + H2 + 10);
Buffer.FrameRectS(xx, yy, xxx, yyy, clRoyalBlue32);
Buffer.MoveToF(Cx - 10, Cy);
Buffer.LineToFS(Cx + W2, Cy + H2 - 10);
Buffer.MoveToF(Cx, Cy - 10);
Buffer.LineToFS(Cx + W2 + 10, Cy + H2);
Buffer.MoveToF(Cx + 10, Cy);
Buffer.LineToFS(Cx + W2, Cy + H2 + 10);
Buffer.MoveToF(Cx, Cy + 10);
Buffer.LineToFS(Cx + W2 - 10, Cy + H2);
Buffer.MoveToF(Cx, Cy);
for I := 0 to 240 do
Buffer.LineToFS(
Cx + W2 * I * Cos(I * 0.125),
Cy + H2 * I * Sin(I * 0.125));
end;
end;
procedure TfrmMain.RBResizing(Sender: TObject;
const OldLocation: TFloatRect; var NewLocation: TFloatRect;
DragState: TRBDragState; Shift: TShiftState);
var
w, h, cx, cy: Single;
nw, nh: Single;
begin
if DragState = dsMove then Exit; // we are interested only in scale operations
if Shift = [] then Exit; // special processing is not required
if ssCtrl in Shift then
begin
{ make changes symmetrical }
with OldLocation do
begin
cx := (Left + Right) / 2;
cy := (Top + Bottom) / 2;
w := Right - Left;
h := Bottom - Top;
end;
with NewLocation do
begin
nw := w / 2;
nh := h / 2;
case DragState of
dsSizeL: nw := cx - Left;
dsSizeT: nh := cy - Top;
dsSizeR: nw := Right - cx;
dsSizeB: nh := Bottom - cy;
dsSizeTL: begin nw := cx - Left; nh := cy - Top; end;
dsSizeTR: begin nw := Right - cx; nh := cy - Top; end;
dsSizeBL: begin nw := cx - Left; nh := Bottom - cy; end;
dsSizeBR: begin nw := Right - cx; nh := Bottom - cy; end;
end;
if nw < 2 then nw := 2;
if nh < 2 then nh := 2;
Left := cx - nw;
Right := cx + nw;
Top := cy - nh;
Bottom := cy + nh;
end;
end;
end;
procedure TfrmMain.SetSelection(Value: TPositionedLayer);
begin
if Value <> FSelection then
begin
if RBLayer <> nil then
begin
RBLayer.ChildLayer := nil;
RBLayer.LayerOptions := LOB_NO_UPDATE;
//pnlBitmapLayer.Visible := False;
//pnlButtonMockup.Visible := False;
//pnlMagnification.Visible := False;
iwMain.Invalidate;
end;
FSelection := Value;
if Value <> nil then
begin
if RBLayer = nil then
begin
RBLayer := TRubberBandLayer.Create(iwMain.Layers);
RBLayer.MinHeight := 1;
RBLayer.MinWidth := 1;
end
else
RBLayer.BringToFront;
RBLayer.ChildLayer := Value;
RBLayer.LayerOptions := LOB_VISIBLE or LOB_MOUSE_EVENTS or LOB_NO_UPDATE;
RBLayer.OnResizing := RBResizing;
RBLayer.OnDblClick := LayerDblClick;
if Value is TBitmapLayer then
with TBitmapLayer(Value) do
begin
//pnlBitmapLayer.Visible := True;
//GbrLayerOpacity.Position := Bitmap.MasterAlpha;
//CbxLayerInterpolate.Checked := Bitmap.Resampler.ClassType = TDraftResampler;
end
else if Value.Tag = 2 then
begin
// tag = 2 for button mockup
//pnlButtonMockup.Visible := True;
end
else if Value.Tag = 3 then
begin
// tag = 3 for magnifiers
//pnlMagnification.Visible := True;
end;
end;
end;
end;
procedure TfrmMain.tbZoomChange(Sender: TObject);
begin
iwMain.Scale:= tbZoom.Position / 10;
btZoom.Caption:= FloatToStr(tbZoom.Position / 10 * 100) + '%';
end;
procedure TfrmMain.btAddMarkClick(Sender: TObject);
begin
drawMark();
end;
procedure TfrmMain.btManImgPickClick(Sender: TObject);
var jpg : TJPEGImage;
//bcImage : TBacmedImage;
//Center : Coordinant;
begin
with DataModule1.OpenPictureDialog do
if Execute then
begin
jpg:=TJPEGImage.Create;
jpg.LoadFromFile(FileName);
//Center.x:=round(jpg.Width/2);
//Center.y:=round(jpg.Height/2);
//bcImage:=TBacmedImage.Create(jpg,100,'AAA',1,Center,jpg.Width,23.83);
OpenImage(FileName);
end;
iwAutofit();
end;
procedure TfrmMain.btZoomClick(Sender: TObject);
begin
iwAutofit();
end;
function TfrmMain.CreatePositionedLayer: TPositionedLayer;
var
P: TPoint;
begin
// get coordinates of the center of viewport
with iwMain.GetViewportRect do
P := iwMain.ControlToBitmap(GR32.Point((Right + Left) div 2, (Top + Bottom) div 2));
Result := TPositionedLayer.Create(iwMain.Layers);
Result.Location := FloatRect(P.X - 32, P.Y - 32, P.X + 32, P.Y + 32);
Result.Scaled := True;
Result.MouseEvents := True;
Result.OnMouseDown := LayerMouseDown;
Result.OnDblClick := LayerDblClick;
end;
procedure TfrmMain.drawMark;
var
L: TPositionedLayer;
begin
L := CreatePositionedLayer;
L.OnPaint := PaintSimpleDrawingHandler;
L.Tag := 1;
Selection := L;
end;
procedure TfrmMain.FormCreate(Sender: TObject);
begin
DataModule:= TDataModule.Create(self);
end;
procedure TfrmMain.FormResize(Sender: TObject);
begin
//pnlMainRight.Width:= round(frmTest.Width / 5);
end;
procedure TfrmMain.iwAutofit;
begin
if iwMain.Bitmap.Height > 0 then //jednoducha cesta jak checknout neprirazeny obrazek. Pokud je neprirazeny, nezoomovat.
begin
tbZoom.Position:= Round(iwMain.Height / iwMain.Bitmap.Height * 10);
btZoom.Caption:= IntToStr(Round(iwMain.Height / iwMain.Bitmap.Height * 100)) + '%';
iwMain.Scale:= iwMain.Height / iwMain.Bitmap.Height;
end;
end;
procedure TfrmMain.iwMainMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer);
begin
if Button = mbMiddle then
begin
FDragging := True;
iwMain.Cursor:= crDrag;
FFrom := Point(X, Y);
end;
end;
procedure TfrmMain.iwMainMouseMove(Sender: TObject; Shift: TShiftState;
X, Y: Integer; Layer: TCustomLayer);
begin
if FDragging then
begin
iwMain.Scroll(FFrom.X - X, FFrom.Y - Y);
FFrom.X:= X;
FFrom.Y:= Y;
end;
end;
procedure TfrmMain.iwMainMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer);
begin
if Button = mbMiddle then
begin
FDragging := False;
iwMain.Cursor:= crDefault;
iwMain.SetFocus;
end;
end;
procedure TfrmMain.iwMainMouseWheelDown(Sender: TObject;
Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
begin
tbZoom.Position:= tbZoom.Position - 1;
end;
procedure TfrmMain.iwMainMouseWheelUp(Sender: TObject;
Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
begin
tbZoom.Position:= tbZoom.Position + 1;
end;
procedure TfrmMain.iwMainResize(Sender: TObject);
begin
iwAutofit();
end;
procedure TfrmMain.LayerDblClick(Sender: TObject);
begin
if Sender is TRubberbandLayer then
TRubberbandLayer(Sender).Quantize;
end;
procedure TfrmMain.LayerMouseDown(Sender: TObject;
Buttons: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
if Sender <> nil then Selection := TPositionedLayer(Sender);
end;
procedure TfrmMain.WMNCHitTest(var Message: TWMNCHitTest);
const
EDGEDETECT = 7; // adjust
var
deltaRect: TRect;
begin
inherited;
if BorderStyle = TFormBorderStyle(0) then
with Message, deltaRect do
begin
Left := XPos - BoundsRect.Left;
Right := BoundsRect.Right - XPos;
Top := YPos - BoundsRect.Top;
Bottom := BoundsRect.Bottom - YPos;
if (Top < EDGEDETECT) and (Left < EDGEDETECT) then
Result := HTTOPLEFT
else if (Top < EDGEDETECT) and (Right < EDGEDETECT) then
Result := HTTOPRIGHT
else if (Bottom < EDGEDETECT) and (Left < EDGEDETECT) then
Result := HTBOTTOMLEFT
else if (Bottom < EDGEDETECT) and (Right < EDGEDETECT) then
Result := HTBOTTOMRIGHT
else if (Top < EDGEDETECT) then
Result := HTTOP
else if (Left < EDGEDETECT) then
Result := HTLEFT
else if (Bottom < EDGEDETECT) then
Result := HTBOTTOM
else if (Right < EDGEDETECT) then
Result := HTRIGHT
end;
end;
end.
If I draw anything else, it remains unchanged when zooming, or changing the size of the layer.
那是因为您不会通过缩放或调整大小来更改对象的大小:
// square
xx := Round(Cx + W2 - 10);
yy := Round(Cy + H2 - 10);
xxx := Round(Cx + W2 + 10);
yyy := Round(Cy + H2 + 10);
Buffer.FrameRectS(xx, yy, xxx, yyy, clRoyalBlue32);
矩形的大小由常量 -10 和 +10 定义(Cx+W2 和 Cy+H2 定义中心点)。 例如,试试这个:
xx := Round(Cx + W2 *(- 2));
yy := Round(Cy + H2 *(- 2));
xxx := Round(Cx + W2 *(+ 2));
yyy := Round(Cy + H2 *(+ 2));