Page 1 of 1

clipping path is distorted, when the image is cropped

Posted: 2008-01-09T15:04:29-07:00
by thodberg
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>

Re: clipping path is distorted, when the image is cropped

Posted: 2008-01-09T19:52:13-07:00
by anthony
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.

Re: clipping path is distorted, when the image is cropped

Posted: 2008-01-09T20:46:01-07:00
by jn0101
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

Re: clipping path is distorted, when the image is cropped

Posted: 2008-01-09T22:45:33-07:00
by anthony
jn0101 wrote:Anyway it must be quite easy in the simple case of cropping.
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.

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.

Re: clipping path is distorted, when the image is cropped

Posted: 2008-01-10T02:21:55-07:00
by jn0101

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.
As I am quite desperate I will have to try this solution, and then improve it later on.

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

Re: clipping path is distorted, when the image is cropped

Posted: 2008-01-10T05:19:13-07:00
by anthony
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.

Re: clipping path is distorted, when the image is cropped

Posted: 2008-01-15T00:13:33-07:00
by jn0101
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.

Re: clipping path is distorted, when the image is cropped

Posted: 2008-01-18T01:35:57-07:00
by jn0101
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.

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++;
			}
		}
	}
Next, code that traverses a path and fix knot point coordinates:

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:
			}
		}
	}
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

Re: clipping path is distorted, when the image is cropped

Posted: 2008-01-24T23:44:06-07:00
by jn0101
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:

Code: Select all

				if (count % 2 == 1) n--; //XXX NEW
And regarding to
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.
Could you please reply as requested and state whether or not you will consider this code?
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

Posted: 2008-01-25T07:08:26-07:00
by magick
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

Posted: 2009-01-30T13:45:51-07:00
by rvanderkooy
Will this fix be released?

Thanks,
Ryan

Re: clipping path is distorted, when the image is cropped

Posted: 2009-07-02T06:02:21-07:00
by jn0101
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

Re: clipping path is distorted, when the image is cropped

Posted: 2009-07-02T16:59:46-07:00
by anthony
jn0101 wrote:Anyone familiar with C and IM could insert this code in IM source and create a patch.
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!

I myself have a lot of this to be added, updated to IM.