ImageMagick v7 --
Percent Escapes and FX Expression Development

Index
ImageMagick Examples Preface and Index
Known and Fixed Bugs Index

Use of percent escapes in ALL arguments (implemented in IMv7)

This is a suggestion that popped up from quite a large number of sources, in many different forms. Basically it is a way of retrieving colors, and image widths and heights from images either in memory or on disk. Basically allow users to make use of escape substitution in all option arguments. The problem is, that 'percents' are also often used as special 'flags' in things like 'geometry' expressions, and as such should not expand. Settings could be used to hold... numbers, colors, arguments, method names, filenames, and even operational sequences (like a complex function).
WARNING: some options have delayed percent escape expansion: For example "-define", "-label", "-caption", "-comment", "-format".  These must store the given string, including all percent escapes, without modification. Note that "-label" is equivalent to "-define label=..." which does NOT perform any percent escapes until the define is actually used. (delayed escaping).

The Implemented Proposal....

Proposal, allow percent escapes in all arguments, but restricts exactly when a percent escape is recognised. Specifically if the % is after a number, don't expand it, as it is a number percentage.
100%x30       rgb(100%,100%,100%,.5)
More specifically: Expand percent escapes when there is no digit before it, unless followed by a '[' or escaped by another '%'. That allows you to override the percent after number rule. That is, these are expanded, or escaped... But these are expanded as percent escapes...
100%%     %wx%h      max=%[maximum]  100%[x]30 
That is, the double percent is shrunk to a single percent (escape).
While the others do not have a digit before it, or is followed by '['. Note that '100%x30' did not expand the 'x', but '100%[x]30' does expand '%[x]' (X resolution or density). The BIG problem is it is overly complex, and may cause a few problems for DOS users which also use percent escapes in its scripting. However in general it will mean things just work as the user would expect in most situations. The only time it fails is if a number is given before the percent prefix character. Full Example in use...
magick -size 100x100 xc: -print '45%x\n' null:
45%x
magick -size 100x100 xc: -print '45%[h]\n' null:
45100
magick -size 100x100 xc: -print '45x%h\n' null:
45x100
magick -size 100x100 xc: -print '%wx%h\n' null:
100x100

Expansions to Percent Escapes...

Suggestions to alleviate some smaller existing problems with percent escapes.
  • Allow "%[w]" to be equivalent to just "%w", currently this does NOT work. Note that "%[width]" does NOT mean the same thing! That is, the original width of the image, not the current width.
  • Access to more attributes and especially operational settings. For example "%[fill]", "%[background]", "%[mattecolor]".
  • As part of this expansion "-set background" should be equivalent to "-background" command. In fact most settings may be handled in this way. Also remember the difference in usage of "-define label=..." vs "-set label ...".
  • Have alternative color string escapes beyond "%[pixel:...]" which returns either a color name or a rgb() value. For example "%[rgb:...]" and "%[rgba:...]" which forces the color output to the 'rgb(...)' forms. And "%[hexcolor:...]" for the colorspace independent '#......' form. -- NOT implemented

From this point things have not been implemented

Other Existing Problems (IMv7)...

  • Inter-Image Propriety Copying... You currently can not access say the comment of image 3 to use in setting the comment of image 1.
  • Multi-Image String selection... You can not select strings based on some number, for example you can not implement something like the pseudo-code
          if %w > 500 then "too wide code", otherwise "normal code" Perhaps a boolean string selector?
          %[select: %[fx:w>500] : %[value1] : %[value2] ]
    But that seems messy to me. Also that will not let you do selections by string compares!
          if %m == 'JPG' then "Lossy", otherwise "non-Lossy" On the other hand a selection of numbers and colors can be done using FX That is, this works...
          %[pixel:w>h?red:blue]
    or to only shrink images that are too wide...
          -resize '%[fx: w>500 ? 500 : w ]x' Ideally both string handling (Percent escapes) and number mathematics (FX expressions) needs to be merged more fully. Some good macro handling of strings is needed.

Formatting Percent Escapes...

Currently there is only minimal formatting the number resulting from an FX expression using the -precision setting. You can not specify number of digits, leading spaces or alignment. Similarly there is no way to format a simple number percent escape such as %X exactly as you want. For example to always include leading numerical sign. Proposed Solution: '%[...][format]' where '...' is a normal percent escape and 'format' is a printf() format for a single floating point number or string. (could a integer %x format be allowed - for colors?) For example: '%[w][%03g]' image width containing least 3 digits, using leading zeros. Or '%[fx:100*s.h/u.h][%06.2f]%%' which calculates the percentage height relative to first image in the current image list, but outputting a string 6 digits long filled with leading zeros, and 2 decimal places, and a final percent symbol. For example the result of the above expression could be something like... "098.30%" This can also be used for string to space it out to X characters.
For example.. %[background][%-20s] NOTE: in this sceme you will need to escape the '[' if the format is NOT what you want. EG: %[f]\[] Alternative... Use a %[..] printf style of string function.
%[printf:format:argument]
For example
%[printf:%%03g:%w]
this allows the formatting string and argument to also expanding percent escapes!Can %[..] handle nesting of %[..], and what of single ']' in strings?
Would this mean to include % in the printf format you would need %%%% ?

FX Expression handling

Initial Recommendations...

  * FX access to image information, including user defined numerical
    'properties' and 'artifacts', possibly even evaluate expressions.

    For example pre-calculate and save statistic information and constants
    into pre-image properties or global artifacts, then call FX which uses
    that pre-calculated numbers so as to avoid recalculating them all the
    time.

     EG:  -define fx:angle=10  -fx 'r*log(angle)'

  * Saving FX constants into properties. This will allow you to do your own
    'tally' of image information, and each FX expression is parsed.
    Note that some values may be different for different images!!!

Problems...

 * Single letter variable names in FX do not match those in percent escapes?

 * What if you want to access the meta-data of a different image?
   You can access pixel data, why not metadata?


Additional Recommendations

  * FX expression first parsed into an execution tree

  * FX variables are both numbers and strings (like awk)

  * Remove '%' to mean modulus, but 'setting lookup' instead.
    Or again only allow  %[...] as being different to just %

  * Various string processing functions.

  * Allow FX to format strings and numbers for output.

Discussion...
  https://imagemagick.org/discourse-server/viewtopic.php?f=1&t=19273

Specially involving the security concerns of allowing 'eval' or repeated
execution of arguments.  That is, what if FX expressions are found in
a input string?

----
FX Access to Percent Escapes (simple numbers and colors)


For example  tint a image by the background color...

    -fx '( u + %[background] )/2'

The %[background] will be replaced by the current background color value of the
image in the expression before being executed across the whole image.

However for FX this may mean that the modulus operator  '%' may either always
need doubling (%%), OR replacing that operator with a mod()  function.
Alternately only allow %[...] syntax in FX expressions.


NOTE: I will also have the problem of percent escapes in percent escapes.
For example

   -background  '%[pixel: ( u.p{0,0} + %[fill] ) / 2  ]'

So I need to make sure that percent escapes become savvy enough to allow
embedded percent escapes