Search code examples
image-processingimagemagickimage-scaling

9-slice scaling with imagemagick?


Given an input image of dimensions 120x120 pixels, I'd like to use imagemagick to perform 9-slice scaling.

  • keep the image within the box bounded by top-left coordinate (10,10) and bottom right coordinate (110,110) unscaled, This centre section is 100x100 pixels.
  • The left side scale by a given factor, say 3, so this would go from 10x100 pixels to 30x100 pixels
  • The right side scale by a given factor, say 2, so this would go from 10x100 pixels to 20x100 pixels
  • The top and bottom side both scale by a given factor, say 1.5, so these would go from 100x10 to 100x15 each.
  • The four corners would scale to fit the new dimensions of the new top, right, bottom, and left sides.

Something similar to (except in my case the centre element, "5", doesn't need to change)

How can I perform this operation using imagemagick?

(Suggestions for any other CLI tool available on Linux also welcome!)


Solution

  • Using ImageMagick you can approach this as a series of isolated cropping and resizing operations. Here's an example command...

    magick input.png -write mpr:img0 +delete ^
       ( mpr:img0 -gravity west -crop 10x+0+0 -resize 300x100% ) ^
       ( mpr:img0 -shave 10x0 ) ^
       ( mpr:img0 -gravity east -crop 10x+0+0 -resize 200x100% ) ^
       +append +repage -write mpr:img0 +delete ^
       ( mpr:img0 -gravity north -crop x10+0+0 -resize 100x150% ) ^
       ( mpr:img0 -shave 0x10 ) ^
       ( mpr:img0 -gravity south -crop x10+0+0 -resize 100x150% ) ^
       -append +repage result.png
    

    This command will take a 10 pixel wide strip from the left and right sides, widen the left by 300% and the right by 200%, and re-append them to the center.

    Then it follows by taking a 10 pixel high strip from the top and bottom, resizing both their heights to 150%, and re-appending them to the center section.

    The corners get properly scaled because they go through both the horizontal and vertical resizing operations.

    The command uses IMv7 in Windows CLI syntax. For a Windows BAT script you need to double the percent signs "%%".

    To make it work on a *nix system change the continued-line carets "^" to backslashes "\" and escape the parentheses with backslashes "\(...\)".

    To use it with IMv6 change "magick" to "convert".