Skip to content

Instantly share code, notes, and snippets.

@msjyoo
Created July 24, 2015 12:55
Show Gist options
  • Save msjyoo/762dbcef367dd01e2b8e to your computer and use it in GitHub Desktop.
Save msjyoo/762dbcef367dd01e2b8e to your computer and use it in GitHub Desktop.
A quick gist because this wasn't documented anywher else. How to render and make sense of the MCPE / PocketMine Skin Data

How to use

Basically, this file will take in a binary file of skin.dat and export 3 files: image.png is the skin file, face.png is the face in original size, faceLarge.png is the face in 512x512.

Only supports 64x64 skins for now. If you want 32x64 make appropriate checks.

The PocketMine's (MCPE's) Skin Data Format is in RGBA format, when represented as hex strings they are a stream of 8 characters. Each two characters represent the R, G, B A, and this continues until you have enough data for either a 32x64 image or a 64x64 image. You can also check whether 32x or 64x with the isSlimSkin() flag on the Player object.

Note that A only has 2 values: 0 and 255. They are inverted in the script because PHP.

Don't ask me if you have any questions because I can't help you.

<?php
$skinData = bin2hex($file = file_get_contents("skin.dat"));
$height = 64;
$width = 64;
$image = imagecreatetruecolor($width, $height);
imagealphablending($image, false);
imagesavealpha($image, true);
$imgPointer = 0;
for($y = 1; $y <= $height; $y++)
{
for($x = 1; $x <= $width; $x++)
{
$pixel = substr($skinData, ($imgPointer++*8), 8);
$r = hexdec(substr($pixel, 0, 2));
$g = hexdec(substr($pixel, 2, 2));
$b = hexdec(substr($pixel, 4, 2));
$a = hexdec(substr($pixel, 6, 2));
if($a === 255)
{
$a = 0; // Opaque
}
else if($a === 0)
{
$a = 127; // Transparent
}
else
{
echo "Alpha value apart from 0 and 255 detected!\n";
exit(1);
}
$c = imagecolorallocatealpha($image, $r, $g, $b, $a);
echo "y:$y x:$x color(RGBA):$pixel r:$r g:$g b:$b a:$a c:$c\n";
if($c === false or imagesetpixel($image, $x, $y, $c) === false)
{
echo "Error during imagecolorallocatealpha or imagesetpixel!\n";
exit(1);
}
}
}
echo "Complete! Binary size:".strlen($file)." Hex size:".strlen($skinData)."\n";
imagepng($image, "image.png");
echo "Cropping face...";
$imageFace = imagecreatetruecolor(8, 8);
imagealphablending($imageFace, false);
imagesavealpha($imageFace, true);
if(!imagecopy(
$imageFace,
$image,
0,
0,
9,
9,
8,
8
))
{
echo "Error during imagecopy!\n";
exit(1);
}
imagepng($imageFace, "face.png");
echo "done.\n";
echo "Resizing face large...";
$imageFaceL = imagecreatetruecolor(512, 512);
imagealphablending($imageFaceL, false);
imagesavealpha($imageFaceL, true);
if(!imagecopyresampled(
$imageFaceL,
$imageFace,
0,
0,
0,
0,
512,
512,
8,
8
))
{
echo "Error during imagecopy!\n";
exit(1);
}
imagepng($imageFaceL, "faceLarge.png");
echo "done.\n";
exit;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment