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.
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)
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)
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)
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.
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.
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.
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.
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()
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
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.
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?
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?
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?
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.
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.
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:
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.
haha kaaleen - I didn't know you could use a minus sign !!!!!
I wrote this:
Some slightly mad coding including a command call !
Is this what you were trying to do ( video attached )
I've attached the svg too.
Yes! exactly what I’m trying to do.
how did you do it? Is it the code above?
will look into this later tonight!
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.
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):
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.
Thanks very much booth of you :)
Very clean solution Kaalien! It works like a charm!