Scaling with the -fx operator

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
whugemann
Posts: 289
Joined: 2011-03-28T07:11:31-07:00
Authentication code: 8675308
Location: Münster, Germany 52°N,7.6°E

Scaling with the -fx operator

Post by whugemann »

I am trying to turn two vector sketch drawings into two raster images with the same scale. In both raster images I measure the length of a horizontal object and get a result of x which should correspond to n pixels. The width w' of the resulting image should be

w' = w * n / x

with w being the with of the original image. So I tried a command line like

convert non-scaled.png -resize "%[fx:w*830/450]" scaled.png

but this didn't work. Actually, I'm trying to do this in a batch file like

convert %1 -resize "%%[fx:w*%3/%2]" %~n1_scaled%~x1

If I however Identify things first, it works:

FOR /F %%i IN ('identify -format "%%[fx:w*%3/%2]" %1') DO convert %1 -resize %%i %~n1_scaled%~x1

which seems needlessly complicated. Is this a general limitation or just something in the Windows version? Or is there just somthing wrong with my Convert command line? The double quotes are needed under Windows, single quote don't work at all.
Wolfgang Hugemann
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Scaling with the -fx operator

Post by fmw42 »

convert non-scaled.png -resize "%[fx:w*830/450]" scaled.png
neither -resize (nor -crop) understands currently the fx calcs. But you can use -distort SRT and it will allow the fx calcs. Does not seem to work with -distort resize, though. So need to check with Anthony.

But this works to shrink the square image by a factor of 2 (a stupid calculation, but just to demonstrate).

convert zelda1.jpg +distort SRT "%[fx:0.5*w/h] 0" tmp.jpg

note the +distort so it crops it automatically.

I believe on Windows you may need to use %% rather than %.

With distort, you can also, I believe, set the -filter or -interpolate values to suit your anti-aliasing desires on quality depending upon minimizing or maximizing

See
http://www.imagemagick.org/Usage/distorts/#srt
http://www.imagemagick.org/Usage/distor ... rt_bestfit
http://www.imagemagick.org/Usage/distor ... ol_escapes (but fx calcs can be used also for any argument)
http://www.imagemagick.org/Usage/distorts/#summary


P.S.

But I don't understand why you cannot just compute the scale factor as percent (100*830/450)=184% rather than a width in pixels and just use

convert image -resize 184% resultimage

Fred
Last edited by fmw42 on 2011-06-07T20:01:27-07:00, edited 1 time in total.
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: Scaling with the -fx operator

Post by anthony »

whugemann wrote:So I tried a command line like

Code: Select all

convert non-scaled.png -resize "%[fx:w*830/450]" scaled.p
ng
but this didn't work.

Actually, I'm trying to do this in a batch file like

Code: Select all

convert %1 -resize "%%[fx:w*%3/%2]" %~n1_scaled%~x1
If I however Identify things first, it works:

Code: Select all

FOR /F %%i IN ('identify -format "%%[fx:w*%3/%2]" %1') DO convert %1 -resize %%i %~n1_scaled%~x1
which seems needlessly complicated. Is this a general limitation or just something in the Windows version? Or is there just something wrong with my Convert command line? The double quotes are needed under Windows, single quote don't work at all.
You have hit on of the MAJOR problems I am battling with for my re-development of the CLI in IMv7.

Basically geometry arguments can not handle percent escapes as it interferes with the normal '%' flag requirements of geometry expressions. :-(
See IM Examples, Basics, Argument Handling
http://www.imagemagick.org/Usage/basics/#arguments

ASIDE: one proposed solution is that % is only thought to be a %expansion : if it is followed by a '[' or is not after a digit
That is 50%x is NOT an expansion, but 50%[x] is while 50%%[ will replace %% with %

The real drawback of allowing % escapes is when DOS is involved! The % character was chosen so as not to interfere with shell (as the development team is essentially UNIX/Linux programmers). Unfortunately it interferes with DOS scripts.

With the above proposal the reduction of any occurrence of %% to % means that in dos to give a read '%' character in a geometry (not following a digit) you would need to use four percents! %%%% (unix shells get the same problem) Arrggghhhh!!!


Another proposal FIX for IMv7, is to restrict the use of % escapes in ALL arguments, except free-form strings.

Such as in -set as well as -label, -comments, -annotate etc. This will also remove there current use in arguments to -distort and -sparse-colors.

However if ANY argument is of the form %[...] then replace that argument with the pre-calculated escape sequence (doing escape sequence substitutions at that point if a global define).

That is for your specific problem THIS would then work, (in DOS) ...

Code: Select all

  -set myresize "%%[fx:w*%3/%2]" -resize "%%[myresize]"  
the advantage of this is that it includes 'named' argument. EG this would also work

Code: Select all

  -set my_method "Shepards" \
   -set my_args "0,0 %[fill] %w,%h %[background]" \
   -sparse-colors %[method] %[args]
Why you could then also use percent escapes in -draw, which is normally not permitted due to SVG compatibility reasons. BUT it can be included only if you follow the above syntax for the draw MVG command argument!

If -set is used escapes would be expanded immediately, and assigned to individual images. But if -define is use the escapes can be expanded WHEN used!

Why it could even be a way of seting up functional macros!

Code: Select all

  -define framing_function="-resize 50% -frame 6x6+2+2" \
  image.png %[framing_function]  result.png
Now that could be useful!


The other solution is to simply replace all % expansions everywhere with some other character -- but that would not be backward compatible, and finding a character is still a problem! Just looking over my keyboard I can see problems for ANY solution.

All proposals are online (update with above shortly) at
http://www.imagemagick.org/Usage/bugs/future/#settings
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: Scaling with the -fx operator

Post by anthony »

fmw42 wrote:neither -resize (nor -crop nor -size) understands currently the fx calcs. But you can use -distort SRT and it will allow the fx calcs. Does not seem to work with -distort resize, though. So need to check with Anthony.
[/quote]

-distort resize is special in that it does not take a distort floating point list argument, but a geometry argument, like resize.

That special argument is parsed using the same functions as resize so as to correctly handle percent flags, just like resize. Because of this you can not use percent escapes for the same reason you can't use them in -resize.

Basically it was the drawback of implementing a -distort resize to take resize arguments. :-(


However if I use the less complex second proposal (see above, or the final link I gave), then even distort arguments will not directly accept percent arguments. You will need to use them indirectly, just as shown for the -sparse-color example.

For IMv7 the second solution is looking the better solution, unless you (or someone else) can come up with a 3rd proposal for handling percent expansion in geometry arguments!

There is little time. In a couple of months I will have to start work on IMv7 CLI so as to make it into the beta release of IM v7. I need solutions!
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Scaling with the -fx operator

Post by fmw42 »

For IMv7 the second solution is looking the better solution, unless you (or someone else) can come up with a 3rd proposal for handling percent expansion in geometry arguments!
Sorry, you message above is rather complicated with various options. Which one are you saying you are currently leaning toward?

My opinion is that this is important to have as an ability. However, I suppose I could live with the -set to compute it and assign it to a name and then use the name to feed to things like crop and resize. Though doing it more directly as in distort would be preferable.

Fred
User avatar
whugemann
Posts: 289
Joined: 2011-03-28T07:11:31-07:00
Authentication code: 8675308
Location: Münster, Germany 52°N,7.6°E

Re: Scaling with the -fx operator

Post by whugemann »

I follwed Fred's suggestion and succeeded with the following batch command line:

convert %1 +distort SRT "%%[fx:%3/%2]%% 0" %~n1_scaled%~x1

(I had gone for -resize instead of -scale before, because I had been insecure where to put the percent signs for the scaling.)

Anthony's suggestion

convert -set myresize "%%[fx:w*%3/%2]" %1 -resize "%%[myresize]" %~n1_scaled%~x1

didn't work out; it just copied the original image to the new file.

I'm fine for the moment and can live with the +distort SRT solution.
Wolfgang Hugemann
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: Scaling with the -fx operator

Post by anthony »

whugemann I was not suggesting it would work NOW. I said as much at the start of the artical. Only pointing out that it is a problem that I am trying to work out a solution for IM v7 development, that has now started.

As I mentioned only the horrible DOS way of assigning output of commands to DOS variables is available to you. :-(


Shell scripts has the same problem, only the use of external shell variables, to define arguments in this way!


Fred Sorry for providing too much info. As mentioned it is a problem I have been working on a solution for for a long time, and I became excited as limiting the includes to -set, and providing only a global replace of an argument, only just occurred to me.

I am currently leaning to this -set method as it is simpler and more backward compatible with existing usage.

It means I then don't have to worry about the special use of '%' as a flag in geometry arguments, or even in -fx expressions! Because they will work exactly as they have always done. The only change to arguments is an 'all or nothing' replacement of the argument. It isn't specifically nice but better than forcing a change to current geometry handling for users and in the program.

By having a user use -set, the user is making a specific choice to handling the complexity involved with using '%', including the need to double up existing percents. Of course for DOS than means doubling already doubled percents (yuck). But it is a user choice for that complexity, not something that is being forced on them to deal with in ALL arguments.


I welcome any suggestions, but remember complexity is best avoided if possible. Preferably with backward compatibility.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Scaling with the -fx operator

Post by fmw42 »

Withdrawn. Sorry I don't know windows variables and thought you were just using 3/2.
Post Reply