-distort

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Post Reply
User avatar
GreenKoopa
Posts: 457
Joined: 2010-11-04T17:24:08-07:00
Authentication code: 8675308

-distort

Post by GreenKoopa »

A FYI more than a question. I was having difficultly making my images line up after a -distort resize and crop. Sometimes they would, but other times it would be off by a little or an entire pixel. It turns out that the distort:viewport setting rounds all four values to integers. Then this is multiplied by distort:scale and rounded again.

Searching for an alternative, I noticed something else. These are nearly the same, but not always identical:
convert in.jpg -define distort:viewport=200x104+24+24 -define distort:scale=0.625 -distort SRT 0 out_1.png
convert in.jpg -define distort:viewport=200x104+0+0 -define distort:scale=0.625 -distort SRT "24,24 1 0 0,0" out_2.png
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: -distort

Post by fmw42 »

I believe if you do the latter, the distort x,y coordinates permit decimal fractions. I suspect the the viewport (like crop) will not. They will either round or truncate to integer pixels. I am not sure which. So if you want a more accurate result and know the decimal fractions you want, I would use the latter method.

But I will defer to Anthony for a correct response.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: -distort

Post by fmw42 »

Does changing the -virtual-pixel affect the extra column you are getting? If so, you can make it say transparent and then use -trim to remove it.
User avatar
GreenKoopa
Posts: 457
Joined: 2010-11-04T17:24:08-07:00
Authentication code: 8675308

Re: -distort

Post by GreenKoopa »

fmw42 wrote:Does changing the -virtual-pixel affect the extra column you are getting?
Unfortunately not. I am cropping an arbitrary (often interior) area of an image while down-sampling.

To achieve accurate viewport offsets while using distort:scale, they must be moved into the -distort SRT arguments. The offsets are still scaled and fx is still available. The page information does't get updated and this does affect the anchor for rotations and translations.

To address the viewport size rounding issue, distort:scale must be moved into the -distort SRT arguments. The viewport setting must then be scaled manually (calculator or fx expression).

This example of my progression lines up every result to be an integer (viewport geometry compatible with scale factor), but this will rarely be the case.
: This is how I have been doing my resize with crop
convert in.jpg -define distort:viewport=200x104+24+24 -define distort:scale=0.625 -distort SRT 0 out_1.png
: This moves the viewport offsets. Compare detects a moderate change here, but I can't see it.
convert in.jpg -define distort:viewport=200x104 -define distort:scale=0.625 -distort SRT "24,24 1 0 0,0" out_2.png
: This moves the scale factor. This compares identically to the previous step.
convert in.jpg -set option:distort:viewport "%%[fx:200*0.625]x%%[fx:104*0.625]" -distort SRT "24,24 0.625 0 0,0" out_3.png
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: -distort

Post by anthony »

While distort can distort images to factional pixels, you can not store or calculate the colors for an image with fractional pixels. As such viewport is limited to integers. The same thing of course will happen when a 'global output scale' is used, the resulting viewport is limited to integer pixels.

Now output scaling is just that, output scaling, and is performed external to the distortion itself. It is really meant to be only used for integer scaling, AKA Super-sampling.

However ALL the distorts had some form of true distortion scaling built into them, and that is what should be used.
When scaling is done that way the viewport will matchup with the actual image bounds (plus 1 or 2 pixels for filter blur)

The image virtual offset however will be correct, as per 'sub-pixel positioning', regardless.
You must compare images while taking the virtual offset (whcih may be negative) into account!

Can you supply a link to your 'in' image?
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
User avatar
GreenKoopa
Posts: 457
Joined: 2010-11-04T17:24:08-07:00
Authentication code: 8675308

Re: -distort

Post by GreenKoopa »

I liked using distort:scale because it allowed me to specify my viewport size and offset in before-scaling terms. I would determine my area of interest using Gimp, say 3696x2464+580+496. Given an image and this geometry, I used IM to output the area down-sampled to several sizes. A much simplified example:

Code: Select all

convert photo.jpg ^
( +clone ^
  -set option:distort:viewport 3696x2464+580+496 -set option:distort:scale "%%[fx:1920/3696]" -distort SRT 0 ^
  -write photo_4x6.jpg +delete ) ^
( +clone ^
  -set option:distort:viewport 3696x2464+580+496 -set option:distort:scale "%%[fx:576/3696]" -distort SRT 0 ^
  -write photo_576x384.jpg +delete ) ^
null:
I never noticed before that using a non-integer scale could cause problems. I guess it was close enough until now. I can, and will, move the scale factor to the distort parameters, but this will mean I must scale the viewport values for each resize. fx is one option, but this would be very messy.
anthony wrote: Can you supply a link to your 'in' image?
I was using this image from this page. Adding a -depth 16 will allow for more accurate results from -metric. The difference image from the compare is interesting, many red vertical and horizontal lines. At integer scales there is no difference, so my offsets and method is correct. But I don't understand why the difference when the non-integer scale factor doesn't cause rounding to the viewport values. I always assumed the commands I gave would be synonymous, and I still can't pinpoint why they are not.
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: -distort

Post by anthony »

It is more about where the global scaling is applied.
It basically adds more pixels to the viewport area

Hmmm... psuedo-code...

just before main loops start, the viewport is adjusted as follows...

Code: Select all

   Test for scaling setting {
      output_scaling = scaling_value_given_float
      geometry.width=  integer (output_scaling*geometry.width+0.5)
      geometry.height= integer (output_scaling*geometry.height+0.5);
      geometry.x= integer (output_scaling*geometry.x+0.5);
      geometry.y= integer (output_scaling*geometry.y+0.5);
   } 
   Adjust filter window by output_scaling factor
In main loop... i,j is output pixel

Code: Select all

   destination.x = (geometry.x+i+0.5)*output_scaling;
   destination.y = (geometry.y+j+0.5)*output_scaling;

   the scaled filter distortion is done, and color of pixel i,j sampled from source image.
NOTE that the result is the conversion of pixle I,J to destination X,Y is scaled appropriatally.
The Sub-pixel locations within the viewport remains correct, scalling is about origon!

The viewports at two different scales will NOT align except at the image coordinate 0,0, or if a integer scale is used.
0,0 is actually a pixel edge, and not the center of a pixel.

The viewport that is enlarged is of the unscaled image. Distort should be used to actually scale the image in a fixed sized viewport.


If you have a better idea, that does not interfer with integer 'supersampling' scaling. I am all ears!
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
Post Reply