Page 1 of 1

Skew Image by only 1 pixel

Posted: 2019-06-19T06:22:47-07:00
by AlexZ
Hi all,

I want to skew the top side of an image by 1 pixel to the right. In the comand line option I found the shear command. To calculate the shear angle. I used:

<shear angle> = arctan(1/<vertical image resolution>)

In the present case I had a vertical resolution of 19787 pixel, so I get a shear angle of 0,0028956274 degree, means the command line I used is:

"In.tiff" -shear 0.0028956274 "Out.tiff"

To test it I used a solid black image. Unfortunately the left border of the image is skewed less than 1 pixel (I guess around 0.5) and the right side is skewed more than 1 pixel (i guess around 1.5). I know the angle is very small, but necessary for the application. Is there any way to solve this?

Regards, Alex

Re: Skew Image by only 1 pixel

Posted: 2019-06-19T06:52:50-07:00
by snibgo
What version of IM?

The documentation http://www.imagemagick.org/script/comma ... .php#shear seems to be wrong. It says:

Code: Select all

When Ydegrees is omitted it defaults to 0.
... but experimentation suggests that when Ydegrees is omitted it defaults to Xdegrees. So I suggest you use:

Code: Select all

magick "In.tiff" -shear 0.0028956274x0 "Out.tiff"
Does that help?

Re: Skew Image by only 1 pixel

Posted: 2019-06-19T07:19:10-07:00
by GeeMack
AlexZ wrote: 2019-06-19T06:22:47-07:00I want to skew the top side of an image by 1 pixel to the right.
You can use "-distort affine" to get that result, while letting ImageMagick calculate the angle.

Code: Select all

convert in.tiff -virtual-pixel black +distort affine "0,0 1,0 0,%[h] 0,%[h] 1,%[h] 1,%[h]" -shave 1 out.tiff
That essentially slides the top row one pixel to the right, keeps the bottom row locked in place, and moves all the intermediate rows fractionally to create the shear angle.

Using the plus form of "+distort" adjusts the viewport size to contain the entire resulting image, and in most instances it will add another single pixel all around in order to not lose any information at the edges. The "-shave 1" removes that single row of pixels all around. If you want to maintain the input viewport dimensions, just use "-distort" instead of the "+" plus form, and don't "-shave" it at the end.

If you're using IM version 7, use "magick" instead of "convert".

Re: Skew Image by only 1 pixel

Posted: 2019-06-19T08:21:41-07:00
by fmw42
What is your platform? Please always provide your IM version and platform when asking questions. If you are on a Unix-like system, then I have a bash unix shell script (skew) for imagemagick that will skew by either degrees or pixels. See my link below.

Re: Skew Image by only 1 pixel

Posted: 2019-06-21T01:58:01-07:00
by AlexZ
snibgo wrote: 2019-06-19T06:52:50-07:00 What version of IM?

The documentation http://www.imagemagick.org/script/comma ... .php#shear seems to be wrong. It says:

Code: Select all

When Ydegrees is omitted it defaults to 0.
... but experimentation suggests that when Ydegrees is omitted it defaults to Xdegrees. So I suggest you use:

Code: Select all

magick "In.tiff" -shear 0.0028956274x0 "Out.tiff"
Does that help?
Actually I use imageMagick 7.0.8-29 with windows 10 64bit

I checked adding x0 to the shear command, but it did not change the result.
GeeMack wrote: 2019-06-19T07:19:10-07:00
You can use "-distort affine" to get that result, while letting ImageMagick calculate the angle.

Code: Select all

convert in.tiff -virtual-pixel black +distort affine "0,0 1,0 0,%[h] 0,%[h] 1,%[h] 1,%[h]" -shave 1 out.tiff
That essentially slides the top row one pixel to the right, keeps the bottom row locked in place, and moves all the intermediate rows fractionally to create the shear angle.

Using the plus form of "+distort" adjusts the viewport size to contain the entire resulting image, and in most instances it will add another single pixel all around in order to not lose any information at the edges. The "-shave 1" removes that single row of pixels all around. If you want to maintain the input viewport dimensions, just use "-distort" instead of the "+" plus form, and don't "-shave" it at the end.

If you're using IM version 7, use "magick" instead of "convert".
I checked this solution, basically it works, but if I check the result picture there are some artefacts in the upper left and upper right corner.

Code: Select all

magick In.tiff -virtual-pixel white +distort affine "0,0 1,0 0,%[h] 0,%[h] 1,%[h] 1,%[h]" -shave 1 Out.tiff
I tested a solid black square and changed the background for the skew operation to white.
In this case the upper left corner pixel is not white, but the pixel below are white.
For the upper right corner the pixel is not black, but the ones below are black.

Is there any way to improve this?

Re: Skew Image by only 1 pixel

Posted: 2019-06-21T07:43:25-07:00
by fmw42
Please post your input and output images to some free hosting service and put the URL here so we can check against your results.

Re: Skew Image by only 1 pixel

Posted: 2019-06-21T08:04:42-07:00
by snibgo
The "+distort" sets canvas offsets, so you might want "+repage" before saving.

The distort uses the default filter. You might prefer a specific filter, such as "-filter Point" (or even Box) before the distort.

Each pixel has a non-zero area. The distort process actually re-samples pixels, rather than simply "moving" them. You can manipulate the height parameters to, for example, get your expected result on the bottom row.

To more clearly see what happens, I use a 5x5 black square, and don't shave, and scale up the result:

Code: Select all

magick -size 5x5 xc:Black  -virtual-pixel white  -filter Point +distort affine "0,0 1,0 0,%[fx:h-0.5] 0,%[fx:h-0.5] 1,%[fx:h-0.5] 1,%[fx:h-0.5]" +repage +write info: -scale 4000x4000% skew5x5.png
Image

EDIT to add: And to get top and bottom as you might want it (note the 0.5 offsets to move the centres of the pixels):

Code: Select all

magick -size 5x5 xc:Black  -virtual-pixel white  -filter Point +distort affine "0.5,0.5 1.5,0.5 0,%[fx:h-0.5] 0,%[fx:h-0.5] 1,%[fx:h-0.5] 1,%[fx:h-0.5]" +repage +write info: -scale 4000x4000% skew5x5b.png
Image

Re: Skew Image by only 1 pixel

Posted: 2019-07-09T06:51:19-07:00
by AlexZ
Hi all,

sorry for the late reply...
It works now, thanks!