Can Visio cut shapes from images like Photoshop?

Started by Jennifer, May 07, 2023, 04:52:32 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

wapperdude

Just a followup...here's link to Affinity Designer 2 showing cutting (fragment):  https://affinity.help/designer2/English.lproj/index.html?page=pages/ObjectControl/cutting.html?title=Cutting%20objects

Less expensive than Photoshop I believe.
Visio 2019 Pro

Jennifer

Using Visio 2019, part of Office 365 on Windows 10

Yacine

#17
To be honest I wouldn't know how to do it in Photoshop.

But here is a solution in Visio.

Key is the cell "ClippingPath". It allows to define an outer curve for an image shape.
https://learn.microsoft.com/en-us/office/client-developer/visio/clippingpath-cell-foreign-image-info-section

With a little automation you can select the image shape, then the jigsaw shapes.
Then the macro copies the geometry section of each jigsaw shape into a copy of the image shape and assigns the clippingPath cell to the newly imported geometry section.
Done.


Option Explicit

Private Sub cmProcess_Click()
  Dim frameShp As Shape
  Dim frameShp2 As Shape
  Dim picShp As Shape
  Dim picShp2 As Shape
  Dim JSshp As Shape
  Dim JSshp2 As Shape
  Dim JSshp3 As Shape
  Dim sel As Selection
 
  Dim arShpIDs As Variant
  Dim vShpID As Variant
 
  Dim x1 As Double
  Dim y1 As Double
  Dim x2 As Double
  Dim y2 As Double
 
  Set picShp = ActivePage.Shapes.ItemFromID(tPic.Value)
  getExtends picShp, x1, y1, x2, y2
  Set frameShp = ActivePage.DrawRectangle(x1, y1, x2, y2)
 
  arShpIDs = Split(tShapes.Value, ";")
  For Each vShpID In arShpIDs
    Set JSshp = ActivePage.Shapes.ItemFromID(vShpID)
    Set JSshp2 = duplicateInPlace(JSshp, "JigSawShape2")
    Set frameShp2 = duplicateInPlace(frameShp, "Frame2")
    Set picShp2 = duplicateInPlace(picShp, "PicShape2")
   
    ActiveWindow.DeselectAll
    ActiveWindow.Select frameShp2, visSelect
    ActiveWindow.Select JSshp2, visSelect
    ActiveWindow.Selection.Join
    Set JSshp3 = ActivePage.Shapes.Item(ActivePage.Shapes.Count)
    JSshp3.Name = "JigSawShape3"
   
    picShp2.AddSection visSectionFirstComponent + 1
    picShp2.AddRow visSectionFirstComponent + 1, visRowComponent, visTagComponent
   
    Dim row_ As Integer
    Dim col_ As Integer
    Dim rowType_ As Integer
    For row_ = 1 To JSshp3.RowCount(visSectionFirstComponent)
      rowType_ = JSshp3.rowType(visSectionFirstComponent, row_)
      picShp2.AddRow visSectionFirstComponent + 1, row_, rowType_
      For col_ = 0 To JSshp3.RowsCellCount(visSectionFirstComponent, row_) - 1
        picShp2.CellsSRC(visSectionFirstComponent + 1, row_, col_).Formula = JSshp3.CellsSRC(visSectionFirstComponent, row_, col_).Formula
      Next col_
    Next row_
   
    picShp2.Cells("ClippingPath").Formula = Chr(34) & "Geometry2.path" & Chr(34)
    picShp2.Cells("pinx").Formula = picShp2.Cells("pinx").ResultIU + picShp2.Cells("width").ResultIU + 2
    JSshp3.Delete
   
  Next vShpID
  frameShp.Delete
End Sub

Function duplicateInPlace(shp As Shape, Optional ShapeName As Variant) As Shape
  Dim shp2 As Shape
  Set shp2 = shp.Duplicate
  shp2.Cells("pinx").Formula = shp.Cells("pinx").ResultIU
  shp2.Cells("piny").Formula = shp.Cells("piny").ResultIU
  If Not IsMissing(ShapeName) Then
    shp2.Name = ShapeName
  End If
  Set duplicateInPlace = shp2
End Function

Private Sub cmSelPic_Click()
  If ActiveWindow.Selection.Count <> 1 Then
    MsgBox "Please select one picture shape.", vbOKOnly
    Exit Sub
  End If
  tPic.Value = ActiveWindow.Selection(1).ID
End Sub

Private Sub cmSelShapes_Click()
  Dim shp As Shape
  Dim temp As String
  For Each shp In ActiveWindow.Selection
    temp = temp & shp.ID & ";"
  Next shp
  If Right(temp, 1) = ";" Then
    temp = Left(temp, Len(temp) - 1)
  End If
  tShapes.Value = temp
End Sub

Sub getExtends(ByRef shp As Shape, ByRef x1 As Double, ByRef y1 As Double, ByRef x2 As Double, ByRef y2 As Double)
  x1 = shp.Cells("pinx").ResultIU - shp.Cells("locpinx").ResultIU
  x2 = x1 + shp.Cells("width").ResultIU
  y1 = shp.Cells("piny").ResultIU - shp.Cells("locpiny").ResultIU
  y2 = y1 + shp.Cells("height").ResultIU
End Sub


Downside, each new jigsaw shape has the size of the original shape. Got stuck on this one. May one of the peer members help?
Yacine

Yacine

Yacine

Jennifer

Quote from: Yacine on May 10, 2023, 08:51:39 PM
And here the stencil with the macro.

Wow! That will take me a bit of time to get my head around...

Thanks
Using Visio 2019, part of Office 365 on Windows 10

Yacine

#20
Quote from: Jennifer on May 10, 2023, 08:58:25 PM
Wow! That will take me a bit of time to get my head around...

No need to get your head around it.
Just start the form in the stencil (Open the VB editor and run the form).

Note - The jigsaw pieces must be placed on top of the image in order to work properly and at the right place.
Place you image, create the jigsaw pieces, move them over the image.
Start the form, select the image shape, click on first button to get its ID, then select all the jigsaw pieces, press the second button, then the 3rd one ("process").
The image shape may be hidden by all the jigsaw shapes. You can move one those shapes to the side to select the image, then move the jigsaw shape back to its position. Alternatively remove the fillings of the jigsaw shapes.
Yacine

Jennifer

Quote from: Yacine on May 10, 2023, 09:04:44 PM
No need to get your head around it.
Just start the form in the stencil (Open the VB editor and run the form).

Ok, thanks
Using Visio 2019, part of Office 365 on Windows 10

Visisthebest

Visio 2021 Professional

Jennifer

Quote from: Visisthebest on May 11, 2023, 10:58:41 AM
Can't this be solved with a bit of VBA?

Do you mean cutting out pieces? If there is a VBA solution, I would love to know what it is. I don't have a clue as to how to do it.
Using Visio 2019, part of Office 365 on Windows 10

wapperdude

@Yacine:  not sure I get the point.

The OP wants to take a picture, foreign object if you will, and slice it to make a puzzle.  Very simple objective.  Visio, out-of-the-box, won't do that. 

I admit, I haven't tried your code, but your comment about "original size" was, discouraging, unless I misunderstand. 
PowerPoint and other non-stop programs appear to have solutions.  Unfort, my version of PPt, is lacking key feature shown in videos, so I cannot verify.  Nonetheless, all videos seem to indicate fairly straight forward, built-in solutions.

Visio 2019 Pro

Yacine

#25
@Wapperdude
My sad face palm picture was because of Visisthebest's suggestion to use VBA without having read that I posted already such a solution. Anyway - we are nice people here, so I deleted it.

Regarding my solution, it is indeed not perfect yet. The cut shape looks as needed, but its boundaries are those of the big image.
That is why I asked whether someone else could have a look.
Please have a try.

Meanwhile a muse came flying by. I will try to crop the image first, without relying on the helper rectangle.

Rgds,
Y.
Yacine

Yacine

Quote from: wapperdude on May 11, 2023, 05:55:10 PM
Visio, out-of-the-box, won't do that.

And that's where Visio shines, why I love it so much. Having the possibility to implement a feature, that wasn't planed, one that belongs to another software group.
Awesome!
Yacine

wapperdude

LOL.

I get the obvious point.  Most of us have either witnessed it, even victim of it, or even guilty of it.  I speak from experience.    Many times, more than a forehead slap comes to mind as an appropriate response.  "My tongue is numb!"
Visio 2019 Pro

Yacine

#28
Cropping the image before assigning the ClippingPath worked fine.


PROBLEM: The clipping path seems to have issues with complicated NURBS rows. I don't know how to fix it.
You can compare the geometry sections of the original and the new shape. No difference, but other appearance.
So the tool is obviously limited to simpler shapes. Sorry.
Yacine

Yacine

And here the drawing and the updated stencil.
Yacine