This unit contains the TLayeredImage32 class that provides a relatively easy way to manage multiple images that will at some stage be merged into a single image.
Each TLayer32 in a TLayeredImage32 object represents a single image though layers can also contain other layers. Layers can be nested to any level. Child layers will be restricted to the bounds of their parent layers, except for childs of TGroupLayer32.
While layers can have any position in the 2D plane, only those portions of layers that are within the bounds of their owner TLayeredImage32 will be visible when all the images are merged (see TLayeredImage32.GetMergedImage)
There are four basic layer classes that derive from TLayer32:
All layers are contained in a nested tree structure under the very top group layer - TLayeredImage32.Root
uses
...
Img32, Img32.Layers, Img32.Draw,
Img32.Vector, Img32.Extra;
type
TForm1 = class(TForm)
// Form's full declaration removed for brevity
public
layeredImage: TLayeredImage32;
vectorLayer : TLayer32;
buttongroup : TSizingGroupLayer32;
clickedLayer: TLayer32;
clickedPoint: TPoint;
procedure UpdateEllipseLayer(vecLayer: TVectorLayer32);
end;
implementation
procedure TForm1.FormCreate(Sender: TObject);
begin
//create a TLayeredImage32 object
layeredImage := TLayeredImage32.Create(ClientWidth, ClientHeight);
//TDESIGNERLAYER32
with layeredImage.AddLayer(TDesignerLayer32) do
begin
SetSize(layeredImage.Width, layeredImage.Height);
HatchBackground(Image);
end;
//TVECTORLAYER32
//add a simple vector layer and draw an ellipse
vectorLayer := layeredImage.AddLayer(TVectorLayer32) ;
with vectorLayer do
begin
SetBounds(Rect(120, 120, 320, 220));
CursorId := crHandPoint;
UpdateEllipseLayer(vectorLayer as TVectorLayer32);
end;
//TGROUPLAYER32
//add a (designing) button group to size the vector layer
sizingbuttongroup := CreateSizingButtonGroup(vectorLayer,
ssCorners, bsRound, DefaultButtonSize, clRed32);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
layeredImage.Free;
end;
procedure TForm1.UpdateEllipseLayer(vecLayer: TVectorLayer32);
var
rec: TRect;
pp: TPathsD;
margin: integer;
begin
//draw an ellipse on vecLayer and update the
//hit-test mask so the layer will respond to clicking
with vecLayer do
begin
margin := 5;
rec := Rect(0, 0, Width, Height);
rec := Img32.Vector.InflateRect(rec, -margin, -margin);
SetLength(pp, 1);
pp[0] := Ellipse(rec);
DrawPolygon(Image, pp, frEvenOdd, $4000FFFF);
DrawLine(Image, pp, 5, $FF006666, esPolygon);
UpdateHitTestMask(pp, frEvenOdd);
end;
end;
procedure TForm1.FormMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
clickedLayer := layeredImage.GetLayerAt(Types.Point(X,Y));
clickedPoint := Types.Point(X,Y);
end;
procedure TForm1.FormMouseMove(Sender: TObject;
Shift: TShiftState; X,Y: Integer);
var
layer: TLayer32;
dx, dy: integer;
rec: TRect;
begin
if not (ssLeft in Shift) then
begin
layer := layeredImage.GetLayerAt(Types.Point(X,Y));
if Assigned(layer) then
Cursor := layer.CursorId else
Cursor := crDefault;
end;
if not Assigned(clickedLayer) then Exit;
dx := X - clickedPoint.X;
dy := Y - clickedPoint.Y;
clickedPoint := Types.Point(X,Y);
clickedLayer.Offset(dx, dy);
if clickedLayer = vectorLayer then
buttongroup.Offset(dx, dy) //move the sizing buttons too
else
begin
//update the sizing group with moved clickedLayer
rec := Rect(UpdateSizingButtonGroup(clickedLayer));
//and resize and repaint vectorLayer accordingly.
vectorLayer.SetBounds(rec);
UpdateEllipseLayer(vectorLayer as TVectorLayer32);
end;
Invalidate;
end;
procedure TForm1.FormMouseUp(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
clickedLayer := nil;
end;
procedure TForm1.FormPaint(Sender: TObject);
begin
with layeredImage.GetMergedImage do
CopyToDc(Self.Canvas.Handle);
end;
TDesignerLayer32, TGroupLayer32, TLayer32, TLayeredImage32, TLayeredImage32.AddLayer, TLayeredImage32.GetLayerAt, TLayeredImage32.GetMergedImage, TLayeredImage32.Root, TRasterLayer32, TVectorLayer32
Copyright ©2010-2023 Angus Johnson - Image32 4.8 - Help file built on 16 Apr 2025