ImageEn for Delphi and C++ Builder ImageEn for Delphi and C++ Builder

 

ImageEn Forum
Profile    Join    Active Topics    Forum FAQ    Search this forumSearch
Forum membership is Free!  Click Join to sign-up
Username:
Password:
Save Password
Forgot your Password?

 All Forums
 ImageEn Library for Delphi, C++ and .Net
 ImageEn and IEvolution Support Forum
 Edit a Polygon visually (drag/add/delete)
 New Topic  Reply to Topic
Author Previous Topic Topic Next Topic  

andyhill

Australia
133 Posts

Posted - Aug 16 2022 :  18:53:07  Show Profile  Reply
I want to Edit the Polygon visually: Removing/Adding points, Expanding/Shrinking Polygon Outline, cutting out multiple points that have been selected with auto rejoin, then save as a mask.

I would appreciate some help to modify this Demo - thanks in advance.

Andy

xequte

38198 Posts

Posted - Aug 17 2022 :  00:32:41  Show Profile  Reply
Hi Andy

Are you working off the demo:

\Demos\LayerEditing\Layers_Lines\Layers.dpr

Can you let me know what specific things you need added to it?

Nigel
Xequte Software
www.imageen.com
Go to Top of Page

andyhill

Australia
133 Posts

Posted - Aug 17 2022 :  16:07:35  Show Profile  Reply
I was using C:\ProgramData\ImageEn\Demos\LayerEditing\MagicFillToPolygon

Goal:
MagicPolygon Mask To Select Desired Image

Steps:
Auto-Create Selection,
User interaction - Remove Unwanted areas by drawing Line/Rectangle (Identifying-Multiple-Polygon-Points with Auto-Stitch/ReJoin)
User Interaction - Edit Points in Polygon (Add/Delete/Move)
User interaction - Expand/Shrink Polygon to suit
Cutout Selection and Save as desired image

I will send sample images privately



Andy
Go to Top of Page

xequte

38198 Posts

Posted - Aug 18 2022 :  00:09:23  Show Profile  Reply
Hi Andy

If you are auto-creating from a selection, then this requirement is mostly a merge between the MagicFillToPolygon and Layers_Lines demos. Try combining the relevant functionality of those two demos, and let me know if you have any difficulty.

Nigel
Xequte Software
www.imageen.com
Go to Top of Page

andyhill

Australia
133 Posts

Posted - Aug 18 2022 :  19:09:39  Show Profile  Reply
I tried most demos but not what I want (now using LayerMask.dproj) - please see ImageEnView1MouseDown

I want to DrawSelectionMask FreeHand,
Smooth/Reduce Points,
Add/Delete/Move Points
Shrink/Expand Mask
Feather

procedure Tfmain.FormCreate(Sender: TObject);
begin
ImageEnView1.MouseInteractLayers:= [mlDrawCreatePolylineLayers, mlEditLayerPoints]; // Makes No Difference
end;

procedure Tfmain.ImageEnView1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin

//hobj:= ImageEnView1.LayersCreatePolylineFromSelection(1, True); // ???
hobj:= ImageEnView1.LayersCreateFromEdge(X, Y, 20, False, 1); // WORKS BUT WANT DRAWFREEHAND OPTION

TIEPolylineLayer(ImageEnView1.CurrentLayer).SmoothJaggedEdges;
ImageEnView1.Update();

TIEPolylineLayer(ImageEnView1.CurrentLayer).SimplifyPolygon(100); // WORKS
ImageEnView1.Update();

Shrink/Expand Mask
//TIEPolylineLayer(ImageEnView1.CurrentLayer).Magnify.Rate:= 2; // ???

TIEPolylineLayer(ImageEnView1.CurrentLayer).AlphaEdgeFeathering:= 50; // WORKS
ImageEnView1.Update();

end;

Please advise - thanks

Andy
Go to Top of Page

andyhill

Australia
133 Posts

Posted - Aug 18 2022 :  20:15:32  Show Profile  Reply
OK, this is what I have got so far (LayerMask.dproj):-

procedure Tfmain.FormCreate(Sender: TObject);
begin
ImageEnView1.MouseInteractLayers:= [mlDrawCreatePolylineLayers, mlEditLayerPoints];
end;

// Post Process
procedure Tfmain.btnAndyClick(Sender: TObject);
begin

TIEPolylineLayer(ImageEnView1.CurrentLayer).SmoothJaggedEdges;
ImageEnView1.Update();

TIEPolylineLayer(ImageEnView1.CurrentLayer).SimplifyPolygon(100);
ImageEnView1.Update();

TIEPolylineLayer(ImageEnView1.CurrentLayer).FillColor:= clNone;
ImageEnView1.Update();

TIEPolylineLayer(ImageEnView1.CurrentLayer).AlphaEdgeFeathering:= 50;
ImageEnView1.Update();

TIEPolylineLayer(ImageEnView1.CurrentLayer).IsMask:= True;
ImageEnView1.Update();

//TIEPolylineLayer(ImageEnView1.CurrentLayer).MaskInverted:= True;
//ImageEnView1.Update();

SHRINK ???
EXPAND ???

TIEPolylineLayer(ImageEnView1.CurrentLayer).Cropped:= True;
ImageEnView1.Update();
end;

The freehand drawn polygon does not act as a mask, when I crop it reverts to a rectangle crop ???

Also I need Expand/Shrink Polygon Mask

Please advise

Andy
Go to Top of Page

xequte

38198 Posts

Posted - Aug 19 2022 :  00:46:26  Show Profile  Reply
Hi Andy

Your code above draws a polyline layer, not a selection.

https://www.imageen.com/help/TIEPolylineLayer.html


Is your end goal to crop the image around the boundary of the polyline layer?


You can convert a polygon layer to a polygon selection in one of two ways:

1. Adding polyline points to a selection

For each point of the polygon layer:
https://www.imageen.com/help/TIEPolylineLayer.GetPointEx.html

Add it as a selection point:
https://www.imageen.com/help/TImageEnView.AddSelPoint.html

Then remove the layer


2. Drawing the polygon layer to the mask

This is more complex, but you'd need to convert the polygon layer to a monochrome bitmap, starting with:

https://www.imageen.com/help/TIELayer.ConvertToImageLayer.html

And assign it to the selection mask:

https://www.imageen.com/help/TImageEnView.SelectionMask.html


There is no method to shrink or enlarge a selection, you would need to do some math on the polyline points to do it (e.g. by calculating the centroid and moving the points to/from that):

https://www.imageen.com/help/TIEPolylineLayer.CalculateCentroid.html



Nigel
Xequte Software
www.imageen.com
Go to Top of Page

andyhill

Australia
133 Posts

Posted - Aug 19 2022 :  02:32:02  Show Profile  Reply
As I await for answers to the above, I am trying to draw a rectangle shape in code against a background image of 7016px By 9921px at 300dpi.

Obviously we have to pan the image to allow the user to select an X/Y location for the rectangle shape to be positioned HOWEVER the X/Y mouse down click is not absolute addressing on MouseDown ???

Please show me how to compute the actual X/Y from the relative X/Y MouseDown position taking into account the zoom and pan offset so that the code generated Rectangle Shape is created in the correct position of the overall image.

ImageEnView1.LayersAdd(ielkShape);
TIEShapeLayer(ImageEnView1.CurrentLayer).Shape:= iesRoundRect;
ImageEnView1.CurrentLayer.PosX:= X - 500; //Round(zpx);
ImageEnView1.CurrentLayer.PosY:= Y - 500; //Round(zpy);
ImageEnView1.CurrentLayer.Width:= 1000; //Round(zw);
ImageEnView1.CurrentLayer.Height:= 1000; //Round(zh);
ImageEnView1.CurrentLayer.FillColor:= clNone;
ImageEnView1.CurrentLayer.AlphaEdgeFeathering:= 50;
ImageEnView1.CurrentLayer.IsMask:= True;


Andy
Go to Top of Page

xequte

38198 Posts

Posted - Aug 19 2022 :  04:05:52  Show Profile  Reply
Hi Andy

To convert screen values to bitmap values use:

https://www.imageen.com/help/TImageEnView.XScr2Bmp.html
https://www.imageen.com/help/TImageEnView.YScr2Bmp.html

Nigel
Xequte Software
www.imageen.com
Go to Top of Page

andyhill

Australia
133 Posts

Posted - Aug 19 2022 :  15:23:31  Show Profile  Reply
Thanks Nigel, it has been so long since working with EXE's (been in UniGUI World for a very long time).

Now that I have the rectangle shape how do I crop and save ?

ImageEnView1.CurrentLayer.IsMask:= True;
ImageEnView1.CurrentLayer.Selected:= True;
ImageEnView1.CurrentLayer.Cropped:= True;
w:= ImageEnView1.CurrentLayer.Width;
h:= ImageEnView1.CurrentLayer.Height;
bm:= TIEBitmap.Create;
ImageEnView1.CurrentLayer.CopyToBitmap(bm, w, h, True, True);
bm.CopyToClipboard(True, True, 300, 300);
bm.Free;

Does not include Background image section ??


Andy
Go to Top of Page

xequte

38198 Posts

Posted - Aug 20 2022 :  03:04:48  Show Profile  Reply
Hi Andy

So you have an image in the background layer (Layer[0]) and a rectangle shape layer (TIEShapeLayer at layer[1])?

So basically you want to crop the rect from ImageEnView1.Layers[0].Bitmap at the size and position of Layer[1].

So it should be:

ImageEnView1.LayersCurrent := 0; // Make background layer active
ImageEnView1.Proc.Crop( ImageEnView1.Layers[1].PosX,
                        ImageEnView1.Layers[1].PosY,
                        ImageEnView1.Layers[1].PosX + ImageEnView1.Layers[1].Width,
                        ImageEnView1.Layers[1].PosY + ImageEnView1.Layers[1].Height );
ImageEnView1.LayersRemove( 1 ); // Remove the shape layer

https://www.imageen.com/help/TImageEnProc.Crop.html

Nigel
Xequte Software
www.imageen.com
Go to Top of Page

andyhill

Australia
133 Posts

Posted - Aug 20 2022 :  17:11:17  Show Profile  Reply
Thanks Nigel but I only want to copy the shape area of Layer 0 to file, not crop Layer 0 (need Layer 0 to be unchanged).

Andy
Go to Top of Page

xequte

38198 Posts

Posted - Aug 21 2022 :  14:05:58  Show Profile  Reply
Hi Andy

Then is should be:

x := ImageEnView1.Layers[1].PosX;
y := ImageEnView1.Layers[1].PosY;
w := ImageEnView1.Layers[1].Width,
h := ImageEnView1.Layers[1].Height;

bm := TIEBitmap.Create( w, h );
ImageEnView1.Layers[0].CopyRectTo( bm, x, y, 0, 0, w, h, False );
bm.CopyToClipbord( True, True );
bm.Free;

https://www.imageen.com/help/TIEBitmap.CopyRectTo.html
https://www.imageen.com/help/TIEBitmap.CopyToClipboard.html

Nigel
Xequte Software
www.imageen.com
Go to Top of Page

xequte

38198 Posts

Posted - Aug 23 2022 :  17:24:57  Show Profile  Reply
Here is the code to convert a polyline layer to a polygon selection

ImageEnView1.LockPaint();
ImageEnView1.Deselect();
ImageEnView1.SelectionBase := iesbClientArea;
plyr := TIEPolylineLayer( ImageEnView1.CurrentLayer );
ImageEnView1.LayersCurrent := 0;  // Selecting layer 0
for i := 0 to plyr.PointCount - 1 do
begin
  xx := Round( plyr.GetPointEx( i, iepbClientArea).x );
  yy := Round( plyr.GetPointEx( i, iepbClientArea).y );
  ImageEnView1.AddSelPoint(xx, yy);
end;
ImageEnView1.EndSelect();
ImageEnView1.LayersRemove( plyr.LayerIndex );
ImageEnView1.UnlockPaint();



Nigel
Xequte Software
www.imageen.com
Go to Top of Page
  Previous Topic Topic Next Topic  
 New Topic  Reply to Topic
Jump To: