Intro

I’m developing a 2D game in Unity called Enso that uses layers of objects placed at various depths from the camera in order to create a parallax effect. However, the size of my texture folder and therefore my game, was getting out of hand!

My Workflow

While designing the game world, I wanted to feel free to create any shape of object that I desired, and not have to think about pixel density, export dimensions, or really anything technical about the export and import processes.

A workflow naturally unfolded. I draw my objects in a vector program, and export them as separate images. I keep all of my objects at a consistent relative scale to each other inside the vector program. This ensures that my objects aren’t pixelated in Unity, because once I have found the correct export scale for my desired in-game pixel density, I can set it and forget it.

Once the images are all exported I find myself with a folder full of textures with completely random dimensions. This isn’t great for games, as a lot of compression techniques, like Crunch Compression, require images to be sized to a factor of 4. So let’s fix that!

The Solution - ImageMagick

ImageMagick is a Free and Open-source (FOSS) command-line program for manipulating images, and it is very powerful!

I recommend learning how to use it and seeing what you can implement to speed up in your own game creation workflow.

Extend the dimensions of a whole folder of images outwards to the next multiple of 4

Crunch compression is a very useful way to reduce the disk size of your textures. If you want to learn more, I recommend reading What Is Crunch Compression by Nick Mower.

Here is how I use ImageMagick on my textures to get them ready to be imported into Unity and ensure compatibility with Crunch Compression.

Make a whole folder of images padded outwards to the next multiple of 4

$folderPath = "C:\My Game\Textures"
$imageFiles = Get-ChildItem -Path $folderPath -Filter *.png

foreach ($file in $imageFiles) {
    # Get the dimensions of the current image
    $dimensions = iex "magick identify -format '%wx%h' `"$($file.FullName)`""

    # Extract width and height from the dimensions
    $width, $height = $dimensions -split 'x'

    # Calculate the next multiple of 4 for width and height
    $nextWidth = [math]::ceiling($width/4) * 4
    $nextHeight = [math]::ceiling($height/4) * 4

    # Extend image dimensions using magick convert
    magick convert `"$($file.FullName)`" -background transparent -gravity center -extent "${nextWidth}x${nextHeight}" "$($file.DirectoryName)\$($file.BaseName)_Resized.png"
}

This iterates through all the images found in the given folder, and extends the width and the height out until it reaches the next factor of 4. Then it exports the image with the _Resized suffix appended onto the filename so as not to overwrite the original.

Extend the dimensions of a single image outwards to the next multiple of 4

# Specify the path to the image file
$imageFilePath = "C:\My Game\Textures\Image_01.png"

# Get the dimensions of the current image
$dimensions = iex "magick identify -format '%wx%h' `"$imageFilePath`""

# Extract width and height from the dimensions
$width, $height = $dimensions -split 'x'

# Calculate the next multiple of 4 for width and height
$nextWidth = [math]::ceiling($width/4) * 4
$nextHeight = [math]::ceiling($height/4) * 4

# Extend image dimensions using magick convert
magick convert `"$imageFilePath`" -background transparent -gravity center -extent "${nextWidth}x${nextHeight}" "${imageFilePath}_Resized.png"

This does the same thing but only on a single image file.

Conclusion

Even though Crunch Compression is lossy, in my use-case I couldn’t see the difference. So this was a slam-dunk and reduced the size of Enso by a dramatic amount.