clipping path is distorted, when the image is cropped
clipping path is distorted, when the image is cropped
When an image is cropped, then the clipping path is scaled
proportional to the size of the cropped image. If for example
the image is cropped to half of its original size, then the area
of the clipping is also reduced to half of its original size in pixel.
The problem can be reproduced with the attached file in the
following way:
convert -crop 50x50+20%x+20% path_test.jpg test22.jpg
When you compare the clipping path of the to file you will see the difference:
identify -verbose test22.jpg will give this result:
<svg width="71" height="56">
<g>
<path style="fill:#00000000;stroke:#00000000;stroke-width:0;stroke-antialiasing:false" d="
M 25.61,16.2379
L 45.7023,16.7584
L 45.8064,32.3717
L 25.7141,33.4126
"/>
</g>
</svg>
identify -verbose path_test.jpg will give this result:
<svg width="142" height="112">
<g>
<path style="fill:#00000000;stroke:#00000000;stroke-width:0;stroke-antialiasing:false" d="
M 51.2199,32.4758
L 91.4047,33.5167
L 91.6129,64.7435
L 51.4281,66.8253
"/>
</g>
</svg>
proportional to the size of the cropped image. If for example
the image is cropped to half of its original size, then the area
of the clipping is also reduced to half of its original size in pixel.
The problem can be reproduced with the attached file in the
following way:
convert -crop 50x50+20%x+20% path_test.jpg test22.jpg
When you compare the clipping path of the to file you will see the difference:
identify -verbose test22.jpg will give this result:
<svg width="71" height="56">
<g>
<path style="fill:#00000000;stroke:#00000000;stroke-width:0;stroke-antialiasing:false" d="
M 25.61,16.2379
L 45.7023,16.7584
L 45.8064,32.3717
L 25.7141,33.4126
"/>
</g>
</svg>
identify -verbose path_test.jpg will give this result:
<svg width="142" height="112">
<g>
<path style="fill:#00000000;stroke:#00000000;stroke-width:0;stroke-antialiasing:false" d="
M 51.2199,32.4758
L 91.4047,33.5167
L 91.6129,64.7435
L 51.4281,66.8253
"/>
</g>
</svg>
- anthony
- Posts: 8883
- Joined: 2004-05-31T19:27:03-07:00
- Authentication code: 8675308
- Location: Brisbane, Australia
Re: clipping path is distorted, when the image is cropped
Clipping paths are not adjusted by most IM commands as they are more format specific and not part of normal raster image processing.
As such they are generally wrong after any form of crop or resize.
The best idea is to apply the clipping path to the image first so that it is no longer required.
As such they are generally wrong after any form of crop or resize.
The best idea is to apply the clipping path to the image first so that it is no longer required.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
https://imagemagick.org/Usage/
Re: clipping path is distorted, when the image is cropped
I was going to post about this, but I see someone else has already done the work
Retaining clipping path when cropping is very important for us, we cannot just throw it away or apply it!
I understand from viewtopic.php?f=3&t=10317 that general conservation of clippath is a hard problem, but can it really be true that this is not a priority for IM development?
Anyway it must be quite easy in the simple case of cropping.
Could you give some clues or ideas about how to work around this?
What is the chance that IM could implement correct clip path handling in the case of cropping?
If chances == 0%, could you point me some advice about how to implement correct clip path handling in the case of cropping myself?
Thank you!
Jacob
Retaining clipping path when cropping is very important for us, we cannot just throw it away or apply it!
I understand from viewtopic.php?f=3&t=10317 that general conservation of clippath is a hard problem, but can it really be true that this is not a priority for IM development?
Anyway it must be quite easy in the simple case of cropping.
Could you give some clues or ideas about how to work around this?
What is the chance that IM could implement correct clip path handling in the case of cropping?
If chances == 0%, could you point me some advice about how to implement correct clip path handling in the case of cropping myself?
Thank you!
Jacob
- anthony
- Posts: 8883
- Joined: 2004-05-31T19:27:03-07:00
- Authentication code: 8675308
- Location: Brisbane, Australia
Re: clipping path is distorted, when the image is cropped
Actually it isn't!!! You need to locate lines that either get croped, or pass through the crop area (with end points outside the crop area), then crop the lines appropriatally.jn0101 wrote:Anyway it must be quite easy in the simple case of cropping.
A simplier solution may be to just subtract the top-left corner of from all the coordinates of the lines, but then many lines may be outside the image area, and I am not certain just how valid that is, or how other programs will reach to things like negative coordinates, or other out pf range coordinates.
As for development, it is that it isn't important, it is getting someone who has the time and interest in that specific development to start adding 'clip path' fixes to various IM core functions.
I myself am trying to get more time to get back to Image Distortion stuff, after doing a major overhaul of resize filter functions (specifically for more image distortion work). others Are similarly bogged down in long Todo lists.
As such if you think it is important, download a subversion copy of the source and look at trying to do something about it. the code isn't really that hard when you have a huge library of existing code to follow and example from. Adding to existing code is a lot easier than trying to create new code.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
https://imagemagick.org/Usage/
Re: clipping path is distorted, when the image is cropped
Code: Select all
A simplier solution may be to just subtract the top-left corner of from all the coordinates of the lines, but then many lines may be outside the image area, and I am not certain just how valid that is, or how other programs will reach to things like negative coordinates, or other out pf range coordinates.
Please, I beg you, could you please provide some hints on doing this!
I can imagine that in transform.c I will have to add some code in
MagickExport Image *CropImage(const Image *image,const RectangleInfo *geometry,
ExceptionInfo *exception)
{
Could you *please* try to give some code that gets the coordinates
This is what I suppose is needed:
char
*property;
const char
*value;
property=AcquireString("#1");
(void) FormatMagickString(property,MaxTextExtent,"8BIM:1999,2998:%s",
pathname);
value=GetImageProperty(image,property);
... and then what?
Which format is the value in?
Is this property in the same format that TraceSVGClippath in property.c uses, so that
I could use a modified version?
Please help a little, I am desperate and I will do all the number crunching myself, if you just help me a little with the IM code.
Thank you!
Jacob
- anthony
- Posts: 8883
- Joined: 2004-05-31T19:27:03-07:00
- Authentication code: 8675308
- Location: Brisbane, Australia
Re: clipping path is distorted, when the image is cropped
That is a problem as I have not dealt with clipping path before myself.
I am not certian how it is stored in the Image data structure.
I have looked at cropping before, for the handling of virtual canvas information.
The crop routine is a single image routine as the calling function (API interface) deals with the looping through the image sequence, which simplifies matters.
I am not certian how it is stored in the Image data structure.
I have looked at cropping before, for the handling of virtual canvas information.
The crop routine is a single image routine as the calling function (API interface) deals with the looping through the image sequence, which simplifies matters.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
https://imagemagick.org/Usage/
Re: clipping path is distorted, when the image is cropped
OK, here's is what I have found out:
The operation is really simple in the case of cropping as the clipping path is allowed to exeed the image borders with a factor of 16 (according to Adobe's spec).
It just boils down to parse the coordinates (as it is done in TraceSVGClippath()) in property.c, translate and scale them and write them back. Its really simple.
As unfortunately I can get no help from you with the IM specific code I have chosen to do so from Java instead.
I hope someone with enough expecience with IM code will at some time do this in C so everyone can get the benefit of my work.
What I imagine is something like:
MagickExport Image *CropImage(const Image *image,const RectangleInfo *geometry,
ExceptionInfo *exception)
{
...
translatePaths(Image, geometry)
In this method we would have to iterate over all paths.
This method would be interesting to use:
GetImageProperty(image,"8BIM:1999,2998:#1");
however it only gives the FIRST path, and it parses it as SVG, which we won't need.
Therefore a separate method would have to be written that found all 8BIM properties from 1999 to 2998 and translated the points coordinates.
I will send in a separate post how this would be done in Java, but if you look at TraceSVGClippath() its simply the cases
switch (selector)
{
case 1:
case 2:
case 4:
case 5:
that would need to have their coordinates translated.
The operation is really simple in the case of cropping as the clipping path is allowed to exeed the image borders with a factor of 16 (according to Adobe's spec).
It just boils down to parse the coordinates (as it is done in TraceSVGClippath()) in property.c, translate and scale them and write them back. Its really simple.
As unfortunately I can get no help from you with the IM specific code I have chosen to do so from Java instead.
I hope someone with enough expecience with IM code will at some time do this in C so everyone can get the benefit of my work.
What I imagine is something like:
MagickExport Image *CropImage(const Image *image,const RectangleInfo *geometry,
ExceptionInfo *exception)
{
...
translatePaths(Image, geometry)
In this method we would have to iterate over all paths.
This method would be interesting to use:
GetImageProperty(image,"8BIM:1999,2998:#1");
however it only gives the FIRST path, and it parses it as SVG, which we won't need.
Therefore a separate method would have to be written that found all 8BIM properties from 1999 to 2998 and translated the points coordinates.
I will send in a separate post how this would be done in Java, but if you look at TraceSVGClippath() its simply the cases
switch (selector)
{
case 1:
case 2:
case 4:
case 5:
that would need to have their coordinates translated.
Re: clipping path is distorted, when the image is cropped
Here is, as promised, the Java code that translates and scales (clipping) paths correctly.
First, code to find 8BIM segments with ID between 2000 and 2998.
beforeCropDimension has the width and height of image before cropping, croppedRectangle has the x and y of upper left cropping point and width and height of image after cropping.
Next, code that traverses a path and fix knot point coordinates:
Please compare to TraceSVGClippath() in property.c and you'll quickly get an idea about how this would easily be done in C by someone who knows IM internals.
I really hope you cat get the time to get the fix into the C code at some time. Please let me know if you do.
Thanks,
Jacob Nordfalk
First, code to find 8BIM segments with ID between 2000 and 2998.
beforeCropDimension has the width and height of image before cropping, croppedRectangle has the x and y of upper left cropping point and width and height of image after cropping.
Code: Select all
private static void findAndTranslatePaths(byte[] b, int n, int lgd, Dimension beforeCropDimension, Rectangle croppedRectangle) {
int slutN = n + lgd;
while (n < slutN) {
if (b[n] == '8' && b[++n] == 'B' && b[++n] == 'I' && b[++n] == 'M') {
int ID = (0xff & b[++n]) * 256 + (0xff & b[++n]);
byte count = b[++n];
++n;
String path_name = new String(b,n,count);
n += count;
if (count % 2 == 1) n--; //XXX NEW
int str = (((0xff & b[++n]) * 256 + (0xff & b[++n])) * 256 + (0xff & b[++n])) * 256 + (0xff & b[++n]);
n++;
if (ID>=2000 && ID<=2998) {
translatePath(b,n,str, beforeCropDimension, croppedRectangle);
}
n = n + str; if (str%2==1) n++;
} else {
n++;
}
}
}
Code: Select all
private static void translatePath(byte[] b, int ofs, int str, Dimension beforeCropDimension, Rectangle croppedRectangle) {
for (int i=0; i<str; i+=26) {
int n = ofs+i;
int selector = (0xff & b[++n]) + (0xff & b[++n]) * 256;
switch (selector)
{
case 1:
case 2:
case 4:
case 5:
/*
Sub-path knot
*/
for (int j = 0; j < 3; j++) {
int y = ReadPropertyMSBLong(b, n); // read coordinate
double dy = (double) y * beforeCropDimension.height / 4096 / 4096; // scale down
double dy2 = dy - croppedRectangle.y; // translate origin
double afterCropDimension_height = croppedRectangle.getHeight();
int y2 = (int )(((dy2 * 4096 * 4096) + 0.5)/afterCropDimension_height); // scale up
WritePropertyMSBLong(b,n,y2); // write back
n+=4;
int x = ReadPropertyMSBLong(b, n);
double dx = (double) x * beforeCropDimension.width / 4096 / 4096; // scale down
double dx2 = dx - croppedRectangle.x; // translate origin
double afterCropDimension_width = croppedRectangle.getWidth();
int x2 = (int )(((dx2 * 4096 * 4096) + 0.5)/afterCropDimension_width); // scale up
WritePropertyMSBLong(b,n,x2); // write back
n+=4;
}
break;
case 0:
case 3:
break;
default:
}
}
}
I really hope you cat get the time to get the fix into the C code at some time. Please let me know if you do.
Thanks,
Jacob Nordfalk
Re: clipping path is distorted, when the image is cropped
Sorry, a small bug had sneaked in in case of a pathname with oneven length.
I have edited the previous post to include de fix:
And regarding to
I don't want to waste your time and my time submitting fixes if this subject is so uninteresting to IM developers that you even dont find the time to look at my posts!
Thank you,
Jacob Nordfalk
I have edited the previous post to include de fix:
Code: Select all
if (count % 2 == 1) n--; //XXX NEW
Could you please reply as requested and state whether or not you will consider this code?I really hope you cat get the time to get the fix into the C code at some time. Please let me know if you do.
I don't want to waste your time and my time submitting fixes if this subject is so uninteresting to IM developers that you even dont find the time to look at my posts!
Thank you,
Jacob Nordfalk
Re: clipping path is distorted, when the image is cropped
We consider all improvements/patches that users post. However, our to-do list has over 300 items on it so we do not not have an ETA on when we will get to reviewing your code.
Re: clipping path is distorted, when the image is cropped
Will this fix be released?
Thanks,
Ryan
Thanks,
Ryan
Re: clipping path is distorted, when the image is cropped
Hi rvanderkooy,
Apperently never
However I have posted the Java code. And its working great for us.
Anyone familiar with C and IM could insert this code in IM source and create a patch.
So, the real question migt be: When will someone pay a C prof do it.
Im sure IM would accept a patch ready to insert in the C code.
Yours,
Jacob
Apperently never
However I have posted the Java code. And its working great for us.
Anyone familiar with C and IM could insert this code in IM source and create a patch.
So, the real question migt be: When will someone pay a C prof do it.
Im sure IM would accept a patch ready to insert in the C code.
Yours,
Jacob
- anthony
- Posts: 8883
- Joined: 2004-05-31T19:27:03-07:00
- Authentication code: 8675308
- Location: Brisbane, Australia
Re: clipping path is distorted, when the image is cropped
So download the SVN code and create a patch (diff) file for submission. This does not need much work to review and insert so it gets done fast. I did my original changes to IM this way. Don't forget the patch for ChangeLog too!jn0101 wrote:Anyone familiar with C and IM could insert this code in IM source and create a patch.
I myself have a lot of this to be added, updated to IM.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
https://imagemagick.org/Usage/