Use the following information to implement the highest quality possible downscaling and upscaling in python using pillow and numpy. Information 1: 
ImageMagick v6 Examples --
Resize or Scaling (General Techniques)
Index
ImageMagick Examples Preface and Index

    Resizing Images

        Ignore Aspect Ratio ('!')
        Only Shrink Larger ('>')
        Only Enlarge Smaller ('<')
        Fill Given Area ('^')
        Percentage Resize ('%')
        Pixel Count Limit ('@')
        During Image Reading 

    Other Specialised Resize Operators

        Geometry - Resize just the last image
        Thumbnail - Resize with profile stripping
        Resample - Changing an images resolution
        Scale - Minify with pixel averaging
        Sample - Resize by row/column replication/deleting
        Magnify - double images size by "pixel scaling"
        Adaptive Resize - Small resizes without blurring
        Interpolative Resize - resize using interpolation method
        Liquid Rescale - Resize using Seam Carving
        Distort Resizing - free-form resizing
        Distort vs Resize - orthogonal vs cylindrical 

      
    Resizing Techniques

        Resizing with Colorspace Correction * * *
        Resizing with Gamma Correction
        Resizing in LAB colorspace
        Resizing in LUV colorspace
        Summary of Resizing using different colorspaces
        Resizing using a Sigmoidal Colorspace
        Sharpen Resized Images -- Photoshop Resize
        Resizing to Fill a Given Space -- OLD
        Resizing Line Drawings 

      
    Resize/Resampling Filters (separate section) 
    Resampling by Nicolas Robidoux (separate section) 

We look at enlarging and reducing images in various ways. The image remains intact and whole, but individual points of color merged or expanded to use up a smaller/larger canvas area.

Note that while this is related to the resolution of an image (number of pixels per real world length), that is more a product of how the image is eventually used, and not a true concern of Direct Image Processing.

Resizing Images
The most obvious and common way to change the size of an image is to resize or scale an image. The content of the image is then enlarged or more commonly shrunk to fit the desired size. But while the actual image pixels and colors are modified, the content represented by the image is essentially left unchanged.

However resizing images can be a tricky matter. It can modify images in very detremental ways, and there is no 'best way' as what is best is subjective as to what you actually want out of the resize process.

Because there is no 'best' or 'perfect' way, there are a lot of options that you may like to consider. IM has always tried to provide options to give you the maximum scope of control in image resizing. There are hundreds of posiblilties, styles, and techniques, and even resize experts are consantally trying to find new and different ways of changing an images size.

Of course for most people, the normal default options is good enough as they were designed with general use in mind.

The resize operator has been very carefully designed to try to produce a very good result for real world images. That is not to say you can't use it for diagrams, or line drawings, though for that type of image you may need to use some of the more advanced options we'll look at later.


The foremost thing you should consider when specifying an image to resize is...
Do you really want to modify the image?

Resizing will cause drastic changes to an image, and avoiding or minimizing unwanted 'artifacts' is of greatest importance. Perhaps just a slight Shave of the edges, or a more general Crop of the image will produce a better and more desirable outcome than a wholesale resize of the image. It generally will look better and the area left will be a perfect copy of the original.

Because it is often better not to resize images...
Resize will do nothing at all if the resized image is the same size.

The exception to this (there is always an exception) is if you actually specify a Resampling Filter using a "-filter" setting. In that case the normal "do nothing if image isn't resized" is overridden and the filter will be applied. However, many filters (even the default filters) can blur images slightly. It is part of their nature. So normally this 'short-circuit' for a no-op resize a good thing.

The argument to the resize operator is the area into which the image should be fitted. This area is not the final size of the image but the maximum size of the area into which the image is to be fitted. That is because IM tries to preserve the aspect ratio of the image more than the final (unless a '!' flag is given), but at least one (if not both) of the final dimensions should match the argument given image.

So let me be clear...
Resize will fit the image into the requested size.
It does NOT fill, the requested box size.

Aspect ratio is preserved basically so that any circles in the input image will remain a circle in the output image. That is the image will not be squashed or squeezed, only resized, unless you tell it otherwise.

For example here I attempt to fit two source images, one larger image and one smaller image into a square box 64x64 pixels in size.


  convert dragon_sm.gif    -resize 64x64  resize_dragon.gif
  convert terminal_sm.gif  -resize 64x64  resize_terminal.gif

[IM Output] ==> [IM Output] [IM Output] ==> [IM Output]

As you can see a 64x64 square image was NOT produced by "-resize". In fact the images were only enlarged or reduced just enough so as to best fit into the given size.

Ignore Aspect Ratio ('!' flag)
If you want you can force "-resize" to ignore the aspect ratio and distort the image so it always generates an image exactly the size specified. This is done by adding the character '!' to the size. Unfortunately this character is also sometimes used for special purposes by various UNIX command line shells. So you may have to escape the character somehow to preserve it.


  convert dragon_sm.gif    -resize 64x64\!  exact_dragon.gif
  convert terminal.gif  -resize 64x64\!  exact_terminal.gif

[IM Output] ==> [IM Output] [IM Output] ==> [IM Output]

Only Shrink Larger Images ('>' flag)
Another commonly used option is to restrict IM so that it will only shrink images to fit into the size given.   Never enlarge.   This is the '>' resize option. Think of it only applying the resize to images 'greater than' the size given (its a little counter intuitive).


  convert dragon_sm.gif    -resize 64x64\>  shrink_dragon.gif
  convert terminal.gif  -resize 64x64\>  shrink_terminal.gif

[IM Output] ==> [IM Output] [IM Output] ==> [IM Output]

This option is often very important for saving disk space for images, or in thumbnail generation, when enlarging images generally may not desirable as it tends to produce 'fuzzy' enlargements.

	The Only Shrink Flag ('>' flag) is a special character in both UNIX Shell and in Window batch scripts, and you will need to escape that character (using backslash '\>' in shell, and '^>' in windows batch). It is also special in and HTML web pages, so PHP scripts also may need some special handling.

Only Enlarge Smaller Images ('<' flag)
The inverse to the previous flag is '<', which will only enlarges images that are smaller than the given size, is rarely used.

The most notable use is with an argument such as '1x1<'. This resize argument will never actually resize any image. In other words it's a no-op, which will allow you to short circuit a resize operation in programs and scripts which always uses "-resize". Other than that you probably do not actually want to use this feature.

One such example of using this 'short circuit' argument is for the "-geometry" setting of "montage". See Montage and Geometry, caution needed for more details.

	The Only Enlarge Flag ('<' flag) is a special character in both UNIX Shell and in Window batch scripts, and you will need to escape that character (using backslash '\<' in shell, and '^<' in windows batch). It is also special in and HTML web pages, so PHP scripts also may need some special handling.

Fill Area Flag ('^' flag)
As of IM v6.3.8-3 IM now has a new geometry option flag '^' which is used to resize the image based on the smallest fitting dimension. That is, the image is resized to completely fill (and even overflow) the pixel area given.


  convert dragon_sm.gif    -resize 64x64^  fill_dragon.gif
  convert terminal.gif  -resize 64x64^  fill_terminal.gif

[IM Output] ==> [IM Output] [IM Output] ==> [IM Output]

As it stands this option does not seem very useful, but when combined with either a centered (or uncentered) "-crop" or "-extent" to remove the excess parts of the image, you can fit the image so as to completely fill the area specified. Both the resize and the final image size arguments should be the same values.

Though the "-crop" is most logical, it may require an extra "+repage" to remove virtual canvas layering information. The "-extent" does not require this cleanup, but still allows the use of "-gravity" for positioning. See Cutting and Bordering for more information.


  convert dragon_sm.gif      -resize 64x64^ \
          -gravity center -extent 64x64  fill_crop_dragon.gif
  convert terminal.gif    -resize 64x64^ \
          -gravity center -extent 64x64  fill_crop_terminal.gif

[IM Output] ==> [IM Output] [IM Output] ==> [IM Output]

Also "-extent" can be used to pad out images that use the normal resize (with a "-background" color setting). See Thumbnails, Fit to a Given Space Summary, for more on this type of operation.

	Remember this requires IM v6.3.8-3 or greater to make use of it. Otherwise use the older Resizing to Fill a Given Space technique below.

	The Fill Area Flag ('^' flag) is a special character in Window batch scripts and you will need to escape that character by doubling it. For example '^^', or it will not work. See Windows Batch Scripting for this and other windowing particularities.

Percentage Resize ('%' flag)
Adding a percent sign, '%', to the "-resize" argument causes resize to scale the image by the amount specified.


  convert dragon_sm.gif    -resize 50%  half_dragon.gif
  convert terminal.gif  -resize 50%  half_terminal.gif

[IM Output] ==> [IM Output] [IM Output] ==> [IM Output]

Be warned however that the final pixel size of the image will be rounded to the nearest integer. That is, you will not generate partial pixels along the edge of the image! As a result the actual scale may not exactly match the scaling factor you provide, and may even be slightly different for X and Y directions, but it will be very close. (See Resize using Distort below).

	If you really want to resize image such that the final size looks like it has a partial pixel size differences, you can use the General Distortion Operator and specifically the Scale-Rotation-Translate (see Distort Resizing below).

	The Percentage Resize Flag ('%' flag) is a special character in Window batch scripts and you will need to escape that character by doubling it. For example '%%', or it will not work. See Windows Batch Scripting for this and other windowing particularities.

	All these 'flag' options '!', '<', '>', '^', '%', and '@' are just on/off switches for the "-resize" operator. Just the character's presence (or absence) in the resize argument is what matters, not their position. They can appear at the start or end of the argument, or before or after individual numbers (though not in the middle of a number).

That is, '%50' has exactly the same effect as '50%' though the latter is preferred for readability. Also '50%x30' actually means '50%x30%' and NOT 50% width and 30 pixel high as you might think.

This is the case for all IM arguments using a 'geometry' style ('WxH' or '+X+Y') of argument. However offsets such as '+X+Y' are never treated as a percentage.

Resize using a Pixel Area Count Limit ('@' flag)
There is one final "-resize" option flag. The "at" symbol '@', will resize an image to contain no more than the given number of pixels. This can be used for example to make a collection of images of all different sizes roughly the same size. For example here we resize both our images to a rough 64x64 size, or 4096 pixels in size.


  convert dragon_sm.gif    -resize 4096@  pixel_dragon.gif
  convert terminal.gif  -resize 4096@  pixel_terminal.gif

[IM Output] ==> [IM Output] [IM Output] ==> [IM Output]

Note that the final image size is not limited to 64 pixels in height or width, but will have an area that is as close to (but smaller than) this size as IM can manage. That means one dimension will generally be slightly larger than 64 pixels and one will be slightly smaller.

In some ways this is an ideal compromise for thumbnailing images. See Area Fit Thumbnail Size.

You can also add the '>' flag to only shrink images that have more than the calculated number of pixels, while leaving images that are already smaller than that size.

	Unfortunatally the '<', enlarge smaller images, flag is currently ignored when using 'Area Resize'.

Resize During Image Read
The resize operator can also be applied to images immediately after being read, before it is added to the current image sequence and the next image is read. That way a minimal amount of memory is needed to read in a lot of images. See Image Read Modifiers for more details.

For example...


  convert dragon_sm.gif'[64x64]'    read_dragon.gif
  convert terminal.gif'[64x64]'  read_terminal.gif

[IM Output] ==> [IM Output] [IM Output] ==> [IM Output]

The only problem with this technique is that no special resize options can be used, during the image read process.

	Resize and transparency posed a problem for ImageMagick before v6.2.4, producing a black halo effect around light colored objects on transparency. This was researched and finally fixed from that version onward. For more detail of this old bug see Resize Halo Bug

Other Resize Operators
Geometry - Resize just the last image
Geometry is a very special option. The operator behaves slightly differently in every IM command, and often in special and magical ways. The reasons for this is mostly due to legacy use and should be avoided if at all possible.

First, in "display" it is used to size and position the window of the image being displayed. This was its original usage and meaning when IM was first started. It was from this that its other 'resize' capabilities came about.

For "montage" "-geometry" is a setting that is saved until all the arguments have been read in. At this point it then defines the final tile (cell) size (or leaves it up to "montage" to work out) while the position arguments are used to specify the space surrounding the tile cells. See Montage Control Settings.

In "composite", "-geometry" is also saved until the end of arguments have been reached. Then it is used to resize and position the overlay image (the first image given) before it is overlaid onto the background image (the second image). For example see Composite Multiple Images.

As you can see it is used as a 'setting' in most IM commands, but in "convert" "-geometry" is both a special image resizing operator and a positioning setting.

What it does is to "-resize" just the last image in the current image sequence. This is the only image processing operator that is designed specifically to effect just the one image (the last one), in the current image sequence.

To complicate this special option further, the positional parts of the "-geometry" option is saved by "convert" command, just as it is in "composite". That is, any position is preserved for later use by the "-composite", to position the 'overlay' image, (the second last image in the current image sequence) over the 'background' image (the first image in the image sequence).

For this reason, you should limit the use of "-geometry" in "convert" commands to just before a "-composite" or "-layers composite" operations.

To summarize, this operator is only really useful after reading or creating a second image, just before you perform some type of Alpha Composition to process with those images.

For practical examples of using "-geometry" to resize/position images see Compositing Multiple Images.

Thumbnail - Resize with profile stripping
The "-thumbnail" operator is a variation of "-resize" designed specifically for shrinking very very large images to small thumbnails.

First it uses "-strip" to remove all profile and other fluff from the image. It then uses "-sample" to shrink the image down to 5 times the final height. Finally it does a normal "-resize" to reduce the image to its final size.

All this is to basically speed up thumbnail generation from very large files.

However for thumbnails of JPEG images, you can limit the size of the image read in from disk using the special option "-define jpeg:size={size}" setting. See Reading JPEG Images for more details. As such this speed improvment is rarely needed for JPEG in thumbnail generation, though profile stripping is still very important.

For other image formats, such as TIFF, both profile stripping and speed improvement is still vitally important. As such it is still the recommended way to resize images for thumbnail creation.

	Before IM v6.5.4-7 the "-thumbnail" would strip ALL profiles from the image, including the ICC color profiles. From this version onward the color profiles will be preserved. If the color profile is not wanted then "-strip" all profiles.

Resample - Changing an image's resolution
Just as in the previous alternative resize operators, "-resample" is also a simple wrapper around the normal "-resize" operator.

Its purpose however is to adjust the number of pixels in an image so that when displayed at the given Resolution or Density the image will still look the same size in real world terms. That is, the given image is enlarged or shrunk, in terms of the number of pixels, while the image size in real world units will remain the same.

It is meant to be used for images that were read in from, or will be written out to, a program or device of a particular resolution or density. This is especially important for adjusting an image to fit a specific hardware output device, whether it is a display, or printer, or a postscript or PDF image format of a specific resolution. Just remember the real world size of the image does not change, only its resolution and of course the number of pixels used to represent the image.

For example, suppose you had an image that you scanned at a 300dpi (dots per inch). The image was saved with this resolution (density) or when you read it into IM, you specified it as a 300dpi image (using "-density"). Now you decide to display it on a screen that has a resolution of 90dpi, so you do a "-resample 90". IM will now resize the image by 90/300 or to 30% of the images original size and set the images new density to 90dpi. The image is now smaller in terms of the number of pixels used, but if displayed on a 90dpi display will appear at the same physical size as the original image you scanned. That is, it now has a resolution appropriate for a 90dpi display, so it will be displayed to the user at its original real world size.

A "-units" setting (with arguments 'PixelsPerInch' or 'PixelsPerCentimeter') may be required in some situations to get this operator to work correctly. This setting can also be important for output to Postscript and PDF image file formats.

Note that only a small number of image file formats (such as JPEG, PNG, and TIFF) are capable of storing the image resolution or density with the image data.

For formats which do not support an image resolution, or which are multi-resolution (vector based) image formats, the original resolution of the image must be specified via the "-density" attribute (see Density Image Meta-data) before being read in. If no density attribute has been set IM will assume it has a default density of 72dpi. Setting the density AFTER reading such an image will only affect its output resolution, and not affect its final size in terms of pixels.

Scale - Minify with pixel averaging
The "-scale" resize operator is a simplified, faster form of the resize command.

When enlarging an image, the pixels in the image are replicated to form a large rectangular blocks of color. Which is great for showing a clean unblurred magnification of an image.

For example here is a magnified view of one of the built-in tile patterns...


  convert -size 8x8 pattern:CrossHatch30 -scale 800% scale_crosshatch.gif

	[IM Output]

Generally a single percentage value that is a multiple of 100% is used for the image enlargement so as to ensure all pixels are enlarged by the same amount, otherwise you can have different size pixel rows and columns producing large scale Moiré pattern.

For example here I badly scaled a smooth looking '50% gray checks' pattern, using a size that was not a multiple of the original images size.


  convert pattern:gray50 scale_gray_norm.gif
  convert pattern:gray50 -scale 36 scale_gray_mag.gif

	[IM Output]
==>
[IM Output]

When shrinking images, neighbouring pixels are averaged together to produce a new colored pixel. For example scaling an image to 50% of its original size will effectively average together blocks of 4 pixels to create a new pixel (assuming the image size is a multiple of 2 as well).

Caution is advised however as a scale reduced image can also generate Moiré patterns, unless the new image is an exact integer reduction (a technique known as 'binning'), which also requires the original image size to be some exact integer multiple of the final size.

Also a real-world photograph that has been heavily minified using "-scale" tends to look overlay sharp, with aliasing ('staircase') effects along sharp edges.

The pixel averaging of "-scale" allows it to generate 'pixelated' images. You basically reduce the size of the image to average the pixels, then enlarge again back to the image's original size.


  convert rose:  -scale 25%  -scale 70x46\!  rose_pixelated.gif

[IM Output] ==> [IM Output]

You can use a mask to combine the above pixelated image with the original image, so as to 'hide' a much smaller 'naughty' bit present in the original image. See the Protect Someones Anonymity example for a demonstration of using this technique.

The algorithm is also designed to loop over rows of pixels then columns, which is inverted to that of "-resize". This may allow "-scale" to handle a "mpc:" disk cached image better.

	Up until IM v6.4.7 the "-scale" still contained the old Resize Halo Bug.

Scale Internals (pixel mixing)...
In many ways the Scale Operator is similar to the normal Resize Operator, but using a 'Box' Resampling Filter. However it actually uses a completely different algorithm that is slightly more accurate in its results than that produced by a Box Filter.

The way the Box Filter works is to simply average any pixel (sample) that falls within the filters 'support window' (See Filter Support Expert Control. This means that when shrinking an image by a very small amount, a Box filtered Resize will only produce either exact pixel values, or an perfectly averaged pixel value.

The Scale Operator however uses a different algorithm that is known (for want of a better name) Pixel Mixing. Rather than generate the colors based on a 'average of pixels', within the 'support window' it uses a more accurite 'area of pixels' within the support window.

For example here I take 'checker board' pixel pattern, and shrink it by 2 pixels, comparing result of Scale against resizing using very simple Box & Triangle Filters.


  convert -size 10x10 pattern:gray50  checks.gif
  convert checks.gif  -filter box      -resize 8x8  checks_box.gif
  convert checks.gif                   -scale  8x8  checks_scale.gif
  convert checks.gif  -filter triangle -resize 8x8  checks_triangle.gif

[IM Output]
10 pixel 'hash' 	==> 	[IM Output]
Box Filtered
Resize 	[IM Output]
Pixel Mixing
Scale 	[IM Output]
Triangle Filter
Resize
The images above have been greatly enlarged

The above shows the result you get for 'purely averaged', vs, 'pixel mixed', vs, 'linear interpolation'.

It also shows how Scale Operator is actually similar to that of a Triangle Filter, but only when doing very small downsizing of images. In other cases (strong downsize, upsizing, or exact interger sizing) it will produce results more like that of a Box Filter. Basically it generates something that is more like a mix between Box and Triangle filters depending on exactly how much the image is reduced in size.

You see similar effects when enlarging.


  convert -size 8x8 pattern:gray50  checks_sm.gif
  convert checks_sm.gif -filter box      -resize 10x10 checks_sm_box.gif
  convert checks_sm.gif                  -scale  10x10 checks_sm_scale.gif
  convert checks_sm.gif -filter triangle -resize 10x10 checks_sm_triangle.gif

[IM Output]
10 pixel 'hash' 	==> 	[IM Output]
Box Filtered
Resize 	[IM Output]
Pixel Mixing
Scale 	[IM Output]
Triangle Filter
Resize
The images above have been greatly enlarged

When enlarging a Box Filter will never produce 'averaged pixels', only pixel row/column duplications.

Scale however will generate averaged color pixels along the edges, again much like but not exactly the same as a Triangle Filter. Of course this effect is only really visible for small, non-integer enlargements, and in larger scalings, only along edges where in a more typical case you may get one or two averaged pixels.

In summary: Scale is much much faster than the normal Resize Operator, as it is less general in its image processing requirments. But it is also a completely different algorithm, producing a slightly different result when used to resize images using non-integer scales.

For more detail see the Pixel Mixing page, as well as the IM Forums Discussion, Upscaling a few pixels linearly. Special thanks goes to forum user atnbueno, who pointed out the above difference.

Sample - Resize by row/column replication/deleting
The "-sample" resize operator is the fastest resize operator, especially in large scale image reduction. In fact it is also even faster than the "-scale" operator (see above).

When enlarging or magnifying an image it only performs does pixel replication (as per the Box Filter, generating rectangular 'blocks' of pixel colors. However when shrinking an image "-sample" simply deletes rows and columns of pixels.

Because whole rows and columns of pixels are simply added or removed, "-sample" will generate no new or additional colors. This fact can be important for some image processing techniques such as resizing GIF animations.

Another way of looking at it is that the image has single individual pixels 'sampled' in a very even regular pattern across the whole image. You can think of the image as being divided into an array of regions, and one pixel from each region is selected for the resulting image.

However this 'sampling' of individual pixels (or wholesale row/column removal), can have rather horrible results, especially for images containing thin lines (in terms of width in pixels).

For example, here I draw a line but then reduce the image size resulting in only a line of dots.


  convert -size 150x60 xc: -draw 'line 0,59 149,0' line_orig.gif
  convert line_orig.gif  -sample 50x20  line_sample.gif

[IM Output] ==> [IM Output]

This is a typical effect your get with image sampling, and is known as a sever Aliasing effect.

Offset of the Sampled Pixel
As of IM v6.8.4-7, the exact pixel being sampled in each sampling sub-region, is now defined as being the pixel at the mid-point of each region (or top-left center pixel if the sub-region is an even number of pixels). That means if you make a single pixel sample of an image, you will get the middle pixel of the image.

	Before IM v6.8.4-7 the pixel selected was the top-left pixel of each region. However there are reports of some version where this may have been the bottom-right, or it may have even been slightly variable due to bugs.

This type of information is especially useful for images that being reduced by an integer division of the original image size. Such as when you are creating or sampling a pixelated image, or De-interlacing a Video Frames.

Also as of that version you can control exactly which pixel in each sub-region is selected using the define "sample:offset, which takes one or two percentage value(s) ('50' by default for mid-point).

Note a percentage is used as the in the general case the 'sampling sub-regions' may not align with pixel bounds. That is why it is a percentage is needed and not a 'pixel offset'. However if the image size is nicely divisible by the number of samples then you can easily calculate exactly which pixel you want from each sub-region.

For example if an image sampled so that you have 5 pixel sub regions, then (For example, sampling an image that has 100 pixel across, down to 20 pixel samples), then you can use an sampling offset percentage in the range 0 to 19.9 to select the first pixel in each region, 20.1 to 39.9 for second, and so on. In other words you can use a percentage value of either 10,30,50,70 and 90 to exactly specify exactly which pixel you want from each constant sized sampling region.

For more on sampling offsets see the IM Forum discussion Sample Points.

Magnify - Pixel Scaling
The "-magnify" option doubles the size of an image, but it does so by using a technique known as "Pixel Scaling" using the Scale2X algorithm. This algorithm tries to smooth the corners of pixels being enlarged, without adding extra colors. As such very small pixelated images enlarge more cleanly, while retaining the original colors and a "retro pixel look" of the smaller image.


  convert -size 8x8 pattern:CrossHatch30 -virtual-pixel tile \
          -magnify -magnify -magnify magnify_crosshatch.gif

[IM Output] ==> [IM Output]

Note the Virtual Pixel setting was used to ensure that magnify understood that this specific image 'wraps around' the image edges.

	Before IM v6.8.4-10 magnify was just a wrapper around resize to double the size of the image. Not very useful and rarely used. Using "Pixel Scaling" makes this option a lot more useful. See IM Users forum on Pixel Scaling for more information.

	A "Minify()" function is also often available in API's that halve the size of images but is just a wrapper around resize. However "-minify" is not available from the command line API, at least not at the time of writing.

Adaptive Resize - Small resizes without blurring
The "-adaptive-resize" operator uses the special Mesh Interpolation method to resize images.

For example here I resize a simple line, using first a normal "-resize", then again using "-adaptive-resize".


  convert -size 50x50 xc: -draw 'line 0,49 49,0'  line_orig2.gif
  convert line_orig2.gif           -resize 80x80  line_resize.gif
  convert line_orig2.gif  -adaptive-resize 80x80  line_adaptive.gif

[IM Output] ==> [IM Output] [IM Output]
If you look at a magnification of the two results...
[IM Output] [IM Output]
You can see the Adaptive Resized image on the right is a lot cleaner looking and less blurry than the image produced on the left using the normal "-resize" operator.

Basically the operator avoids the excessive blurring that a "-resize" operator can produce with sharp color changes. This works well for slight image size adjustments, particularly for magnification, and especially with images with sharp color changes.

However as with all pixel interpolative methods, it will produce aliasing, and Moiré effects when images are enlarged or reduced by more than 50%.

You can also generate the exact equivalent result using a Distort Resize operation but with the options "-filter point -interpolate mesh".  That is, resizing the image using a simple Mesh Interpolation lookup method, rather than a more complex resampling filter.

Interpolative Resize - Resize using an Interpolation Method
The "-interpolative-resize" operator is practically identical to the previous Adaptive Resize operator. However this operator will use the current "-interpolate" setting rather than a fixed 'Mesh' interpolation method.

If you use a "-interpolate" setting of 'Nearest', you will essentually get the equivelent of a Sample Operator. Similarly many of the other Simple Interpolation Methods, will equate to using the equivelent Interpolated Resize Filters. But there are a number of Interpolation methods such as Mesh that have no equivelence as a resize filter.
This is also an unscaled resize, which means it works great for enlargements, and small scale shrinking, but when shrinking by more that 50% sever Aliasing Effects can appear, as shown in the other 'sampling resize operators' above.

Liquid Rescale - Seam Carving
Just as Sampling an image resizes by directly removing or duplicating whole columns and rows from an image, the special IM operator "-liquid-rescale" also removes or duplicates columns and rows of pixels from an image to reduce/enlarge an image. The difference is that it tries to do so in a more intelligent manner.

Firstly, instead of removing a simple line of pixels, it removes a 'seam' of pixels. That is, the column (or row) that could zig-zag through the image, at angles up to 45 degrees.

Secondly it tries to remove seams that have the 'least importance' in terms of the image's contents. How it selects this is in terms of the image's energy, or more simply, the amount of color changes a particular 'seam' involves. The 'seam' with the least amount of changes will be removed first, followed by higher 'energy' seams, until the image is the size desired.

For more detailed information of liquid resizing and seam carving see, Wikipedia: Seam Carving, the YouTube Video Demo, and the PDF paper: Seam Carving for Content-Aware Image Resizing.

Here for example is the IM logo as it is resized smaller using the IM "-liquid-rescale" operator.


  convert logo: -resize 50% -trim +repage  logo_trimmed.jpg
  convert logo_trimmed.jpg  -liquid-rescale 75x100%\!  logo_lqr.jpg
  convert logo_trimmed.jpg  -sample 75x100%\!  logo_sample.jpg

[IM Output]
Original 	==> 	[IM Output]
Liquid Resize 	[IM Output]
Sampled

Notice how "-liquid-rescale" preserved the complex wizard, while squeezing up the less complex stars and title part of the image. It also squeeze the right foot of the wizard slightly, producing a little jaggedness in the edge of the cloak, just as it did to the wizard's thin but simple wand.

On the other hand the Sample Resize image, simply removed equally spaced columns of pixels, which resulted in the whole image becoming equally distorted. The stars are not preserved intact and all the edges have distinct but uniform aliasing effects.

Basically "-liquid-rescale" will produce a generally better looking 'squeezed' image without generating extra 'mixed colors' or blurring of the image. However you can get some slight but localized aliasing effects in one spot (the wizards wand in this case) rather than spreading that effect across the whole image.

It will also expand images, by 'doubling' up the seams found within the image.


  convert logo_trimmed.jpg  -liquid-rescale 130x100%\!  logo_lqr_expand.jpg

[IM Output] ==> [IM Output]

As you can see tries to first double the amount of space between the various objects (where it can), spreading them out. Though in this case the left most star and the 'm' becomes distorted as the 'seams' going through these 'low energy' regions become grouped together.

Note however it will only double each seam once, and as such the technique starts to break down when images are expanded too much. A better method is often to resize the image larger first, then use liquid rescaling to reduce it to the desired size. Or to use "-liquid-rescale" in multiple smaller steps.

To show the effect of "-liquid-rescale" better here is an animation, as the same image is resized down to a very thin image, then enlarged again. This animation was created using the shell script animate_lqr.
[IM Output]

Again notice how it tries to preserve the most complex parts of the image, as the image gets compressed into a smaller and smaller area. That is, the spaces in the title are preferentially compressed first, then the wizard's arm, then the right side of the wizard, leaving the most complex middle part of the wizard for the very end.

Especially look at how the stars get pushed together before they are finally effected by the resampling pixel removal that liquid rescaling implements. (See problems next)

You can think of liquid rescaling as trying to compress an image, like a sponge, with the open areas being compressed first leaving the bulky and more structured parts for last.

Seam Carving Problems

Liquid Resize, or Seam Carving, works purely by removing whole pixels from the image. As such, like sampling, it will not generate or merge colors together, and straight lines and patterns within the image may become heavily distorted by the operation. Basically it can result in serious Aliasing Effects, unless some method of smoothing is also applied.

Generally however the aliasing effects will be grouped and localised to the less complex areas of the image rather then spread thought the image. this is the only reason it works so well!

As a 'seam' can zig-zag through the image, the seams, can and often appear to go around complex objects, removing the space between the objects before attempting to compressing the objects themselves. Note for example how the word 'Image' in the above demonstration appears to get shoved under the other letters in the title without too much distortion. However this side to side movement limited to 45 degree angles.

For images with 'busy' backgrounds, and less 'busy' foreground objects such as photos containing peoples faces, the energy function can assume that the foreground object is less important that the background. This results in some serious detrimental side effects, that may require human intervention to resolve.

	Liquid Rescaling, is currently a highly experimental operation added for IM v6.3.8-4. It requires the "liblqr" delegate library to be installed before it will work for you.

At this time no expert user controls have been provided. Controls such as to modify the content energy function used, or use an user provided preservation/removal filter (adjusting that energy function), or access to the intermediate seam carved images, and functions that the library also provides. It is assumed that such controls will be provided in sometime in the future, as users demand them, and we get more internal control of the library functions.

WARNING Do not expect this to remain, exactly as it is currently implemented. It is highly experimental, and is expected to change and expand in functionality.

Distort Resize - free-form resizing
All the above resize methods all have one limitation which we touched on earlier, they will round the size of the new image to an integer number of pixels, then map the old image's pixels to the new pixel array.

This has two effects. First when resizing to a very small size the X scale may not exactly match the Y scale of the resulting image (a slightly different aspect ratio). This difference is minor, and unless you get very small it is usually not noticeable.

The other effect is that you cannot resize an image to fit an area that contains a partial pixel edge, which can be important in further processing, such image overlays.

It also means you cannot use resize to just shift (translate) an image half a pixel to the right (without actual resize) even though the algorithm could quite easily do this.

With IM v6.3.6 the General Distortion Operator "-distort" will let you do this and more, using its Scale-Rotate-Translate distortion method. You can also do this using an Affine distortion based on movements of control points.

Note however that because the edge of the image can contain partial pixels, the final image will probably be 2 to 3 pixels larger than you probably would expect. The extra surrounding pixels will be mixed according to the current Virtual Pixel setting, which you typically set to be transparent.

For example here I resize the rose image to 90% (.9) of its original size, without rotation (0), shrinking it around the center of the image (the default control point if not specified)...


  convert rose: -matte -virtual-pixel transparent \
          +distort SRT '.9,0' +repage  rose_distort_scale.png

	[IM Output]

It may not look like an improvement, in fact it has fuzzy edges, but it is an exact resize without adjustments for a final integer image size, just as you requested. Because of this the edges are fuzzy as the pixel colors are being spread over fractions of a pixel size, and not just to whole integers.

Note that I used the 'plus' form of "+distort" to allow this image's processing operator to set the final images size and offset on the Virtual Canvas correctly, for further processing and layering. If this offset is not desired it can be removed using "+repage" operator. But if left in place then the actual images location on the larger canvas will be preserved, allowing you to exactly position the image correctly with its 'fuzzy edges'.

Here I resized it so the top left corner (0,0) was moved .5 pixels to the right (to .5,0) and the rest of the image scaled around that control point...


  convert rose: -matte -virtual-pixel transparent \
          +distort SRT '0,0  .9  0  .5,0' +repage  rose_distort_shift.png

	[IM Output]

Note that as the top edge did not actually move, it remained relatively sharp, while all the other edges became fuzzy. Here is a pixel magnification of the top corner, showing the transparency that was added by distort to provide sub-pixel resizing...


  convert rose_distort_shift.png -crop 15x15+0+0 +repage \
          -scale 600%   rose_distort_shift_mag.png

	[IM Output]

You can see that the top edge remained sharp, while the left (and all other edges) are now semi-transparent.

And that is the point. You have exact control of the resize, and the final sub-pixel location of the resulting image. Not just a quantized fit of the resized image to an integer number of pixels. That is, the distort is an exact re-scaling and positioning of the image to fractions of a pixel, allow you to fit it precisely into other images.

This can become especially important when doing video work, where an imprecise resize of embeded images can produce 'jarring' effects.

	Technically, image resizing is a simplified form of Image Distortion, both of which are techniques of image resampling. It's very fast 2-pass filtering technique, is limited to orthogonally aligned pixel scaling, and an integer number of pixels in the final result.

Affine, Transform

As of IM v6.4.2-8 the older "-affine" setting used with either "-transform" or "-draw" operators, provide a similar free-form resize capability. However in reality it is equivalent to a calling "+distort" with an 'AffineProjection' distortion method. As such all the previous Distort notes apply.

It does require more mathematics making it hard for the typical user to use. Generally you are better off using the above distortion method, which provides a number of alternative methods of specifying the affine distortion to be applied.

Distort vs Resize
If you actually want to do a direct comparison between using Distort vs Resize you will need to specifically limit the distortion of the image, so as to exactly match the resized image you care comparing it to. This is not a simple task.

To make this easier a special Resize Distortion Method was added to IM v6.6.9-2.

Here for example I greatly enlarge the built-in "rose:" using a fast Resize, and then using Distort...


  convert rose: -filter Lanczos -resize 300x rose_resize.png

  convert rose: -filter Lanczos -distort Resize 300x rose_distort.png

[IM Text]
Resize (Lanczos - Sinc) 	[IM Text]
Distort (Lanczos - Jinc)

If you look along the bottom edge of the rose, you will see that the Distort Operator actually produced a better cleaner result than the Resize Operator. With very little Blocking Artefacts that is common when enlarging images.

Other than this bottom edge, the rest of the image is practically identical, even when compared using a "flicker_cmp" script.

However remember that Distort is much slower than Resize, as it uses a more direct but much more complex Area Resampling technique, without the 2-pass speed optimizations that resize uses.

	The real difference in the above two images is that the Distort Operator uses a two dimensional Elliptical Area Resampling filter method (also known as cylindrical filtering or resampling) for its image processing. This is slower than the one dimensional, two pass resampling method used by all the other resize methods shown in this section. It is also why it produced a better result along the diagonal bottom edge of the enlarged rose image above. It is not limited to just horizontal and vertical filtering.

You can see the effects this has on ringing in the examples on Ringing Artefacts.


Resizing Techniques
Resizing with Colorspace Correction
While resize works very well, most people do not use it correctly. Even I normally just use resize directly on images, as is, and thus technically I resize images incorrectly.

Images are typically stored using a non-linear "sRGB" colorspace, or with gamma correction. See Human Color Perception for details. But resize (like most other image processing operators) is a mathematically linear processor, that assumes that image values directly represent a linear color brightness.

The colorspace "sRGB" is basically contains a gamma correction of roughly 2.2. Actually it is more complex than that involving two separate curves. See wikipedia, sRGB and W3org, sRGB the Default Colorspace of the Internet.

As of version 6.7.5 ImageMagick follows this convention and defines the default colorspace of images (at least for most image file formats) to be sRGB. This means we simply need to use the "-colorspace" to transform the image to a linear space before doing the resize.

	Using color correction on a low-quality Q8 version of IM (see Quality) is not recommended due to the loss of precision such a low memory quality provides.

The NASA image "Earth's City Lights" is a very extreme case where non-linear colorspace effects have a big impact on the results of resizing the image.

Here we directly resize the image without colorspace correction...


  convert earth_lights_4800.tif -resize 500 earth_lights_direct.png

[IM Text]

And here we convert from a non-linear sRGB, to linear RGB, then resize them, and convert it back again...


  convert earth_lights_4800.tif -colorspace RGB     -resize 500    \
          -colorspace sRGB  earth_lights_colorspace.png

[IM Text]

As you can see the 'lights' in the images are much much brighter as they are not so heavilly influenced by the non-linear colorspace of the source image. Though most images do not have as great an impact as can be seen in the above, it is present, and can have many effects.

The main effect that can be seen from the non-linear effects of sRBG is that darker colors are saved as much darker values (so as to be more perceptually relevent. But as they are darker, they do not get processed correctly mathematically, so the resulting sRGB image is darker than an image processed in linear colorspace like RGB (or LAB or LUV).

Also see Color Processing Real Images and Drawing with Gamma and Colorspace Correction.

The same correct colorspace handling also applies to the use of distort (elliptical filter), image blurring, and can have great effects on image quantization, dithering and ordered dithering. This is looked at in detail in resampling filters.

WARNING: RGB colorspace may produce clipping problems along edges involving strong primary color changes (not just between black and white). See the next section.

		
In versions of IM older than v6.7.5, in which the default input colorspace was 'RGB'. The 'sRGB' colorspace actually meant "converted from sRGB to linear-RGB". The result was the two labels were swapped! Wierd but true.

Because of this older versions of ImageMagick would need to do the above colorspace correction with those colorspace names swapped. Like this...


  convert earth_lights_4800.tif -colorspace sRGB \
          -resize 500  -colorspace RGB  earth_lights_colorspace.png

*** This example is depreciated ***

Note that the "-colorspace RGB" operation was not actually needed, as it was automatically performed when saving to PNG image file format.

The above was developed from an IM Forum Discussion Correct Resize.

Resize with Gamma Correction
This is how to correctly resize images using gamma correction only.


  convert earth_lights_4800.tif   -gamma 0.454545 \
          -resize 500    -gamma 2.2  earth_lights_gamma.png

[IM Text]

An alternative to the gamma inverse operation "-gamma 0.454545" is to use "-evaluate POW 2.2".

Note that gamma correction is only a rough match to properly converting images from/to sRGB colorspace, but it is so close that you would be hard pressed to see any difference between colorspace vs gamma correction.

Gamma correction also does not play around with the IMv6 RGB/sRGB colorspace settings, so may be a better choice when the exact version may be unknown.

You may also like to look at the "-auto-gamma" operator, which tries to adjust the image, do as to produce equal amounts of light and dark areas (assuming the image is in a linear colorspace).


Resizing in LAB colorspace
One problem with using sRGB, RGB or even XYZ colorspace for resizing or for any sort of image processing is that the 3 color channels not only represent color but also intensity or brightness. That means that if one channel becomes distorted (such as by being clipped) the pixel color will also become distorted and can result in a funny look.

The LAB colorspace is not only a linear colorspace, but was designed so that intensity (L channel) is separated from two color channels (A* and B* channels). That means that if any one of the channels becomes clipped, it does not generate color skew.

It also means that generally none of the channels are actually close to clip limits unless you specifically deal with pure black and white images, which is uncommon in real life images.

As such by processing images using LAB colorspace, actually works better, and avoids clipping and color skew, that you may get when using a RGB or XYZ colorspace.

	Before IM v6.7.8-2 LAB values for A* and B* channels was stored using signed integers, stored in an unsigned integer memory space. This created a discontinuity between negative and positive values, that did not allow normal processing to work, only image format converstions.

This meant that in older versions of IM, image processing in LAB colorspace did not work, especially when a color involving both positive to negative values were involved. That when working with colors that change between blue-yellow and red-green.

After this release the values were stored internally using a 50% bias, which removed that discontinuity, and thus allowing linear operations to work as expected.

For resize involving 'sharpening' resampling filters (very commonly used), using Lab colorspace will also moderate extreme intensity changes, that can generate overly strong (and range clipped) Ringing Artefacts, in the primary RGB colors.

For example...


  convert rose: -colorspace RGB  -filter Lanczos  -distort resize 300x \
          -colorspace sRGB rose_distort_rgb.png
  convert rose: -colorspace LAB  -filter Lanczos  -distort resize 300x \
          -colorspace sRGB rose_distort_lab.png

[IM Output]
Original 	==> 	[IM Output]
RGB colorspace 	[IM Output]
LAB colorspace

As you can see while the edge of the rose was clipped in linear RGB colorspace, it was not clipped in LAB colorspace.

In RGB colorspace the bottom edge of the rose sees a color change from near pure white to near pure red, causing a strong (negative) change in the 'green' and 'blue' channels. This produces a very strong 'negative lobe' ringing effect which is then clipped in RGB colorspace. The final result is a severe color distortion, due to the filters sharpening effect.

In LAB colorpsace, the shift from white to red is not nearly as strong in either intensity or in the color channels, and so while we get good sharpening in the intensity, neither it nor the color channels is clipped, thus avoiding color distortion.

The result is a far better resized image, with a more appropriate sharpening effect from the filter. Simply by separating intensity from color.

Resize using LUV colorspace
As of IM v6.7.8-8 IM also implements a closely related colorspace LUV. They both designed to be perceptually uniform (linear), and even share the same critical intensity 'L' or 'Lighness' channel results, though calculate the color channels differently.

The main difference is that LUV color axis were adjusted so as to have perceptually equal color deltas (color differneces), which results in a slightly different color scale to LAB colorspace, though intensity remains the same between the two. See Adams chromatic valence color space.

The results for resizes between LAB and LUV is practically identical.


  convert rose: -colorspace LUV  -filter Lanczos  -distort resize 300x \
          -colorspace sRGB  rose_distort_luv.png

[IM Output]

See Colorspace for more information about these two colorspaces..

Summary of Resizing using different colorspaces
Or why not use LAB or LUV for resize?

Well because like sRGB, LAB and LUV colorspace is a non-linear perceptual colorspace! And the mathematics was only ment to be applied to linear values.

For example here is the results of resizing the "Earth's City Lights" image in 'Lab' colorspace.


  convert earth_lights_4800.tif -colorspace Lab     -resize 500    \
          -colorspace sRGB  earth_lights_lab.png

[IM Text]

The result is practically identical to what you get if you had resized directly in the perceptual sRGB colorspace.

But is resizing in a perceptual colorspace really a bad thing? Really that is a debatable point. It seems avoiding color channel clipping, while color slew (unequal changes to differnet color channels) is less important

But then a LAB and LUV images are linear, perceptually! As such perhaps blending colors (which is what the Resampling Filters actually do) in a linear-perceptual colorspace may actually be a good thing to do.

Just one final point, sRGB is only perceptually-linear in intensity along the primary color components. It is not actually perceptually-linear in color, so it remains a bad colorspace to doing any form of image resizing.

Nicolas Robidoux summed it up nicely with...
Generally, the linear light colour spaces (linear RGB and XYZ) produce exaggerated dark halos, and the "perceptual" colour spaces (sRGB, LAB, LUV) produce exaggerated light halos.

If you think about it for a minute, this makes complete sense, because the perceptual colour spaces pack lots of bits at the darker end of the intensity spectrum, and "hollow out" the lighter end, so as to mimick the HVS (Human Visual System). So, 1 unit of dark overshoot gets you less "far" in sRGB than in linear RGB, but 1 unit of light overshoot gets you less "far" in linear RGB than sRGB.

Sigmoidization (see next) treats dark and light overshoots equally, and generally dampens the extremes of both.


Resizing using a Sigmoidal Colorspace
In a lengthy discussion on the ImageMagick Discussion Forums, Sigmoidal minimization of resampling filter haloing. A new technique has been developed in which rather than trying to resize images in a linear color space, the image is resized in a modified colorspace using the Sigmoidal Color Modifier Operator (-sigmoidal-contrast). This can reduce the clipping of extreme halo or Ringing Artefacts that may develop along very sharp edges.

For example, here is a sequence of 'improving' resize techniques, that have been discussed on the Digital Image Processing Forums...


  convert rose: -colorspace RGB  -filter Lanczos  -resize 200x \
          -colorspace sRGB rose_resize_RGB.png
  convert rose: -colorspace RGB  -filter Lanczos  -distort resize 200x \
          -colorspace sRGB rose_distort_RGB.png
  convert rose: -colorspace RGB   +sigmoidal-contrast 6.5,50% \
          -filter Lanczos  -distort resize 200x \
          -sigmoidal-contrast 6.5,50% -colorspace sRGB  rose_sigmoidal_RGB.png

[IM Output]
Resize (normal linear) 	[IM Output]
Distort (cylindrical) 	[IM Output]
Sigmoidal Variation

Essentially what the final example in the above does is to decrease the contrast of the image, compressing mid-tone greys into a tighter linear range, while bringing the extreme values further from the clipping edges, before resizing. It then removes that modification afterward. This in turn de-emphases the extreme effects of color values, while still allowing the filter to process the mid-tones, in a linear fashion, so as to reduce color distortions.

In many ways this is similar to resizing images in the default non-linear sRGB colorspace (which is a far too common practice), but works equally well for both bright and dark ringing artifacts. That is it is symmetrical over the whole range of color values, where as resizing in sRGB colorspace works only from the lower dark end of the color range (blue and green values in the above). That is it is a much more controlled technique.

It has also been commented that that this sigmoidal variation may only work well for enlargements. Also try different values for the sigmoidal contrast intensity (6.5 in the above) for different images.

Remember, just as with every resize technqiue, the results are highly subjective, and may not be good for all image types.

	Sigmoidal transform essentually generates a special DIY non-linear colorspace, that builds on the previous results that was obtained when using a non-linear perceptual colorspace (sRGB).

Note that resizing (distorting) an image with non-linear color channels in RGB colorspace, can lead to slightly different results in each color channel. This results in a slight color shift (as opposed to a color being clipped as we saw earilier).

This is only a problem with non-linear colorspaces with mixed color-intensity channels, such as sRGB, or a sigmoidal colorspace.


Unsharped Resizing (USM) -- Photoshop Resize Technique
Often resizing images (either smaller or larger) adds some fuzziness (Blurring Artefacts to the image. Because of this many people like to play around with the various filters (see Resampling Filters), to try and make the results sharper. But this can add other Resize Artefacts to the image results.

One method that is commonly used is to sharpen the image after resizing. Typically this is done using the special and weirdly named, Unsharp Operation, which contains even more controls to control the quality of the results.

For example, lets 'unsharp' the results of the very blurry 'Spline' filtered image...


  convert logo: -filter spline -resize 150x logo_spline.png
  convert logo: -filter spline -resize 150x \
          -unsharp 0x1  logo_spline_unsharp.png

[IM Output]
Spline 	==> 	[IM Output]
Unsharped

As you can see sharpening the image after the resize improves the results. Looking at the stars and hat details in particular. You get a very good sharp image without any aliasing, ringing or even dimming of effects.

While a Spline Filter is not particularly good filter to begin with, this method of sharpening (actually 'unsharping') will work for ANY filter. It also provides more controls to fine-tune the result.

In actual fact this is what 'photoshop' does to improve the quality of its resized images, though I do not know what settings it uses for the Unsharp Operation. A technique known as USM

The "GIMP" default (radius=6, amount=0.5, threshold=0) for unsharp is equivalent to "-unsharp 12x6+0.5+0", and this is correct (other than ignoring that GIMP sets a hard radius at twice sigma). However remember you really do not need to specify the kernel radius in ImageMagick, so a value of "-unsharp 0x6+0.5+0" will work better.

See also the IM forum topic unsharp parameters in GIMP.

The post Image Resizing suggests using "-unsharp 0x0.75+0.75+0.008" as being good for images larger than 500 pixels.

While an Open Photography Forum discussion Downsampling with ImageMagick suggests "-unsharp 1.5x1+0.7+0.02".


Resizing to Fill a Given Space
Basically: Resizing a large image to completely fill a specific image size but cropping any parts of the image that do not fit.

	As of IM v6.3.8-3 a new resize flag '^' will let you do this directly as a single resize step. These examples represents an alternative method that can be used for users with older versions of IM. See Resize Fill Flag above.

The solution is rather tricky, as the normal user requirement when resizing images is to fit the whole of an image into a given size. As the aspect ratio of the image is preserved, that leaves extra, unused space in the area you are trying to fill.

Here we try to resize an image to fill a 80x80 box.


  convert logo: -resize 80x80\> \
          -size 80x80 xc:blue +swap -gravity center  -composite \
          space_resize.jpg

	[IM Output]

In the above we added a backdrop canvas to pad out the unused parts of the resize box to show the space we wanted the image to fill, but it wasn't filled, as it preserved the image's aspect ratio.

Now if all your images are either landscape style (they are wider than they are high) then you can of course just resize the image to fit either the height or width of the area, then use "-crop" to cut the image to fit it exactly.


  convert logo:    -resize x80  \
          -gravity center  -crop 80x80+0+0 +repage   space_crop.jpg

	[IM Output]

The problem is that, the above will only handle landscape style images. It will fail badly if the image is portrait style (higher than it is wide).

This of course can be solved in a script by first getting the image's dimensions, and then picking the right method to fit the image into the space needed. But a better solution would be to have IM do all the work for all images. The solution within IM is to process the image by resizing each of the images dimension separately. Then picking the larger image of the two results.

To make this easier, resize itself has a built-in test option which will only resize an image if that would make the image larger. This allows use a very nifty solution to our problem.


  convert logo: \
          -resize x160 -resize '160x<'   -resize 50% \
          -gravity center  -crop 80x80+0+0 +repage  space_fill.jpg

	[IM Output]

In the above, the second resize in the series will only resize if the width produced by the first resize was smaller than the area we are trying to fill.

The specific order of the resizes (height first, then width) was chosen, as most images are photographs which are usually longer horizontally. With the above ordering, such a case will result in the second resize operation being skipped.

If your images are more often portrait images (longer vertically) then change the arguments to resize the image by height first, then width. For example...


  convert logo: \
          -resize 160x -resize 'x160<'   -resize 50% \
          -gravity center  -crop 80x80+0+0 +repage   space_fill_2.jpg

	[IM Output]

The result of both of these examples should be very similar, and the command will work for both landscape and portrait styles of image, though it works better for one sort.

The biggest problem with this method is that the image is now being resized 2 to 3 times, producing extra blurring and other possible artifacts in the final result. To reduce this, the initial resizes are performed at double the final dimensions, which assumes the original image is at least 3 or more times the size of the final desired result. Not a problem for thumbnail production, but something to keep in mind.


Resizing Line Drawings
Doing a strong resize of an image containing thin lines can represent a big problem...

Resizing images to very small thumbnails, causes thin lines that are only a few pixels wide to fade and disappear into the background. This can get so bad that I have seen thumbnails of a line drawing which looked completely blank! That is, every detail of the original drawing 'disappeared', making the thumbnail rather useless.

If this is problem there are a few techniques that can help...

    Resize then adjust contrast to make lines more visible. Though this will make the lines more aliased (staircased). It also has limits to just how far this technique can be used.

    Blur and threshold the image (a method very similar to morphological 'dialate' or 'erode') so as to produce make single pixel lines about 300% thicker. Now after resizing by 1/3 the image will be smaller but the lines will remain just as strong and visible as before.

    Thicken lines using Thicken Morphology techniques.

    You may like to do the resize in stages, thickening and resizing the image by 50% at a time until you get to the final size.

    Though as the spacing between the lines shrinks you may find you end up with more of a 'blob' than a line drawing. That is you may get the opposite problem. Adjusting the ratio of thickening to resize however should produce an acceptable result.

    Separate the line edging in an image from the areas of solid colors, and resize each by different methods (lines using the above). Afterward the two parts can be merged back together again, allowing you to preserve the line edging of the image.

    This will in effect reproduce the effect you often get when resizing vector images.

    Convert image to a vector image, then resize. This can be tricky but also can produce the best possible result for resizing line drawings, with perfect anti-aliased (sharp) edges, and clear images. 

If you come up with some other way of effectively resizing line drawings, or tried some of the above technqiues, please let me (and other IM users) know about it.

Created: 15 March 2004
Updated: 10 October 2012 (split resampling filters to separate section)
Updated: 10 October 2012
Author: Anthony Thyssen, <<PRESIDIO_ANONYMIZED_EMAIL_ADDRESS>>
Examples Generated with: [version image]
URL: https://legacy.imagemagick.org/Usage/resize/
Information 2: 
ImageMagick v6 Examples --
Resampling by Nicolas Robidoux
Index
ImageMagick Examples Preface and Index
Resampling Filters

    Methods Recommended by Nicolas Robidoux

        Short Answer
        Quality Control
        Detailed Answer
        Recommended Upsampling Methods (Enlarging)
        Upsampling Examples
        Recommended Methods for Downsampling (Shrinking)
        Downsampling Examples
        Borderline Cases
        Feedback
        Thanks 

The following has been provided by Nicolas Robidoux, now a Senior Research Scientist at Phase One A/S. He has been of great help in improving image processing in ImageMagick, especially the development of Cylindrical Filters as used by the EWA resampling of the General Distortion Operator.

The following are his views on image filters and the best techniques to either shrink (down sample) or enlarge (up sample) different types of images for different requirements. Note that Nicolas is a very active researcher, and as such the following views do change over time.

WARNING: Some of the techniques may only work with recent versions of ImageMagick, and many of the filters do not (and may never) have 'named' filters within ImageMagick "-filter" setting, so require the use of Expert Filter Controls.

Short Answer
When resizing, I (Nicolas Robidoux) generally stick to either a tensor (orthogonal, or 2-pass) Resize (-resize) Operator filter, or an EWA (Elliptical Weighted Averaging) Distort Resize (-distort Resize) operator. Although the filter kernels used with tensor and EWA operations are built using the same families of mathematical functions, they give very different results when used with -resize and when used with -distort Resize.


If you want to use one single filter for everything and would rather avoid complications like color space manipulations and fancy parameters, use the LanczosSharp EWA (Elliptical Weighted Averaging) Filter. It produces images that are slightly blurry, with no jaggies to speak of and reasonably mild halos.


  convert {input} -filter LanczosSharp -distort Resize 200% {output}

The above command resizes by 200 percent, that is, it doubles the width and height of the original image. Change "200%" to the desired size specification. In addition, "{input}" and "{output}" should be replaced by the full names of the original and resized images.


For much sharper results, use the tensor (orthogonal or 2-pass resize) Lanczos Filter.


  convert {input} -filter Lanczos -resize 200% {output}

For certain types of images and operations, tensor Lanczos is the default -resize filter and you can omit "-filter Lanczos".

I do not recommend tensor (-resize) Lanczos filtering unless you use an HDRI Version of ImageMagick. This has nothing to do with any flaw of the tensor Lanczos filter. It has to do with the ImageMagick implementation of tensor filters, which saves memory by clamping intermediate results as a side effect of storing them into 8 or 16-bit unsigned integers (HDRI saved them as doubles, so are unaffected). In other words, the generally mild artifacts that arise when using tensor Lanczos without HDRI result from an "engineering decision" that allows -resize filters to run significantly faster than EWA ones. The present recommendations focus on quality, not speed.

(To find out whether you are running a Q8, Q16 or HDRI version of the convert command, run convert -version. If "HDRI" appears somewhere in the output text message, it's HDRI. If "Q8" appears, it's Q8. Otherwise, it's Q16, the most commonly installed version. If you don't know what version you have installed, chances are it's Q16.)

If you want something about as sharp as tensor Lanczos with a Q8 (8-bit) or Q16 (16-bit) ImageMagick, use EWA Lanczos Radius 3.


  convert {input} -filter LanczosRadius -distort Resize 200% {output}

EWA Lanczos Radius 3 (-filter LanczosRadius) is a recent addition to ImageMagick (version 6.8.0-2). See the Recommended Upsampling Methods (Enlarging) section below for code (with one "fancy parameter") that reproduces this filter with older ImageMagick releases.


EWA LanczosSharp, tensor Lanczos, and EWA Lanczos Radius 3 add two halo rings to sharp interfaces and lines.

To make the second halo unnoticeable, use EWA Quadratic-windowed Jinc 3-lobe, nicknamed "QuadraticJinc". (One "fancy parameter" is needed to generate this filter.)


  convert {input} -define filter:window=Quadratic -distort Resize 200% {output}


To eliminate the second halo completely, use the EWA Robidoux Filter.


  convert {input} -distort Resize 200% {output}

Robidoux is the default "-distort Resize" filter. This is why the above command does not contain "-filter Robidoux".

With HDRI ImageMagick, I recommend tensor Mitchell (the Mitchell-Netravali filter) over EWA Robidoux. Tensor Mitchell and EWA Robidoux are very similar. Although both have no second halo, EWA Robidoux has less of it, and its halo is "smoother". However, tensor Mitchell manages to be slightly sharper without usually being more jaggy.


  convert {input} -filter Mitchell -resize 200% {output}

Mitchell is the default -resize filter for some types of images and operations. For this reason, "-filter Mitchell" can often be omitted.


If you do not want to introduce any halo, use the EWA Quadratic B-spline Filter.


  convert {input} -filter Quadratic -distort Resize 200% {output}

The quadratic B-spline filter is quite blurry, although less so than the better known, and even smoother, tensor cubic B-spline smoothing filter.


Here is a list of the above filters in decreasing order of sharpness (more is good) and halo (more is bad): tensor Lanczos (sharpest, with the most halo), EWA LanczosRadius, EWA LanczosSharp, EWA QuadraticJinc, tensor Mitchell, EWA Robidoux, and finally EWA Quadratic (very blurry, with no halo). Of course, halo and blur are not the whole story: Most importantly, there are also moiré, tonal drift and "jaggies" to worry about.

If you are willing to add just one bell and whistle to your toolchain, it should be to downsample (shrink, or reduce) images through linear light. When downsampling (for example, making a thumbnail), you really should filter through the linear RGB or XYZ color spaces, as discussed in Colorspace Correction. Although this is less of an issue with blurry images and images without dense color patterns, not downsampling through linear light can cause great damage, as documented in Eric Brasseur's Gamma Error in Picture Scaling (which unfortunately presents outdated ImageMagick commands).

On the other hand, I do not recommend upsampling (enlarging) through linear light. That is: You generally should not use standard linear light Colorspace Correction when enlarging images, at least when using filters with significant negative lobes (any filter that introduces haloing, which means most of them). Compare the RGB and XYZ (linear light) enlargements to the sRGB (not color corrected) and sigmoidized (custom color corrected) enlargements shown in the Enlarge with sRGB, RGB, LAB, LUV, XYZ, sigmoidal...? ImageMagick Forum thread. The linear light enlargements (RGB and XYZ) are almost always significantly worse. The sigmoidized elargements generally look best, although enlargements through Lab are sometimes even better. Enlargements through linear light often look so bad that you are better off ignoring color space issues and filtering sRGB pixel values directly (using commands like the above).

Quality Control
Use the Expert Filter Option "-define filter:verbose=1" to make ImageMagick give detailed information on the selected filter for a resize or distort operation.

Do not use an IM Q8 (8-bit) version of ImageMagick with Colorspace Correction (-colorspace), or Sigmoidal Colorspace (-sigmoidal-contrast) resize techniques.

Do use a HDRI Version of IM when using a tensor (2-pass) Resize Operator (-resize) with a filter with one or more negative lobes. HDRI prevents internal clipping of "between resize passes" intermediate values. This clipping leaves small artifacts, especially when enlarging. HDRI is not necessary with the Triangle, Quadratic and Spline filters, because they don't have negative lobes. HDRI is also unnecessary with -distort Resize.

Almost always downsample (shrink) through linear light (provided you do not use a Q8 (8-bit) version of ImageMagick), and almost never upsample (enlarge) through linear light. Working with the wrong colorspace can have as much impact as a bad filter choice. (The real solution may be to choose filters that work well with linear light even when enlarging, but it is more expedient to change color space.)

The chosen conversions into and out of linear RGB assume sRGB input and output images. Other color spaces may require different conversions (into and out of the XYZ color space, for example).

You may want to navigate color spaces using color profiles instead of the built-in conversion utility (-colorspace).

These recommendations have not been carefully checked with an active transparency channel.

Detailed Answer
Downsampling (reducing the image's pixel count, for example, producing thumbnails) and upsampling (enlarging or, more generally, resampling without downsampling much) produce different artifact mixes. For this reason, different techniques are recommended for each type of geometrical operation.

Recommended Upsampling Methods (Enlarging)
Results of resizing using the LanczosSharp EWA Filter through a Sigmoidized Colorspace are fairly artifact free, if a bit blurry. The built-in LanczosSharp, discussed in the Short Answer, works well, but I prefer a version with slightly less de-blur, obtained with the "-filter Lanczos -define filter:blur=.9891028367558475".


  convert {input} -colorspace RGB +sigmoidal-contrast 7.5 \
          -filter Lanczos -define filter:blur=.9891028367558475 \
          -distort Resize 500% \
          -sigmoidal-contrast 7.5 -colorspace sRGB {output}

You would get nearly identical results with the built-in LanczosSharp filter, which is obtained by replacing "-filter Lanczos -define filter:blur=.9891028367558475" by "-filter LanczosSharp".

"Sigmoidization" has to do with the pair of Sigmoidal Contrast operators. Basically, the "+sigmoidal-contrast" operator (with a "+") converts the linear RGB version of the image created by -colorspace RGB to a custom RGB color space that has a S-shaped "intensity curve" instead of a linear one. This "intensity curve" is a bit like piecing together two sRGB gamma curves (one using negated images) to make a symmetrical S curve. The "-sigmoidal-contrast" operator (with a "-") converts the result of filtering back to a normal linear RGB result, which is converted back to the sRGB colorspace for the final save.

You may decrease halos and increase perceptual sharpness by increasing the sigmoidal contrast (up to 11.5, say). Higher contrasts are especially recommended with greyscale images (even "false RGB greyscale" that have three proportional color channels). The downside of sigmoidization is that it sometimes produces "color bleed" artifacts that look a bit like cheap flexographic ("gummidruck") printing or chromatic aberration. In addition, sigmoidization's "fattening" of extreme light and dark values may not work for your image content. If such artifacts are obvious, push the contrast value down from 7.5 (to 5, for example, or even lower). Setting the contrast to 0 is equivalent to enlarging through linear RGB.

WARNING: The two sigmoidal contrast values must match. That is: If you change the first "7.5" to "5", you must do the same with the second "7.5" as well. Likewise, if you remove one of the -colorspace commands, also remove the other one unless, of course, you actually intend to convert to another color space. The commands shown in these recommendations assume that the input and output color spaces are both sRGB.

You may skip sigmoidization altogether, by omitting the two "+/-sigmoidal-contrast" commands, in which case I recommend converting into and out of the Lab color space instead of linear RGB.


  convert {input} -colorspace Lab \
          -filter Lanczos -define filter:blur=.9891028367558475 \
          -distort Resize 500% -colorspace sRGB {output}

As discussed at the end of the Short Answer, enlargements of sRGB images through linear RGB generally look worse than enlargements that are performed by filtering sRGB pixel values directly. In any case, you should omit the two -colorspace commands is you use a Q8 version of ImageMagick.


  convert {input} -filter Lanczos -define filter:blur=.9891028367558475 \
          -distort Resize 500% {output}

The last three commands show how to use one single filter (my favorite EWA LanczosSharp variant, specified by "-filter Lanczos -define filter:blur=.9891028367558475 -distort Resize") three different ways, defined by the color space in which the "mixing of pixel values" is done: sigmoidal, Lab, and sRGB. Every filter can be used with every one of the recommended color spaces. In the remainder of this section, I only show the sigmoidized version.


If you want sharper results, use sigmoidized EWA with another modified "Cylindrical Lanczos 3" filter, namely EWA Lanczos Radius 3.


  convert {input} -colorspace RGB +sigmoidal-contrast 7.5 \
          -filter LanczosRadius -distort Resize 500% \
          -sigmoidal-contrast 7.5 -colorspace sRGB {output}

The above command does not work with ImageMagick older than version 6.8.0-2. You can reproduce this EWA Lanczos Radius 3 by manually setting the blur variable.


  convert {input} -colorspace RGB +sigmoidal-contrast 7.5 \
          -filter Lanczos -define filter:blur=.9264075766146068 \
          -distort Resize 500% \
          -sigmoidal-contrast 7.5 -colorspace sRGB {output}

The Blur Expert Control can be used to adjust the sharpness of the scheme. Decreasing blur increases sharpness, mostly at the expense of increasing jaggies (when downsampling, increasing moiré). Setting "blur=.9264075766146068" scales the EWA disc so it has a radius equal to exactly 3, hence the name "EWA Lanczos Radius 3". (Setting "blur=.9812505644269356" reproduces the built-in EWA LanczosSharp filter.)


If you want something even sharper, use a sigmoidized tensor (orthogonal or 2-pass resize) "Ginseng 3-lobe" filter.


  convert {input} -colorspace RGB +sigmoidal-contrast 7.5 \
          -define filter:window=Jinc -define filter:lobes=3 \
          -resize 500% -sigmoidal-contrast 7.5 -colorspace sRGB {output}

"Ginseng" refers to "Jinc-windowed Sinc" filter: it is a pun based on the similarity of the pronunciations of "Jinc-Sinc" and "Ginseng". Unlike almost all EWA filters, as well as the commonly used tensor Mitchell-Netravali (Mitchell) filter), the Ginseng tensor filter, like the tensor Lanczos Filter, is interpolatory, usually a good thing as far as sharpness is concerned. With HDRI turned on, tensor Ginseng is actually recommended over EWA Lanczos Radius 3.


If the second halo of the above filters bothers you, try sigmoidized EWA Jinc 3-lobe windowed with quadratic B-spline ("QuadraticJinc").


  convert {input} -colorspace RGB +sigmoidal-contrast 7.5 \
          -define filter:window=Quadratic -distort Resize 500% \
          -sigmoidal-contrast 7.5 -colorspace sRGB {output}


You can eliminate the second halo completely using sigmoidized -distort Resize and -resize with Keys cubics. These filters are discussed further in the downsampling section below. I recommend them more for downsampling than upsampling. Nonetheless, they are easy to adjust to taste, and give pretty good results. Start with tensor Mitchell (-filter Mitchell -resize) and EWA Robidoux (-distort Resize), and give a try to EWA RobidouxSharp (-filter RobidouxSharp -distort Resize) and tensor Catmull-Rom (-filter CatRom -resize) if you want something sharper. (Only use -resize with HDRI.)


If you do not want to add any haloing whatsoever, use sigmoidized EWA quadratic B-spline smoothing. It is blurry, but it strikes a pretty good balance between sharpness and jaggedness for a monotone filter. Because it is smoothing, higher values of the contrast are recommended.


  convert {input} -colorspace RGB +sigmoidal-contrast 9.5 \
          -filter Quadratic -distort Resize 500% \
          -sigmoidal-contrast 9.5 -colorspace sRGB {output}

If your image contains lines that are perfectly vertical or horizontal, or contains synthetic linear color gradients, you may want to use sigmoidized tensor quadratic B-spline smoothing filter instead of the EWA version. The tensor version is obtained by replacing "-distort Resize" by "-resize". It is blurrier, by a minuscule amount, than the EWA one. Because it has no negative lobe, tensor Quadratic works fine without HDRI.


If you want neither halos nor jaggies and are willing to live with a lot of blur, use sigmoidized EWA cubic B-spline smoothing.


  convert {input} -colorspace RGB +sigmoidal-contrast 10.75 \
          -filter Spline -distort Resize 500% \
          -sigmoidal-contrast 10.75 -colorspace sRGB {output}

Again, you may want to try the tensor (-resize) version; it preserves horizontal and vertical features well, and is very slightly more blurry. It works fine without HDRI.

Upsampling Examples
In this section, I show the results of enlarging a minuscule image produced by the following code, 10 times (from 10x6 to 100x60).


  convert -size 10x6 xc:grey20 +antialias \
          -draw 'fill white line 4,0 5,5' line.png

The same test image and enlargement ratio was used in the enlargement section of the Filter Comparison.

First, enlargements performed with sigmoidization.
[IM Output]

The Point enlargement, which uses nearest neighbor pixel replication, is there to show the tiny 10x6 image, unprocessed. The other filters are ordered based on the amount of halo and blur they introduce.

Besides nearest neighbour (Point), the comparison includes four interpolatory filters: tensor Cosine-windowed Sinc 3-lobe a.k.a. Cosine (-filter Cosine -resize), tensor Sinc-windowed Sinc 3-lobe a.k.a. Lanczos (-filter Lanczos -resize), tensor Jinc-windowed Sinc 3-lobe a.k.a. Ginseng (-define filter:window=Jinc -define filter:lobes=3 -resize), and tensor filtering with the Catmull-Rom Keys bicubic a.k.a. Catrom (-filter CatRom -resize). The interpolatory filters are among the sharpest and most jaggy, with deep halos. Indeed, sharpness is approximately proportional to the amount of haloing and jaggedness when using a high quality filter.

Here are the results of enlarging through the Lab color space (without sigmoidization).
[IM Output]

Here are the results of enlarging without the colorspace and sigmoidal-contrast commands, that is, filtering sRGB pixel values directly. They are quite similar to the results of enlarging through the Lab color space.
[IM Output]

Finally, here are the results of enlarging through linear RGB (without sigmoidization). Such results are the basis for the "don't enlarge through linear light" recommendation.
[IM Output]

Recommended Methods for Downsampling (Shrinking)
Basically, the filters recommended for upsampling are also recommended for downsampling. Downsampling, however, should almost always be done using a linear light Colorspace Correction technique.

ImageMagick has two linear light color spaces built in: RGB and XYZ. With sRGB images, the RGB color space, which stands for linear RGB with sRGB primary colors in ImageMagick, is the obvious choice. In some situations (jarringly obvious dark halos, sharp images without dense pixel patterns), it may be preferable to use mild (contrast<4) sigmoidization. In general, however, you should stick to linear light downsampling. This is what is done in the remainder of this section. (Of course, downsample without color space conversions when using Q8 ImageMagick.)

First, try downsizing through linear RGB with the LanczosSharp EWA Filter variant discussed in the upsampling section.


  convert {input} -colorspace RGB \
          -filter Lanczos -define filter:blur=.9891028367558475 \
          -distort Resize 20%    -colorspace sRGB {output}

For sharper results, use linear light EWA Lanczos Radius 3.


  convert {input} -colorspace RGB -filter LanczosRadius \
          -distort Resize 20% -colorspace sRGB {output}

You can increase sharpness by decreasing the blur value. For example, "blur=0.88549061701764" generates a decent strongly sharpening filter called "EWA Lanczos3Sharpest" in the ImageMagick Forums and in Adam Turcotte's forthcoming Masters thesis.

Very sharp results are obtained with tensor Cosine-windowed Sinc 3-lobe, a.k.a. Cosine.


  convert {input} -colorspace RGB -filter Cosine \
          -resize 20% -colorspace sRGB {output}

Tensor Lanczos is sharper than tensor Ginseng but softer than tensor Cosine. They give similar results. I actually prefer the Ginseng results, but many people want very sharp results when downsampling. Recommending tensor Cosine is consistent with this common preference. (Remember to use HDRI with such -resize filters.)

You can decrease moiré by increasing the blur value, by increasing the number of lobes, and/or by changing window function. Increasing the blur value is safe, although it also decreases sharpness. I generally do not recommend using more than three lobes, because I do not like seeing more than two halos, and I find the benefits of using more than four lobes to be small. This being said, if your original image is blurry, the additional halos may be invisible, and increasing the number of lobes may be worth a try.

I do not recommend changing window functions if you don't really know what you are doing. (This being said, the Hann window function is a solid general purpose window, and Parzen works well with four lobes.)


Another annoying artifact is haloing (ringing). The above filters all have noticeable second halos. The following filter, EWA quadratic B-spline-windowed Jinc 3-lobe ("QuadraticJinc"), has a very mild second halo and yet manages fairly strong moiré suppression without being too blurry.


  convert {input} -colorspace RGB -define filter:window=Quadratic \
          -distort Resize 20% -colorspace sRGB {output}


To eliminate the second halo completely, use linear light Robidoux EWA Filtering.


  convert {input} -colorspace RGB \
          -distort Resize 20% -colorspace sRGB {output}

The Robidoux Filter is a member of the Keys family of BC-splines. You can dial the sharpness and haloing of the result by adjusting the B parameter. "B=1.0" reproduces EWA cubic B-spline filtering, a halo-free but very blurry filter; "B=0.0" reproduces EWA Catmull-Rom filtering, a very strongly sharpening filter; and linear light EWA Robidoux can be reproduced with the following command.


  convert {input} -colorspace RGB \
          -filter Cubic -define filter:B=.37821575509399867 \
          -distort Resize 20% -colorspace sRGB {output}

From blurry (less halo) to sharp (more halo), the named Keys cubics are Spline, Robidoux, Mitchell, RobidouxSharp, and CatRom. See Cubic B,C Expert Controls for a table of the B values of these filters. Without setting the B value, the named Keys cubics can be obtained using "-filter {filtername}" instead of "-filter Cubic -define filter:B={value}".

Although, with Keys cubics, I prefer linear light EWA filtering when downsampling, linear light tensor filtering with Keys cubics is also recommended (provided you use HDRI). This is obtained by replacing "-distort Resize" by "-resize". Tensor filtering with the Mitchell cubic (-filter Mitchell -resize) is particularly good.


If you do not want any haloing, use linear light EWA or tensor Quadratic or Spline filtering (see the upsampling section). You may also get good results with linear light EWA Triangle filtering.


  convert {input} -colorspace RGB -filter Triangle \
          -distort Resize 20% -colorspace sRGB {output}

Linear light tensor Triangle (a.k.a. bilinear) is obtained by replacing "-distort -resize" by "-resize". Tensor Triangle is slightly blurrier and shows less moiré than its EWA version, and it preserves perfectly horizontal and vertical features better as well. It works fine without HDRI. Both EWA and tensor Triangle filtering are interpolatory.


With the exception of EWA Triangle, tensor Triangle and EWA Lanczos3Sharpest, the above filters also work well when enlarging. (Tensor Triangle is actually recommended if you are enlarging just a little bit.)

Adjusting the blur (between 0.7 and 1.0) or B parameters (between 0.0 and 1.0) should obviate the need for USM (Unsharp) Sharpening, a common final step when downsampling, or allow you to use less of it. Note however that low values of the blur and B parameters generally lead to considerable artifacts; high values, to blur.

Downsampling Examples
These examples use the Smaller Rings Image image also used in the Aliasing and Moiré Effects section. Instead of resizing this 200x200 image down to 100x100, using sRGB values directly, we downsize to 101x101 through linear RGB.
[IM Output]

Ideally, many concentric rings should be preserved, without the appearance of features which are not in the original. There is no such thing as a free lunch: The filters that lose the fewest rings have the most obvious artifacts. Nonetheless, some of the filters manage a pretty good balance between sharpness and aliasing, namely EWA QuadraticJinc, tensor Mitchell, and tensor Triangle. EWA LanczosSharp, EWA Quadratic, EWA Lanczos Radius 3 and EWA Robidoux also do well in this test. Generally, EWA methods have good moiré suppression.

Borderline Cases
If you are changing the aspect ratio to the extent that you upsample (enlarge) in one direction and downsample (reduce) in the other, use a technique that works well in both situations, like linear light EWA LanczosSharp, tensor Ginseng, EWA Lanczos Radius 3, or EWA quadratic B-spline-windowed Jinc 3-lobe ("QuadraticJinc").

If you are both downsampling and upsampling, downsampling considerations should dominate your choice. For example, resize through linear light, as if you are downsampling in both directions.

The same prescription basically holds if the resizing ratio is close to 1 in both directions, for example if you are resizing a 100x100 image to 102x102, 95x95 or 102x95 (or rotating the image). First, try interpolatory filters like tensor Ginseng or tensor Triangle. The usual EWA Lanczos Radius 3, EWA LanczosSharp and EWA QuadraticJinc work well too. Sigmoidization should be used sparingly (constrast<5.5), if at all. In other words, you probably should stick to linear light when barely resizing, although the "should" is weaker than if you are shrinking a lot in one or both directions.
Feedback
I read positive and negative comments with interest. These recommendations are a work in progress, and consequently examples in which they fall short of expectations are particularly valuable.

Sigmoidization and resizing through the Lab color space, in particular, are recent additions to my tool kit and their strengths and limitations have not been carefully established. Consequently, I am particularly interested in hearing about good and bad experiences with these techniques. For example, it appears that sigmoidization is not so good with "defective" images which already contain significant ringing and haloing, or have been heavily manipulated somehow (that are far from "natural"), although it seems to do fine at enlarging CG art, line drawings and text-like images.

Sending NicolasRobidoux a message through the ImageMagick Forums System is a good way to point me to a relevant post. Otherwise, try <<PRESIDIO_ANONYMIZED_EMAIL_ADDRESS>>.

Thanks
I (Nicolas Robidoux) thank John Cupitt, Henry HO, Bryant Moore, Mathias Rauen, Adam Turcotte, Dane Vandeputte, Luiz E. Vasconcellos and Fred Weinhaus for useful comments, with special thanks to <PRESIDIO_ANONYMIZED_PERSON> on whose shoulders I stood when developing EWA methods. Anthony and Cristy built quite a nice platform for image processing research.

Created: 10 October 2012
Updated: 21 October 2012
Author: Nicolas Robidoux, <<PRESIDIO_ANONYMIZED_EMAIL_ADDRESS>>
Formatting: Anthony Thyssen, <<PRESIDIO_ANONYMIZED_EMAIL_ADDRESS>>
Examples Generated with: [version image]
URL: https://legacy.imagemagick.org/Usage/filter/nicolas/