diff --git a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/map/TextureGallery.java b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/map/TextureGallery.java index f1e4426e..d879a8d2 100644 --- a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/map/TextureGallery.java +++ b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/map/TextureGallery.java @@ -30,10 +30,12 @@ import de.bluecolored.bluemap.core.resources.ResourcePath; import de.bluecolored.bluemap.core.resources.adapter.ResourcesGson; import de.bluecolored.bluemap.core.resources.resourcepack.ResourcePack; import de.bluecolored.bluemap.core.resources.resourcepack.texture.Texture; +import de.bluecolored.bluemap.core.util.Key; import org.jetbrains.annotations.Nullable; import java.io.*; import java.util.Arrays; +import java.util.Comparator; import java.util.HashMap; import java.util.Map; @@ -66,7 +68,10 @@ public class TextureGallery { } public synchronized void put(ResourcePack resourcePack) { - resourcePack.getTextures().keySet().forEach(this::put); + resourcePack.getTextures().keySet() + .stream() + .sorted(Comparator.comparing(Key::getFormatted)) + .forEach(this::put); } public void writeTexturesFile(ResourcePack resourcePack, OutputStream out) throws IOException { @@ -98,7 +103,7 @@ public class TextureGallery { for (int ordinal = 0; ordinal < textures.length; ordinal++) { Texture texture = textures[ordinal]; if (texture != null) { - gallery.ordinalMap.put(textures[ordinal].getResourcePath(), ordinal); + gallery.ordinalMap.put(texture.getResourcePath(), ordinal); } } } catch (JsonIOException ex) { diff --git a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/resources/resourcepack/texture/Texture.java b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/resources/resourcepack/texture/Texture.java index 5061ff05..6acb696f 100644 --- a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/resources/resourcepack/texture/Texture.java +++ b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/resources/resourcepack/texture/Texture.java @@ -26,6 +26,7 @@ package de.bluecolored.bluemap.core.resources.resourcepack.texture; import de.bluecolored.bluemap.api.debug.DebugDump; import de.bluecolored.bluemap.core.resources.ResourcePath; +import de.bluecolored.bluemap.core.util.BufferedImageUtil; import de.bluecolored.bluemap.core.util.math.Color; import javax.imageio.ImageIO; @@ -112,7 +113,7 @@ public class Texture { boolean halfTransparent = checkHalfTransparent(image); //calculate color - Color color = calculateColor(image); + Color color = BufferedImageUtil.averageColor(image); //write to Base64 ByteArrayOutputStream os = new ByteArrayOutputStream(); @@ -136,36 +137,6 @@ public class Texture { return false; } - private static Color calculateColor(BufferedImage image){ - float alpha = 0f, red = 0f, green = 0f, blue = 0f; - int count = 0; - - for (int x = 0; x < image.getWidth(); x++){ - for (int y = 0; y < image.getHeight(); y++){ - int pixel = image.getRGB(x, y); - float pixelAlpha = ((pixel >> 24) & 0xff) / 255f; - float pixelRed = ((pixel >> 16) & 0xff) / 255f; - float pixelGreen = ((pixel >> 8) & 0xff) / 255f; - float pixelBlue = (pixel & 0xff) / 255f; - - count++; - alpha += pixelAlpha; - red += pixelRed * pixelAlpha; - green += pixelGreen * pixelAlpha; - blue += pixelBlue * pixelAlpha; - } - } - - if (count == 0 || alpha == 0) return new Color(); - - red /= alpha; - green /= alpha; - blue /= alpha; - alpha /= count; - - return new Color().set(red, green, blue, alpha, false); - } - public static Texture missing(ResourcePath resourcePath) { return new Texture(resourcePath); } diff --git a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/util/BufferedImageUtil.java b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/util/BufferedImageUtil.java new file mode 100644 index 00000000..bdfb8ea6 --- /dev/null +++ b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/util/BufferedImageUtil.java @@ -0,0 +1,63 @@ +package de.bluecolored.bluemap.core.util; + +import de.bluecolored.bluemap.core.util.math.Color; +import org.jetbrains.annotations.Nullable; + +import java.awt.image.BufferedImage; +import java.awt.image.RenderedImage; + +public class BufferedImageUtil { + + public static Color averageColor(BufferedImage image) { + Color average = new Color(); + Color color = new Color(); + float[] buffer = null; + int count = 0; + for (int x = 0; x < image.getWidth(); x++) { + for (int y = 0; y < image.getHeight(); y++) { + buffer = readPixel(image, x, y, color, buffer); + + count++; + average.add(color.premultiplied()); + } + } + average.div(count); + return average; + } + + public static Color readPixel(BufferedImage image, int x, int y, @Nullable Color target) { + readPixel(image, x, y, target, null); + return target; + } + + private static float[] readPixel(BufferedImage image, int x, int y, @Nullable Color target, float @Nullable [] buffer) { + if (target == null) target = new Color(); + + // workaround for java bug: 5051418 + if (image.getType() == BufferedImage.TYPE_BYTE_GRAY) { + buffer = readPixelDirect(image, x, y, target, buffer); + } else { + readPixelDefault(image, x, y, target); + } + + return buffer; + } + + private static void readPixelDefault(BufferedImage image, int x, int y, Color target) { + target.set(image.getRGB(x, y), image.getColorModel().isAlphaPremultiplied()); + } + + private static float[] readPixelDirect(RenderedImage image, int x, int y, Color target, float @Nullable [] buffer) { + buffer = image.getData().getPixel(x, y, buffer); + + float a = buffer.length >= 4 ? buffer[3] / 255f : 1f; + float r = buffer[0] / 255f; + float g = buffer.length >= 3 ? buffer[1] / 255f : r; + float b = buffer.length >= 3 ? buffer[2] / 255f : r; + + target.set(r, g, b, a, image.getColorModel().isAlphaPremultiplied()); + + return buffer; + } + +} diff --git a/BlueMapCore/src/main/resourceExtensions/mc1_18/assets/minecraft/blockColors.json b/BlueMapCore/src/main/resourceExtensions/mc1_18/assets/minecraft/blockColors.json index e4a8a397..f948d075 100644 --- a/BlueMapCore/src/main/resourceExtensions/mc1_18/assets/minecraft/blockColors.json +++ b/BlueMapCore/src/main/resourceExtensions/mc1_18/assets/minecraft/blockColors.json @@ -7,6 +7,7 @@ "minecraft:lava_cauldron": "#ffffff", "minecraft:grass_block": "@grass", "minecraft:grass": "@grass", + "minecraft:short_grass": "@grass", "minecraft:tall_grass": "@grass", "minecraft:fern": "@grass", "minecraft:large_fern": "@grass", diff --git a/BlueMapCore/src/main/resourceExtensions/mc1_18/assets/minecraft/blockProperties.json b/BlueMapCore/src/main/resourceExtensions/mc1_18/assets/minecraft/blockProperties.json index d319683a..1062822c 100644 --- a/BlueMapCore/src/main/resourceExtensions/mc1_18/assets/minecraft/blockProperties.json +++ b/BlueMapCore/src/main/resourceExtensions/mc1_18/assets/minecraft/blockProperties.json @@ -6,6 +6,7 @@ "minecraft:bubble_column": { "alwaysWaterlogged": true }, "minecraft:grass": { "randomOffset": true }, + "minecraft:short_grass": { "randomOffset": true }, "minecraft:tall_grass": { "randomOffset": true }, "minecraft:fern": { "randomOffset": true }, "minecraft:dandelion": { "randomOffset": true },