Mipmap script (Python)

Enhance your gameplay with these tools. This category is also the right place for tools useful for modders.
Mod databases, calculators, cheatsheets, multiplayer, scripts, libs and other useful stuff that is not strictly in-game mods.
Post Reply
User avatar
Smart Inserter
Smart Inserter
Posts: 2512
Joined: Fri Nov 06, 2015 7:41 pm

Mipmap script (Python)

Post by Deadlock989 »

This is the script I use to convert batches of png images to the mipmap format expected by Factorio's item, recipe and technology icons.

It theoretically works with any size of square output image but is only really expected to work well with powers of 2 such as 64x64, 256x256 etc.

If the input image (after any transparent space around it is cropped off) is smaller or equally sized to the output image, it is not resized but will be centred on the output's sprite "canvas".

If the input image (ditto) is larger than the output image, it is resized down to the maximum size in either direction and then centred.

The PIL or Pillow libraries are required.

Code: Select all

from PIL import Image
import os, math
from pathlib import Path

def crop_canvas(old_image, size):
  old_image = old_image.crop(old_image.getbbox())
  old_width, old_height = old_image.size
  if old_width > size or old_height > size:
    largest = (old_width >= old_height) and old_width or old_height
    old_image = old_image.resize((int(size*old_width/largest),int(size*old_height/largest)), Image.LANCZOS)
    old_width, old_height = old_image.size
  x1 = int(math.floor((size - old_width) / 2))
  y1 = int(math.floor((size - old_height) / 2))
  newImage = Image.new("RGBA", (size, size), (0,0,0,0))
  newImage.paste(old_image, (x1, y1, x1 + old_width, y1 + old_height))
  return newImage

def create_mipmap(outputf, inputf, size, levels):
  original = crop_canvas(Image.open(inputf),size)
  mipmap = Image.new("RGBA", (int(size * ((1-0.5**levels)/0.5)), size), (0,0,0,0))
  offset = 0
  for i in range(0,levels):
    new_size = int(size * (0.5**i))
    copy = original.resize((new_size, new_size), Image.LANCZOS)
    mipmap.paste(copy, box = (offset, 0))
    offset += new_size

finput = "./input/"
foutput = "./output/"
max_icon_size = 64
mipmap_levels = 4

for dirpath, dirs, files in os.walk(finput):
    for filename in files:
        if ".png" in filename:
          create_mipmap(foutput+filename, finput+filename, max_icon_size, mipmap_levels)

User avatar
Posts: 27
Joined: Sun Jan 03, 2021 6:01 pm

Re: Mipmap script (Python)

Post by snouz »

Thanks, it works like a charm for me on windows using Anaconda, but for some reason I had to use absolute paths, like "C:/Users/Max/Desktop/output/" instead of "./output/".

For future users who are not python friendly, you need python3, anaconda, then you need the lib Pillow, install it with:

Code: Select all

python -m pip install --upgrade Pillow
Graphically contributed to : Bio Industries (soon) | Warehousing | MFerrari's mods | Brevven's mods | Bob Artisanal Reskins | Mining Drones | Teleporters | Emoji signals

Post Reply

Return to “Tools”