Skip to content

Instantly share code, notes, and snippets.

@Mystiflow
Last active January 1, 2023 23:33
Show Gist options
  • Save Mystiflow/c42f45bac9916c84e381155f72a96d84 to your computer and use it in GitHub Desktop.
Save Mystiflow/c42f45bac9916c84e381155f72a96d84 to your computer and use it in GitHub Desktop.
Convert range of colors to a traditional Minecraft Chat Color Pre 1.16
package io.mystiflow;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
import java.awt.*;
import net.md_5.bungee.api.ChatColor;
import org.junit.Assert;
import org.junit.Test;
import java.util.Map;
import java.util.Set;
public class ColorTest {
// List of ChatColor's to not process
private static final Set<ChatColor> STYLE_COLORS;
// Mapping of Spigot ChatColor to appropriate Java Color
private static final Map<ChatColor, Color> COLOR_MAPPINGS;
static {
STYLE_COLORS = Sets.immutableEnumSet(
ChatColor.BOLD,
ChatColor.UNDERLINE,
ChatColor.STRIKETHROUGH,
ChatColor.RESET,
ChatColor.ITALIC,
ChatColor.MAGIC
);
// https://minecraft.gamepedia.com/Formatting_codes#Color_codes
COLOR_MAPPINGS = ImmutableMap.<ChatColor, Color>builder()
.put(ChatColor.BLACK, new Color(0, 0, 0))
.put(ChatColor.DARK_BLUE, new Color(0, 0, 170))
.put(ChatColor.DARK_GREEN, new Color(0, 170, 0))
.put(ChatColor.DARK_AQUA, new Color(0, 170, 170))
.put(ChatColor.DARK_RED, new Color(170, 0, 0))
.put(ChatColor.DARK_PURPLE, new Color(170, 0, 170))
.put(ChatColor.GOLD, new Color(255, 170, 0))
.put(ChatColor.GRAY, new Color(170, 170, 170))
.put(ChatColor.DARK_GRAY, new Color(85, 85, 85))
.put(ChatColor.BLUE, new Color(85, 85, 255))
.put(ChatColor.GREEN, new Color(85, 255, 85))
.put(ChatColor.AQUA, new Color(85, 255, 255))
.put(ChatColor.RED, new Color(255, 85, 85))
.put(ChatColor.LIGHT_PURPLE, new Color(255, 85, 255))
.put(ChatColor.YELLOW, new Color(255, 255, 85))
.put(ChatColor.WHITE, new Color(255, 255, 255))
.build();
}
public static String rgbToHex(int rgb) {
return Integer.toHexString(rgb).substring(2);
}
public static int hexToRgb(String hex) {
return Integer.valueOf(hex, 16);
}
public static int getRgb(int red, int green, int blue) {
return new Color(red, green, blue).getRGB();
}
public static String formattedRgb(Color color) {
return "(" + color.getRed() + ", " + color.getGreen() + ", " + color.getBlue() + ")";
}
@Test
public void testColorMatching() {
for (ChatColor chatColor : ChatColor.values()) {
if (STYLE_COLORS.contains(chatColor)) continue;
Color color = COLOR_MAPPINGS.get(chatColor);
Assert.assertEquals(getClosestChatColor(color), chatColor);
// Test with slightly mutated colors
Assert.assertEquals(chatColor,
getClosestChatColor(new Color(Math.min(255, color.getRed() + 10), color.getGreen(), color.getBlue())));
Assert.assertNotEquals(chatColor,
getClosestChatColor(new Color(color.getRed(), (color.getGreen() < 128) ? 255 : 0, color.getBlue())));
Assert.assertEquals(chatColor,
getClosestChatColor(new Color(color.getRed(), color.getGreen(), Math.max(0, color.getBlue() - 10))));
}
// General color match testing
String hex = "9F34BA";
System.out.println("Closest color for (" + hex + ") = " + getClosestChatColor(new Color(hexToRgb(hex))).getName());
}
private static ChatColor getClosestChatColor(Color color) {
ChatColor closest = null;
int mark = 0;
for (Map.Entry<ChatColor, Color> entry : COLOR_MAPPINGS.entrySet()) {
ChatColor key = entry.getKey();
Color value = entry.getValue();
int diff = getDiff(value, color);
if (closest == null || diff < mark) {
closest = key;
mark = diff;
}
}
return closest;
}
// Algorithm to determine the difference between two colors, source:
// https://stackoverflow.com/questions/27374550/how-to-compare-color-object-and-get-closest-color-in-an-color
private static int getDiff(Color color, Color compare) {
int a = color.getAlpha() - compare.getAlpha(),
r = color.getRed() - compare.getRed(),
g = color.getGreen() - compare.getGreen(),
b = color.getBlue() - compare.getBlue();
return a * a + r * r + g * g + b * b;
}
}
@MightyCoderX
Copy link

Thanks for your effort, i took a part of it and it works perfectly! 🙂

@yvesnormand
Copy link

Thanks for the work

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment