Skew Image by only 1 pixel
Skew Image by only 1 pixel
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
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
-
- Posts: 12159
- Joined: 2010-01-23T23:01:33-07:00
- Authentication code: 1151
- Location: England, UK
Re: Skew Image by only 1 pixel
What version of IM?
The documentation http://www.imagemagick.org/script/comma ... .php#shear seems to be wrong. It says:
... but experimentation suggests that when Ydegrees is omitted it defaults to Xdegrees. So I suggest you use:
Does that help?
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.
Code: Select all
magick "In.tiff" -shear 0.0028956274x0 "Out.tiff"
snibgo's IM pages: im.snibgo.com
- GeeMack
- Posts: 718
- Joined: 2015-12-01T22:09:46-07:00
- Authentication code: 1151
- Location: Central Illinois, USA
Re: Skew Image by only 1 pixel
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
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".
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Skew Image by only 1 pixel
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
Actually I use imageMagick 7.0.8-29 with windows 10 64bitsnibgo 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:... but experimentation suggests that when Ydegrees is omitted it defaults to Xdegrees. So I suggest you use:Code: Select all
When Ydegrees is omitted it defaults to 0.
Does that help?Code: Select all
magick "In.tiff" -shear 0.0028956274x0 "Out.tiff"
I checked adding x0 to the shear command, but it did not change the result.
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.GeeMack wrote: ↑2019-06-19T07:19:10-07:00
You can use "-distort affine" to get that result, while letting ImageMagick calculate the angle.
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.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
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".
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
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?
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Skew Image by only 1 pixel
Please post your input and output images to some free hosting service and put the URL here so we can check against your results.
-
- Posts: 12159
- Joined: 2010-01-23T23:01:33-07:00
- Authentication code: 1151
- Location: England, UK
Re: Skew Image by only 1 pixel
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:
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):
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
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
snibgo's IM pages: im.snibgo.com
Re: Skew Image by only 1 pixel
Hi all,
sorry for the late reply...
It works now, thanks!
sorry for the late reply...
It works now, thanks!