Back to blog

Minecraft Lohse Skin: Procedural Pixel Art

Procedurally generating Minecraft skins using Python PIL, creating pixel art based on the character Lohse from Divinity: Original Sin 2.

#Python#PIL#Minecraft#Pixel Art

Project Overview

This project procedurally generates Minecraft Java Edition 64×64 skins using Python scripts (PIL library). Based on the companion character Lohse from Divinity: Original Sin 2, it recreates character features within Minecraft's pixelated aesthetic framework.

Technical Implementation

Skin generation is entirely defined through code specifying pixel colors and positions, without manual image editing:

  • Uses RGB color blending functions to simulate light/dark gradients and material transitions
  • Separate implementations for Steve (4px arm) and Alex (3px arm) models
  • Hat layer supports full transparency (normal version) and partial thickening (volumetric hair version)

Generation Flow

Define palette → Draw head/torso base layer → Draw arms (Steve/Alex) →
Draw legs → Overlay decoration layer (cape, magic effects) → Output PNG

Core Code

Palette Definition

# Lohse theme colors
PALETTE = {
    'hair': (199, 168, 119),      # Golden long hair
    'skin': (255, 213, 170),      # Skin tone
    'coat_primary': (45, 45, 75),   # Dark purple coat
    'coat_secondary': (80, 60, 100),# Light purple inner
    'accent': (180, 140, 200),     # Magic purple
    'cape': (60, 50, 90),          # Cape
}

Pixel Drawing

from PIL import Image
 
def draw_pixel(img, x, y, color, alpha=255):
    """Draw pixel at specified position"""
    if alpha < 255:
        # Semi-transparent blending
        base = img.getpixel((x, y))
        blended = blend_colors(base, color, alpha / 255)
        img.putpixel((x, y), blended)
    else:
        img.putpixel((x, y), color)
 
def draw_gradient(img, x, y, width, color_start, color_end):
    """Draw gradient bar"""
    for i in range(width):
        ratio = i / width
        color = interpolate_color(color_start, color_end, ratio)
        draw_pixel(img, x + i, y, color)

Steve vs Alex Arms

def draw_arm_alex(img, is_left):
    """Alex model: 3px wide arm"""
    offset = 0 if is_left else 5
    for x in range(3):
        for y in range(12):  # Arm height
            color = get_arm_color(x, y, is_left)
            draw_pixel(img, offset + x, y, color)
 
def draw_arm_steve(img, is_left):
    """Steve model: 4px wide arm"""
    offset = 0 if is_left else 4
    for x in range(4):
        for y in range(12):
            color = get_arm_color(x, y, is_left)
            draw_pixel(img, offset + x, y, color)

Output Files

  • Lohse.png — Alex model version
  • Lohse_steve.png — Steve model version
  • Lohse_alex_volumetric.png — Alex volumetric hair version
  • Lohse_steve_volumetric.png — Steve volumetric hair version

Usage

# Install dependencies
pip install Pillow
 
# Generate skin
python build_lohse_skin.py
 
# Output in output/ directory

Limitations

Current implementation is pure code pixel generation, no GUI editing interface or in-game preview. Skins need to be manually imported into Minecraft.


Related Links


Last updated: 2026-04-19