Merge pull request #2586 from ExerciseBook/v3.0

HD skins support
This commit is contained in:
mikeprimm 2019-12-15 00:39:51 -06:00 committed by GitHub
commit 3eebde9170
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -11,6 +11,7 @@ import org.dynmap.utils.DynmapBufferedImage;
import org.dynmap.utils.ImageIOManager;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
@ -96,6 +97,13 @@ public class PlayerFaces {
}
}
}
private void copyLayersToTarget(BufferedImage srcimg, int layer1x, int layer1y, int layer2x, int layer2y, int w, int h, BufferedImage dest, int destoff, int destscansize)
{
int[] tmp = new int[w*h];
copyLayersToTarget(srcimg,layer1x,layer1y,layer2x,layer2y,w,h,tmp,0,w);
dest.setRGB(0,0,w,h,tmp,destoff,destscansize);
}
private class LoadPlayerImages implements Runnable {
public final String playername;
@ -145,14 +153,24 @@ public class PlayerFaces {
img.flush();
return;
}
else if(img.getHeight() == 32) {
else if( (img.getWidth() / img.getHeight()) == 2 ) { /* Is single layer skin? */
is_64x32_skin = true;
}
/* Get buffered image for face at original size */
int scale = img.getWidth()/8 /8;
BufferedImage faceOriginal = new BufferedImage(8*scale, 8*scale, BufferedImage.TYPE_INT_ARGB);
// Copy face and overlay to icon
copyLayersToTarget(img, 8*scale, 8*scale, 40*scale, 8*scale, 8*scale, 8*scale, faceOriginal, 0, 8*scale);
int[] faceaccessory = new int[64]; /* 8x8 of face accessory */
/* Get buffered image for face at 8x8 */
DynmapBufferedImage face8x8 = DynmapBufferedImage.allocateBufferedImage(8, 8);
// Copy face and overlay to icon
copyLayersToTarget(img, 8, 8, 40, 8, 8, 8, face8x8.argb_buf, 0, 8);
Image face8x8_image = faceOriginal.getScaledInstance(8,8,BufferedImage.SCALE_SMOOTH);
BufferedImage face8x8_buff = new BufferedImage(8, 8, BufferedImage.TYPE_INT_ARGB);
face8x8_buff.getGraphics().drawImage(face8x8_image,0,0,null);
face8x8_buff.getRGB(0,0,8,8,face8x8.argb_buf,0,8);
/* Write 8x8 file */
if(refreshskins || (!has_8x8)) {
BufferOutputStream bos = ImageIOManager.imageIOEncode(face8x8.buf_img, ImageFormat.FORMAT_PNG);
@ -164,36 +182,60 @@ public class PlayerFaces {
if(refreshskins || (!has_16x16)) {
/* Make 16x16 version */
DynmapBufferedImage face16x16 = DynmapBufferedImage.allocateBufferedImage(16, 16);
for(int i = 0; i < 16; i++) {
for(int j = 0; j < 16; j++) {
face16x16.argb_buf[i*16+j] = face8x8.argb_buf[(i/2)*8 + (j/2)];
}
}
Image face16x16_image = faceOriginal.getScaledInstance(16,16,BufferedImage.SCALE_SMOOTH);
BufferedImage face16x16_buff = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
face16x16_buff.getGraphics().drawImage(face16x16_image,0,0,null);
face16x16_buff.getRGB(0,0,16,16,face16x16.argb_buf,0,16);
BufferOutputStream bos = ImageIOManager.imageIOEncode(face16x16.buf_img, ImageFormat.FORMAT_PNG);
if (bos != null) {
storage.setPlayerFaceImage(playername, FaceType.FACE_16X16, bos);
}
DynmapBufferedImage.freeBufferedImage(face16x16);
face16x16_buff.flush();
}
/* Write 32x32 file */
if(refreshskins || (!has_32x32)) {
/* Make 32x32 version */
DynmapBufferedImage face32x32 = DynmapBufferedImage.allocateBufferedImage(32, 32);
for(int i = 0; i < 32; i++) {
for(int j = 0; j < 32; j++) {
face32x32.argb_buf[i*32+j] = face8x8.argb_buf[(i/4)*8 + (j/4)];
}
}
Image face32x32_image = faceOriginal.getScaledInstance(32,32,BufferedImage.SCALE_SMOOTH);
BufferedImage face32x32_buff = new BufferedImage(32, 32, BufferedImage.TYPE_INT_ARGB);
face32x32_buff.getGraphics().drawImage(face32x32_image,0,0,null);
face32x32_buff.getRGB(0,0,32,32,face32x32.argb_buf,0,32);
BufferOutputStream bos = ImageIOManager.imageIOEncode(face32x32.buf_img, ImageFormat.FORMAT_PNG);
if (bos != null) {
storage.setPlayerFaceImage(playername, FaceType.FACE_32X32, bos);
}
DynmapBufferedImage.freeBufferedImage(face32x32);
face32x32_buff.flush();
}
/* Write body file */
if(refreshskins || (!has_body)) {
Image skin_image = null;
BufferedImage skin_buff = null;
if (is_64x32_skin){
skin_image = img.getScaledInstance(64,32,BufferedImage.SCALE_SMOOTH);
skin_buff = new BufferedImage(64, 32, BufferedImage.TYPE_INT_ARGB);
skin_buff.getGraphics().drawImage(skin_image,0,0,null);
} else {
skin_image = img.getScaledInstance(64,64,BufferedImage.SCALE_SMOOTH);
skin_buff = new BufferedImage(64, 64, BufferedImage.TYPE_INT_ARGB);
skin_buff.getGraphics().drawImage(skin_image,0,0,null);
}
/* Make 32x32 version */
DynmapBufferedImage body32x32 = DynmapBufferedImage.allocateBufferedImage(32, 32);
/* Copy face at 12,0 to 20,8 (already handled accessory) */
@ -203,34 +245,38 @@ public class PlayerFaces {
}
}
/* Copy body at 20,20 and chest at 20,36 to 8,12 */
copyLayersToTarget(img, 20, 20, 20, 36, 8, 12, body32x32.argb_buf, 8*32+12, 32);
copyLayersToTarget(skin_buff, 20, 20, 20, 36, 8, 12, body32x32.argb_buf, 8*32+12, 32);
/* Copy right leg at 4,20 and 4,36 to 20,12 */
copyLayersToTarget(img, 4, 20, 4, 36, 4, 12, body32x32.argb_buf, 20*32+12, 32);
copyLayersToTarget(skin_buff, 4, 20, 4, 36, 4, 12, body32x32.argb_buf, 20*32+12, 32);
/* Copy left leg at 4,20 if old format or 20,52 and 4,53 to 20,16 */
if(is_64x32_skin) {
img.getRGB(4, 20, 4, 12, body32x32.argb_buf, 20*32+16, 32);
skin_buff.getRGB(4, 20, 4, 12, body32x32.argb_buf, 20*32+16, 32);
}
else {
copyLayersToTarget(img, 20, 52, 4, 52, 4, 12, body32x32.argb_buf, 20 * 32 + 16, 32);
copyLayersToTarget(skin_buff, 20, 52, 4, 52, 4, 12, body32x32.argb_buf, 20 * 32 + 16, 32);
}
/* Copy right arm at 44,20 and 44,36 to 8,8 */
copyLayersToTarget(img, 44, 20, 44, 36, 4, 12, body32x32.argb_buf, 8*32+8, 32);
copyLayersToTarget(skin_buff, 44, 20, 44, 36, 4, 12, body32x32.argb_buf, 8*32+8, 32);
/* Copy left arm at 44,20 if old format or 36,52 and 52,52 to 8,20 */
if(is_64x32_skin) {
img.getRGB(44, 20, 4, 12, body32x32.argb_buf, 8*32+20, 32);
skin_buff.getRGB(44, 20, 4, 12, body32x32.argb_buf, 8*32+20, 32);
}
else {
copyLayersToTarget(img, 36, 52, 52, 52, 4, 12, body32x32.argb_buf, 8 * 32 + 20, 32);
copyLayersToTarget(skin_buff, 36, 52, 52, 52, 4, 12, body32x32.argb_buf, 8 * 32 + 20, 32);
}
BufferOutputStream bos = ImageIOManager.imageIOEncode(body32x32.buf_img, ImageFormat.FORMAT_PNG);
if (bos != null) {
storage.setPlayerFaceImage(playername, FaceType.BODY_32X32, bos);
}
DynmapBufferedImage.freeBufferedImage(body32x32);
skin_buff.flush();
}
DynmapBufferedImage.freeBufferedImage(face8x8);
face8x8_buff.flush();
faceOriginal.flush();
img.flush();
}
}