Body Rendering
The 2D body render assembles a full player model from six body parts extracted
from the skin texture: head, torso, left arm, right arm, left leg, and right
leg. Each part is cropped, resized, and composited onto a single output canvas.
The entire pipeline uses Jimp.
Body Part Regions
Each body part occupies a specific rectangle on the Minecraft skin texture. The
coordinates below are in the format (x, y, width, height) relative to the
top-left corner of the skin PNG.
Base Layer Parts
| Part | Position | Size | Notes |
|---|---|---|---|
| Head front | (8, 8) | 8x8 | Same as head render |
| Torso front | (20, 20) | 8x12 | |
| Left arm front | (44, 20) | 4x12 | |
| Right arm front | (36, 52) | 4x12 | New format only |
| Left leg front | (4, 20) | 4x12 | |
| Right leg front | (20, 52) | 4x12 | New format only |
Overlay Layer Parts
| Part | Position | Size | Notes |
|---|---|---|---|
| Head overlay | (40, 8) | 8x8 | Hat layer |
| Torso overlay | (20, 36) | 8x12 | |
| Left arm overlay | (44, 36) | 4x12 | |
| Right arm overlay | (52, 52) | 4x12 | New format only |
| Left leg overlay | (4, 36) | 4x12 | |
| Right leg overlay | (4, 52) | 4x12 | New format only |
Skin Layout Diagram
64x64 Modern Skin Texture Map:
0 4 8 16 20 28 32 36 40 44 48 52 56
0 +----+----+----+----+----+----+----+----+----+----+----+----+
| |Head | | |Hat | |
8 | |Top | | |Top | |
+---------+---------+---------+---------+---------+---------+
|Head|Head|Head|Head|Hat |Hat |Hat |Hat | | |
16 |Rgt |Frnt|Left|Back|Rgt |Front|Left|Back| | |
+----+----+----+----+----+-----+----+----+---------+---------+
| |Leg | | | |Torso| | | |Arm | | |
20 | |Frnt| | | |Front| | | |Frnt| | |
| |4x12| | | |8x12 | | | |4x12| | |
32 +----+----+----+----+----+-----+----+----+----+----+----+----+
| |Leg | | | |Torso| | | |Arm | | |
36 | |Ovly| | | |Ovly | | | |Ovly| | |
| |4x12| | | |8x12 | | | |4x12| | |
48 +----+----+----+----+----+-----+----+----+----+----+----+----+
| |RLeg| | | |RArm | | | | | | |
52 | |Frnt| | | |Front| | | | | | |
| |4x12| | | |4x12 | | | | | | |
64 +----+----+----+----+----+-----+----+----+----+----+----+----+
"R" prefix = right side (new format only, rows 48-63)
Overlay rows (32-47) mirror base rows (16-31) for each part.
Legacy vs Modern Skin Format
Minecraft skins come in two sizes:
- Legacy format: 64x32 pixels. Only the left arm and left leg are defined.
The right arm and right leg are created by mirroring (horizontally flipping)
the left side. - Modern format: 64x64 pixels. Both left and right limbs have independent
textures, plus overlay layers for every body part.
The API detects the format by checking the image height:
const isNewFormat = skin.bitmap.height >= 64;
For legacy skins, the right arm and right leg are generated by cloning and
flipping:
if (isNewFormat) {
rightArm = skin.clone().crop(36, 52, 4, 12)
.resize(size/4, size*3/4, Jimp.RESIZE_NEAREST_NEIGHBOR);
} else {
rightArm = leftArm.clone().flip(true, false);
}
The flip(true, false) call mirrors horizontally (left-right) without vertical
flipping.
Composite Layout
The output canvas is size pixels wide and size * 2 pixels tall (portrait
orientation). Body parts are positioned relative to the size parameter:
Output canvas (size x size*2):
0 size/4 size/2 3*size/4 size
+----------+----------+----------+----------+
0 | | | | |
| | HEAD | HEAD | |
| | (size/2 x size/2) | |
| | | | |
size/2+---------+----------+----------+----------+
| LEFT ARM | TORSO | RIGHT ARM|
| (size/4 | (size/2 x size*3/4) | (size/4 |
| x | | x |
| size*3/4)| | size*3/4)|
5s/4 +----------+----------+----------+----------+
| | LEFT LEG | RIGHT LEG| |
| | (size/4 | (size/4 | |
| | x | x | |
| | size*3/4)| size*3/4)| |
2s +----------+----------+----------+----------+
Part Positions (in pixels)
| Part | X offset | Y offset | Render size |
|---|---|---|---|
| Head | size/4 | 0 | size/2 x size/2 |
| Torso | size/4 | size/2 | size/2 x size*3/4 |
| Left arm | 0 | size/2 | size/4 x size*3/4 |
| Right arm | size*3/4 | size/2 | size/4 x size*3/4 |
| Left leg | size/4 | size*5/4 | size/4 x size*3/4 |
| Right leg | size/2 | size*5/4 | size/4 x size*3/4 |
Overlay Compositing
When the hat option is enabled, overlay layers are drawn on top of each base
part. The overlay regions are located 16 rows below their corresponding base
regions on the skin texture (e.g., torso base at row 20, torso overlay at
row 36).
The compositing order is bottom-to-top for each part:
- Draw base part.
- Draw overlay part at the same position (alpha-blended on top).
For legacy skins, right-side overlays are not available, so only the left arm
and left leg overlays are drawn. The right arm/leg overlay compositing is
skipped with an isNewFormat guard:
if (hat && isNewFormat) {
const rightArmOverlay = skin.clone()
.crop(52, 52, 4, 12)
.resize(size/4, size*3/4, Jimp.RESIZE_NEAREST_NEIGHBOR);
body.composite(rightArmOverlay, size*3/4, size/2);
}
Rendering Order
Parts are composited in this sequence:
- Head (base)
- Head overlay (if hat)
- Torso (base)
- Torso overlay (if hat)
- Left arm (base)
- Left arm overlay (if hat)
- Right arm (base, from new format or flipped)
- Right arm overlay (if hat and new format)
- Left leg (base)
- Left leg overlay (if hat)
- Right leg (base, from new format or flipped)
- Right leg overlay (if hat and new format)
The order matters because later composites draw over earlier ones. Arms and legs
are drawn after the torso so their edges overlap the torso boundary correctly.
Output
The function returns a PNG buffer via body.getBufferAsync(Jimp.MIME_PNG). The
output dimensions are always size x (size * 2) pixels. For the default size
of 128, that produces a 128x256 pixel image.
Endpoint
GET /player/:input/:size?/:option?
input-- username, UUID, or Bedrock identifier.size-- width in pixels (default 128). Height is always 2x the width.option-- passhatto include overlay layers.
Route defined in routes/player.js, calls createBodyRender inutils/imageProcessor.js.