Skip to content

ImageMagick

Malcolm Riley edited this page Jun 21, 2024 · 1 revision
magick original.png -trim -resize 64x64 -resize 80% \
	-gravity center -background none -extent 64x64 \
	output.png

What does it mean?

Command-line Image Processsing with ImageMagick

Cropping, rescaling, and color grading renders is a common post-Blender processing step. It's possible to do all of this and more, automatically.

What is ImageMagick?

ImageMagick is a command-line image processing tool. It can be downloaded from their website. Like Blender, ImageMagick is both free and open-source. It is also available as a HomeBrew formula imagemagick (via brew install imagemagick).

As ImageMagick operations are invoked from the command-line, it can be used to save time when performing common editing operations. If one finds themselves repeatedly performing the same post-render processing steps, it is likely that they could save time by creating a shell script or batch file with these operations. In combination with Command-Line Rendering, it is theoretically possible to automate the entire rendering-to-final-sprite pipeline.

Just about every image-processing operation that can be imagined can be performed using ImageMagick, from mundane operations such as scaling or file type conversion, to exotic operations such as image fourier transformation for denoising or deconvolution - "enhance!". As a result, it is quite complex and thus is probably not the most time-efficient tool for one-off edits in comparison to a more conventional WYSIWYG application.

File Format Conversion

The simplest ImageMagick command is to ingest an input file and return an output file:

magick input.jpg output.png

The format of the output is deduced from the provided suffix; therefore in the above example the image input.jpg will be converted to a PNG. One might encounter useful or interesting sprites on the internet in the wrong format; a user can use ImageMagick to quickly convert these without having to open up an app.

Rescaling

One of the most common post-render operations is to rescale the image. While it is possible to do this in Blender's Compositor, if any intermediate external editing is needed, then the rescaling step might as well be performed externally as well. This is also a very straightforward operation:

magick ${input} -resize 64x64 ${output}

With ${input} being replaced with the path to the input file, and ${output} being replaced with the desired path to put the output, this will rescale the input image to a 64x64 pixel output. The argument passed to the -resize argument is known as an "Image Geometry Argument" and it can take many forms, but I've summarized the most commonly-used kinds below:

Syntax Meaning Example
${x}x${y} Where ${x} is width, ${y} is height, resize to at most these pixel dimensions -resize 512x1024 - Output dimensions will be at most 512px (width) by 1024px (height) such that the original aspect ratio is preserved
x${y} Where ${y} is height, resize such that the height is the specified dimension, preserving aspect ratio -resize x64 - Output height will be 64px, and width will be such the original aspect ratio is preserved
${x} Where ${x} is width, resize such that the width is the specified dimension, preserving original aspect ratio -resize 64 - Output width will be 64px, and height will be such that the original aspect ratio is preserved
${scale}% Where ${scale} is the percentage, resize by a percentage of the original -resize 40% - Output dimensions will be 40% of the dimensions of the input

It is also possible to explicitly specify filters for operations using the -filter argument, but this argument must precede the -resize argument:

  • Point and Box are "nearest neighbor" interpolations (with Box including special handling for reductions in image dimensions)
  • Triangle is "Bilinear" interpolation
  • Catrom is a specific implementation of "Cubic" interpolation

Thus, to convert an input image input.jpg to an output result.png with height of at most 128px using bilinear filtering:

magick input.jpg -filter triangle -resize x128 result.png

Note

There is much to be explored about which filter is best to use for rescaling sprites for Factorio, but this is left as an exercise to the reader. Factorio itself uses some variety of bilinear interpolation when automatically generating mipmaps, so triangle is likely good enough.

Removing Extraneous Transparent Edges

Cropping out extraneous padding from an image is such a common operation that ImageMagick has a built in argument for it: -trim. Technically, this removes any padded edges from the image that are the same color as the corner pixels; thus if the corner pixels are all transparent, the operator will remove all transparent padding from the input image.

magick ${input} -trim ${output}

An example demonstrating how to use the ImageMagick trim operator

Note that in the above example, a 1px wide border has been added around the original images for visual clarity.

This can be a useful intermediate step between resizing, to ensure that resulting sprites are of a consistent apparent size and to prevent the need for manually cropping. That is to say, if a render has extra transparent padding around the subject matter and is resized without it, then a proportional amount of transparent padding is present in the output image as well. This isn't necessarily a problem, but it can make sprites look "too small".

Special Example: Re-Centering Subject Matter

Due to the complexity and scale of ImageMagick, this cannot possibly be an exhaustive tutorial, but is instead an introductory one featuring a few commonly-used operations. One may consult the extensive ImageMagick Examples Page for more specifics, but to whet the appetite, let us conclude with a special example.

Suppose that the following render has been obtained for use as an item icon:

An off-center render of red and yellow crystals atop a rock

Note that a 1px wide border has been added for visual clarity.

As can be seen, the cameraman was a bit lazy and the image is quite off-center. Renders can be quite time-consuming so it would be better to fix this as a post-processing step rather than adjusting the camera to re-render, and manually cropping and re-centering many such images would probably be a bit tedious. Fortunately, all of these problems can be solved at once, automatically, with ImageMagick.

What needs to happen is a trimming operation to remove the extraneous padding, a centering operation to put it in the middle of the canvas, and a resize operation to reduce it to a size appropriate for use as an item icon.

magick bad_cinnabar.png -trim -resize 64x64 -gravity center -background none -extent 64x64 fixed_cinnabar.png

A centered and reduced-size render of red and yellow crystals atop a rock, more suitable for use as an item sprite

Note that a 1px wide border has been added for visual clarity.

This is better, but it would be best if there was a little bit of transparent padding on the edges of the image - as it is, the item sprite runs to the edges and will appear too large in game.

magick bad_cinnabar.png
	-trim \
	-resize 64x64 \
	-resize 80% \
	-gravity center \
	-background none \
	-extent 64x64 \
	fixed_cinnabar.png

A centered and reduced-size render of red and yellow crystals atop a rock, most suitable for use as an item sprite

Note that a 1px wide border has been added for visual clarity.

This is much better, and what's more, it can be used as a generic solution to all problems of this type. But what's going on here?

The ImageMagick argument operators are applied in order:

  1. The original image is trimmed, removing all the extraneous padding.
  2. The trimmed image is resized to 64x64; since the image was trimmed, the outermost extent of the subject matter is exactly touching the edges.
  3. The resized trimmed image is resized to 80% of the step 2 size, leaving some transparent padding
  4. An internal -gravity setting is applied, in preparation for step 6
  5. An internal -background setting is set to none (transparent pixels), in preparation for step 6
  6. The virtual canvas is extended to 64x64 pixels, keeping the original subject matter centered (see step 4) and using a transparent background (see step 5).

Table of Contents

Introductory Series

  1. Blender Basics
    How to use Blender
  2. Plates and Beams
    Dynamic and manual Mesh-making
  3. Gears
    Blender Add-Ons, simple Materials, and environments
  4. Corroded Metal Things
    Using Shader Nodes for procedural materials
  5. Gravel Pile
    How to use Geometry Nodes to procedurally generate Meshes, including automatic item variants

Miscellaneous Techniques

Blender-External Techniques

WIP Articles

  • Automatic Decoration: Rivets, Bolts and Fasteners
    A common visual motif is the ever-presence of rivets, bolts, and fasteners on the surface of metal objects. From the humble Assembling Machine to the exotic Spidertron, Factorio machines are a beautiful mess of crudely-fastened metal plates. Manually placing such Objects on the surface of Meshes is too much work, but Blender offers several semi-automated solutions.
  • Creating Compelling Crystals
    There isn't much precedent for effects like this in the base game, but even a relatively simple Material can create compelling images. Even seemingly complex features such as realistic refraction and chromatic aberration are relatively simple to accomplish.
  • Adding Details to Transparent Objects
    No material in real-life is perfectly uniform. Therefore, adding imperfections to the interior of a transparent Object can add realism and visual interest to a render. Whether adding bubbles to a gel or fluid, or adding mineral inclusions to a crystal, this simple method can help.
  • Using Shader Nodes to Rotate an Environment Texture
    HDRIs add realism and character to the lighting of a Scene, but rarely do the light features of these images arrive from the needed direction. Fortunately, there is an easy way to "rotate" the appearance of an HDRI without having to reorganize each and every Object in the Scene.
  • Looping Animations of Procedural Textures - Without Trigonometry
    Creating looping animations of animated procedural textures is fraught with peril - and trigonometry. There is an easier, more flexible, and more comprehensible method; what's more, it doesn't involve using a single trigonometric function. It can be used with 2D or 3D textures - you too can create looping animations of roiling volumetric clouds.
  • Easy Procedural Ores - Including Ground Transitions
    Many Factorio mods seek to add ores to the game - It may be easier than you think to create your own without having to resort to recoloring base-game assets.
  • Holdouts, Shadow Catchers, and Glow Textures
    When making a Factorio mod, sometimes it's necessary to capture only the shadow cast by an Object, only the light or "bloom" that it emits, or only everything except the Object itself. Blender makes alternative rendering techniques very straightforward.
Clone this wiki locally