ImageMagick v6 Examples --
Future Development

Index
ImageMagick Examples Preface and Index
Known and Fixed Bugs Index
This page known problems in areas of IM currently under development, so are not true bugs, but works in progress. Also listed below are new enhancements and suggested development within ImageMagick itself.

Future Development Proposals

This is a list of existing problems, and wants in ImageMagick. It is also a sort of un-offical guide for things I may try to implement in IM.

Anything listed here is open for review, comment or suggestion, but should be taken with a grain of salt as they may never actually be implemented. though the more comments people make on the ImageMagcik Discussion forum and in emails to me, the more likely it will get implemented!


MVG expansion to allow full use of SVG gradients

SVG gradients which are overlaid as a 'fill tile', can be defined using multiple colors (not just two), linearly from one point to another (any angle), radially, or using path shapes. The how range is defined in the SVG -- Scalable Vector Graphics manual.

Currently IM only supports vertical linear gadients across the whole canvas of the image.

This lack is becoming important as just about every SVG image I have looked at relies of gradients of various forms for shading images. Without it the SVG image conversion are basically yuck!.

An expandsion of the "gradient:" syntax to provide extra options would also be good. For example (posibility only)
  gradient:'red=.1-green=.3-blue=.9, 1,1, 50,90'
These are suggestions for the future development for IM. They are currently not being developed but have been requested my myself and other users on the IM mail lists and web forum.

Some of these may never be developed, others may not be provided until a new major version number release of IM. Some may appear next week!

If you feel you can help, you can attempt to program these into IM and send the patches to Crisy. I am sure he wold welcome them.


Scripted form of Convert Command

What is really needed is for the command line API to be re-written in such as way as to allow...

This re-write may require some re-coding of mogrify which current does some very weird argument handling to seperate the list of images to process, from the operations and settings needed to process them. For example some settings need to be pre-set before reading the first image!

Actually if a "loop over image list" type construct is implemented, then it may be posible to make 'morgify' a special case of convert, just as 'montage' is a special convert with post processing of the final image list in memory.

This new command line API could in fact be done as a separate command to convert, but will need someone to get the ball rolling and keep it moving. One previous attempt that failed (probably was done before IM was ready for it) was "conjure". the new version would have to be BOTH command line and script capable, and do what convert does to properly replace convert.


Auto-levels, Stretching, Auto-Gamma, De-normalizing problem

A IM Forum Discussion has resulted in a request for a "-histogram-stretch" operator which normalizes the image so that the given percentage of the brightest and darkest pixels are pegged to black and white. That is a single odd white or black pixel will not majorly effect the overall result.

A "-linear-stretch" operator was also added recently.


Another IM mail list discussion between Jason Lamey and Ed Halley, talked about a posible gamma level auto adjusting operator.

Fit a gaussian peak to a histogram. This will give you a peak position, and a width for the peak (two half-widths, actually). Then choose a gamma value that will realign the distribution to be more centered and appropriately wide.

Redistributing the Histogram based on 'equalizing' the colors to fit a gaussian peak was also suggested by a image expert Fred Weinhaus. The overall brightness and contrast of an image can then be controled by two simple arameters (mean and std).

 A simpler and linear transformation can be effective if one computes the
linear transformation from a formula that uses desired mean and standard
deviations along with the image's actual mean and standard deviation. That was
why I was asking if you have a function that can extract the images mean and
standard deviation (as well as the min and max values). Something like
"-identify or info:" but more of an image statistics function that would report
these values per channel.  This could be very useful.  
I have yet to find a real-world use for "-equalize"


The current "-contrast-stretch" operator normalizes images using the peak color values in the image, then moving those points inward by the percentages given. This provides a more controled normalize.

Current Recommended Solution...

Linear 'stretching' methods should be able to...

For example woring with 8bit values and image with min = 100  and max =
200 (make it easy) and a autolevel parameter of say 20 (units).

  1/  find the max and min values than move inward by 'percentage'
      so min+20  max-20   =>  level 120,180
      (black/white point arguments are 'color values')

  2/  cut off 20 pixel values from each end of the histogram
      (black/white point arguments are 'pixels')

  3/  select the value of the first bin from each end where the number
      of values in the exceeds 20  (the height of the bin)
      (black/white point arguments are 'pixels per bin')

Also note that histograms have multiple types.
   separate color channels,  grayscale,  all values
   luminance (HSL colorspace)

Once the points have been determined (per channel or combined channels)
then the 'level' routines can be used to do the 'stretch' (as per -level).

Implementation should separate the generation of histogram data that can then
be used by various histogram modification methods. Including the posibility of
the data of one image being used for a completely different image!

Data output should correctly handle 8-bit histogram output (existing bug).

The data can also be used to generate, histogram gradients, cumultive histogram
gradients. Also we should be able to do gradient graphing (profile
generation), rather than using external image generating applications.

The data will also be used for equalize, and equalize-gaussian, histogram
re-distribution, as well as histogram thresholding methods, and histogram
segmentation.


Better handling of histograms, as LUT gradient images

Hmmmmm....   I wonder if we can change the histogram: usage.

That is  histogram: currently outputs a simple normalized  LUT  histogram
(one row)  and also we add   cumulative:  to output a normalize cumulative
histogram.

BUT we also add    graph:   which graphs a LUT image!

Now that would be great!  It can even follow the techniques that you
developed in your "profile" script.  Or the displacement graphing
technique I developed.



Better still lets take all this OUT of the output and make them
operations.

   -histogram  -cumulative  -graph

Now this would be great!!!  Of course they can still contain a
comment of the actual values.

Divide an image into horizontal rows (or columns) of pixels

Given an image, divide the image into rows (or columns) basied on rows of pixels which are simular to each other (according to the fuzz factor).

One implementation would be to divide image into blank,non-blank... alturnating rows extracted from the image. An argument can used to place constraints on the minimum size for the separate blank and non-blank areas. A missed image at the start can denote if the first part was non-blank, something that is commonly just junked.

The offset positions can be kept or junked as per crop.

Two operators may be needed, -divide-vert and -divide-horiz.
EG: divide-horizontally +{bw}+{nbw}

Complementary operators such as -layers 'remove-blank' and -layers 'remove-null' may be needed to allow user to also delete 'blank' images if these are unwanted.

ADDUMDUM I wrote a script divide-vert whcih does basically what I am suggesting gets built into IM.

Another similar script is de-pixelate which removes 'doubled' rows and columns of pixels from an image.


Miscellanious functions to be added..

Other fuctions...

Consolidation of Specialized Blur Options

Currently we have two specialised blur operations... "-radial-blur" and "-motion-blur" as generic blur operations.

First of all "-radial-blur" is miss-named, as it is really a rotational blur. A radial blur would blur out from the center point of the image or region, not in a circle around that point.

Secondally these speciallised blurs are only the start of a whole set of blur type operations that should be made available. And implementing as a single option per blur type woudl produce far too many options. It needs to be consolidated before new types of blurs are introduced.

I can see 7 types of special blurs...
Type Direction Description
linear one direction like -motion-blur
linear both directions like a 1d blur, but at any angle)
rotational one direction like a electron around an atom
rotational both directions like -radial-blur
radial out of small circles would look like
asteroids speeding from the center
radial into things heading toward the center
radial both in & out

I propose a single 2 argument operator for specialised blurs...
   -special-blur {type} {radius}x{sigma}+{dir}+{angle}
Where...

I do not want to seperate these into seperate settings as they are linked too closely to the specific operation being performed.


Specify the exact "Quantum Range" for specific output formats

At this time depth is generally restricted to 8 or 16 depending on the compile time Q-level of your IM installation. That is setting of "-depth 4" only results in 8 bit images, not 4 bit images. Of course that is only valid if the image format and IM even allows the use of 'depths' for that image format. These depth/quantium restriction is becoming a problem for many image formats such as NetPBM, TXT (IM pixel enumeration), BMP, TIFF... etc..

Actually instead of "-depth", prehaps we can specify an exact "-quantum" for text image formats such as TXT: PGM: PPM: all of which should allow you to specify a different 'quantium' for its format.
   convert -size 1x1000 gradient:  -quantum  1000  t.pgm

    P2
    1 1000
    999
    999 998 997 ... 3 2 1 0
Where all image data values are in the 0 to 999 inclusive range.

If "-quantum" is unspecified (or reset using "+quantum"), it can fallback set to a default of 2^depth (if it ever allows depths other than 8 and 16!)


Image layout methods

Addition of "layout" methods to "convert".

For example a 'layout' method to generate a montage 'grid'. A fixed sized grid of cells with optional spacing between cells. Spacing may be negative to allow overlapping images, but will NOT 'clip' edge images (due to negative spacing) as "montage" currently does.

Note that spacing is not just a 'border' added to each image, as spacing on ends is the same as in the middle, except in the negative case. Implementation can ignore any existing 'virtual canvas' setting, and use virtual canvases to do image layout efficientally.

Or 'lines' whcih appends images horizontally (with given spacing), with vertical "-gravity" alignment, until "-size" width, is reached. The line is then horizontally -gravity justified, and padded to the "-size" width. When the height of all the lines exceeds a optionally given "-size" height, a new page is started, but pages are not padded (to allow user justification with "-extent").

Similarly for a 'columns' layout method but vertically, down the 'pages'.

The "+/-append" operator could be classed as a special ("-size" is not defined) case of the above two layout methods.

Other posible methods could include 'best fit into page' using various 2D 'napsack packing' algorithms.

All methods however should record and keep track of the location each image ended up, for the purpose of 'HTML' image map generation. Something that "montage" currently does but which goes wrong in its 'concatenate' mode.

The above does NOT need to deal with 'captions' or 'labels' as these should be taken care of by pre-layout operators.


Output size control for Montage

Often it is imposible for a user to know how big a "montage" will be, and it has, many times, been suggested that some sort of output size control added.

That is specify a final size and geometry size, and let montage work out the tiling, (and perhaps geometry spacing) to produce however many pages are nessary. Of course if the width of the individual tiles (as determined by -geometry is more that the final output size, then all bets are off, and a warning probably should be issued.

Or, specify the final size and number of tiles, then let montage work out the geometry needed. What algorithm should be used for figuring out tile size verses tile spacing is another matter, particularly when labels and framing also needs to taken into account.

It may be that in both cases some extra boarder space will be required to 'pad out' the image to the exact image size requested, as a variable geometry or tile setting may not generate an exact fit.

At the moment there is no defined method of setting a final output image size. Also what should "montage" do if all three (size, tile, geometry) is given.


One suggestion is to allow the use of a '!' flag to "-tile" as meaning a 'fit to this size if posible' setting. Of course the -tile setting (and extra boarder space) would then be the variable part of the montage generator.

EG: "-tile 800x600\!" would mean that montage will try to adjust the tile counts to form pages that fit into a final image of this size.

OR: "-tile 800x\!" will only adjust the number of columns to fit into 800 pixels, in a single page of appropriate length.

Some extra spacing may have to be added to the edges to handle any remaining space that can't be assorbed by the tile geometry size or spacing.


Shadow controls in Montage (interface change - require major release)

Add some control to shadows within "montage" to allow user defined hard or soft shadows in a simular way that the new "convert", "-shadow" operator does.

No suggestions as to implimentation, as "montage" "-shadow" setting should probably remain a boolean on/off operator, unless it is added as part of a major version number release.

Simularly add some extra framing controls, would be nice if more that a single number is given.


Text/Image Justification Setting (as distinct to gravity positioning)

Seperate the controls for text/image justification from the gravity defined position. Justification should also have vertical and horizontal attributes.

Horizontal Attributes: left, center, right
Vertical Attributes: top, middle, baseline, bottom
The setting should consist of one item from both aspects.

If the justification is unset the gravity setting can be use to define the missing justification attribute to use...
   gravity_setting       default justification attributes
      undefined             Left       Baseline      (Top for images)
      North                 Center     Top
      South                 Center     Bottom
      East                  Right      Middle
      West                  Left       Middle

      Center                Center     Middle

      ... other gravity settings as appropriate ...
Note that 'Baseline' has no meaning for image justification. But if specifically given for an images it should probably be equal to either 'Bottom', 'Middle' or prehaps to align with text better, 1/3 from the Bottom.


FX and Regions

Having FX obey region limits will be a nice way of restricting its processing to a smaller part of an image.

  convert -size 5x5 xc:white -channel R \
          -region 1x1+2+2 -fx 'debug(u)' null: 2>&1 | sort
[IM Text]

This does not however work yet.


Setting arguments from in memory images and/or other settings

This is a suggestion that popped up from quite a large number of souces. in many different forms. Basically it is a way of retreving colors, and image widths and heights from images either in memory or on disk.

This is has now been particialy implemented, at least for "-format", "-label" and "-annotate". Basically in places where you can specify 'format escapes', and basically allows called to the 'fx expresion handler' to perform mathematical espressions.

For example, these can NOW be used...
Number of pixels in an image...
   convert rose: -format "pixels: %{fx:w*h}" info:
   pixels: 3220

Color of a specific pixel (this needs to be changed to return a color)
   fmt="color 12,36: rgb("
   fmt="$fmt%[fx:floor(p{12,36}.r*256)],"
   fmt="$fmt%[fx:floor(p{12,36}.g*256)],"
   fmt="$fmt%[fx:floor(p{12,36}.b*256)])"
   convert rose: -format "$fmt" info:

   color 12,36: rgb(115,112,105)

This is now implemented as
    convert rose: -format '%[pixel:p{12,36}]' info:
Whcih will use rgb() or color names as appropriate.

The FX escapes has also been augmented to include new shortcuts such as.
   s  = current image in sequence (for FX escapes, u otherwise)
   t  = index of current image (for FX escapes, 0 otherwise)
   u  = first image in sequence
   v  = second image in sequence
   n  = number of images in sequence
   i  = column offset of purrent pixel (for -fx operator, 0 otherwise)
   j  = row offset of purrent pixel (for -fx operator, 0 otherwise)

  with the default image now being 's' rather than 'u'. 

For more detail see FX Expressions as Format and Annotate Escapes.

for example...  Using bias to 'add' a constant

  convert -delay 10 rose: \( -clone 0,0,0,0,0,0,0,0,0,0,0 \) \
          -set option:bias '%[fx:t/12*QuantumRange]' -convolve 1 \
          -loop 0  miff:- | animate -

NOTE: 'n' will work in -fx  but not in  %fx  as only one image is available
As such some progress has even been made with this proposal, (see the rounded corners example) but is proving more difficult due to interfacing with the various API's (which has no concept of a 'current image sequence').

-----

Expand format escapes into geometry, and color arguments.

Example... set a background color to an average of an image
  convert rose: -resize 1x1 -background '%{fx:u}' +delete .... 
Example... Create a canvas the same size as the Fifth image in memory, using its center (posibly interpolated) color.
  convert ....  -size '%[fx:u[4].w]x%[fx:u[4].h]' \
                xc:'%[pixel: u[4].p{u[4].w/2,u[4].h/2} ]' ...  
----

Addendum: from cristy...
The operator xc:'p{30,40}' requires a prior image from the image stack.
Currently there is no method to access prior images from a coder module.  You
also need to keep in mind that APIs generally have no fixed 'current image
sequence' to refer to.  So how do we feed prior images so the fx expression
can get at the pixels (p{30,40}) when so specific image sequence is available?

Instead we may be able to say something like-

  convert rose: -define mypixel p{30,40} -size 100x100  xc:mypixel ...

Unfortunately the current color method signatures do not have access to
either the image or image_info structure and in many places where the color
methods are called they may not be available.  These are required to grab
image pixels, image attributes, or defines.  That means only the MPR is
available which could be ugly and slow. MPR is like a global variable for
images.

All-in-all this is a complex problem that is going to take some time to
implement properly if at all.
However the information is available before the xc: image read! That is at the API level!
Created: 1 November 2005 from 'testing' page
Updated: 15 July 2009
Author: Anthony Thyssen, <A.Thyssen@griffith.edu.au>
Examples Generated with: [version image]
URL: http://www.imagemagick.org/Usage/bugs/future/