Inkscape.org
Creating New Extensions rotate and move a clipped image back to position
  1. #1
    dr_erk dr_erk @dr_erk

    Hi,

    I'm trying to clip an image with a copied path and then rotate and move the clipped image back to the original path position. (see attached picture) But i don't know how to  ´get this done. 

    the plan is to first rotate the cliped image around it's bbox center, then get a new bbox center and translate this to the original path position. The operation works individually but when i combine i does not., It seems like it first does the translation, and then rotate it with the center of rotation as before the translation.

    here is my code:

        def move_to_org_pos(self, org_item, image, angle):
            org_center = org_item.bounding_box().center
            im_center = image.bounding_box().center
            
            rotate_transform = inkex.Transform()
            rotate_transform.add_rotate(angle)
            image.transform = image.transform @ rotate_transform
            
            # new bounding box center after rotation
            im_center = image.bounding_box().center
            move_transform = inkex.Transform()
            move_transform.add_translate(org_center[0] - im_center[0], org_center[1] - im_center[1])

            image.transform = image.transform @ move_transform   

     

    BR Erik

    Clip And Move Back
  2. #2
    inklinea inklinea @inklinea⛰️

    It's a bit difficult to understand, what is the reason for the first rotation ? 

    What is the before and after you are trying to achieve. 

    Also once you get into filters / clipping etc, you have to be aware of visual vs geometric bounding boxes.

     

  3. #3
    dr_erk dr_erk @dr_erk

    I'll try to explain.

    1 The path in the top right corner of the white page is copied

    2. I rotate and move the copied path over the image ( shark) to catch the pattern i want (manualy).

    3. The image is duplicated and cliped.

    4. I reteive the angle of the rotation of the path that were used  as a clip-path

    5. Then I want to rotate and move back the cliped image to the positian of the  path  in the top right corner of the white page. (this is the function in the first post)

     

    Do you understand what I want to do?

     

  4. #4
    dr_erk dr_erk @dr_erk

    I'll try to explain.

    1 The path in the top right corner of the white page is copied

    2. I rotate and move the copied path over the image ( shark) to catch the pattern i want (manualy).

    3. The image is duplicated and cliped.

    4. I reteive the angle of the rotation of the path that were used  as a clip-path

    5. Then I want to rotate and move back the cliped image to the positian of the  path  in the top right corner of the white page. (this is the function in the first post)

     

    Do you understand what I want to do?

     

  5. #5
    dr_erk dr_erk @dr_erk

    I'll try to explain.

    1 The path in the top right corner of the white page is copied

    2. I rotate and move the copied path over the image ( shark) to catch the pattern i want (manualy).

    3. The image is duplicated and cliped.

    4. I reteive the angle of the rotation of the path that were used  as a clip-path

    5. Then I want to rotate and move back the cliped image to the positian of the  path  in the top right corner of the white page. (this is the function in the first post)

     

    Do you understand what I want to do?

     

  6. #6
    dr_erk dr_erk @dr_erk

    sorry for three repetitions of the same answer. don't know how that happened.
    But I think the problem is as you stated that cliped image has different visual and geometric bounding boxes.

  7. #7
    inklinea inklinea @inklinea⛰️

    Yes, 

    I think the problem however can be solved in the following way:

    When you rotate a path - inkscape will recalculate the points - it generally does not add transforms  ( open the Edit>XML Editor and look what happens when you tap [] to rotate ) 

    However if you group  that path - transforms on the group should be used instead of recalculating the path.

    So grouping before etc should enable you to  work with transforms, at least before the clip.

  8. #8
    Kaalleen Kaalleen @Kaalleen

    If you do it as @inklinea said (using a group for manual transformations), then you can get the transformation of the clip group and subtract it from the elements transformation like so:

    for g in element.clip:
        element.transform.add_matrix(-g.transform)

    You may want to check if clip is not None or if you are getting a group or something else, etc. This is just a hint on how you could proceed.

  9. #9
    inklinea inklinea @inklinea⛰️

    haha kaaleen - I didn't know you could use a minus sign !!!!!

    I wrote this:

    def get_inverse_transform(self, transform):
        import numpy
        my_object_np_matrix = list(transform.matrix)
        my_object_np_matrix.append((0, 0, 1))
    
        inverse_matrix = numpy.linalg.inv(my_object_np_matrix)
    
        inkscape_inverse_matrix = inverse_matrix.tolist()
        inkscape_inverse_matrix.pop(2)
    
        inverse_transform = Transform().add_matrix(inkscape_inverse_matrix)
    
        return inverse_transform

     

  10. #10
    inklinea inklinea @inklinea⛰️
    *

    Some slightly mad coding including a command call !

    Is this what you were trying to do ( video attached ) 

    I've attached the svg too.

    Peek 2023 01 19 18 45
  11. #11
    dr_erk dr_erk @dr_erk

    Yes!  exactly what I’m trying to do. 
    how did you do it? Is it the code above?

    will look into this later tonight!
     

  12. #12
    inklinea inklinea @inklinea⛰️
    *

    https://gitlab.com/inklinea/mad-clip-transform

    Please note - my coding is probably a bit crazy. Appears Under Extensions>Mad Clip Transform

    Requires a grouped path and an image - there is no need to duplicate images etc - the extension will take care of that in the background.

    As with anything involving Transforms - can be tripped up by layer transforms if you have objects across layers - usually these are created when you use Edit>Resize Page to selection.

    Enjoy.

    I should point out it does require Inkscape 1.2+, as the command line call it uses - the syntax changed in 1.2

    It could be made to work with 1.1 and below - but would require using command line verbs etc.

  13. #13
    Kaalleen Kaalleen @Kaalleen

    Oh, this really looks like a lot of code for the task. Here is what I would do (just posting in case this may help, but go with whatever works best for you):

    from inkex import ClipPath, EffectExtension, errormsg
    
    
    class ClipAndRotate(EffectExtension):
    
        def effect(self):
            images = []
            groups = []
    
            for element in self.svg.selection:
                if element.TAG == 'g':
                    groups.append(element)
                elif element.TAG == 'image':
                    images.append(element)
    
            if not images or not groups:
                errormsg("Please select an image and a group")
    
            # only process the first image, but allow multiple groups (for whatever reason)
            image = images[0]
            parent = image.getparent()
            index = parent.index(image)
    
            for g in groups:
                transform = -g.transform
                new_image = image.copy()
                parent.insert(index, new_image)
                clip = ClipPath(g)
                self.svg.defs.add(clip)
                new_image.clip = clip
                new_image.transform.add_matrix(transform)
    
    
    if __name__ == '__main__':
        ClipAndRotate().run()

     

  14. #14
    inklinea inklinea @inklinea⛰️

    Yes I would recommend using Kaalleen method. 

    I failed to realised how simple applying a clip path actually - is. 

    I used a command call - which was not needed, also using the minus sign in -g.transform a lot easier than making your own reverse matrix.

    Thanks Kaallen for your help.

  15. #15
    dr_erk dr_erk @dr_erk

    Thanks very much booth of you :)

  16. #16
    dr_erk dr_erk @dr_erk

    Very clean solution Kaalien! It works like a charm! 

Inkscape Inkscape.org Inkscape Forum Creating New Extensions rotate and move a clipped image back to position