001 package org.bukkit.map; 002 003 import java.awt.Color; 004 import java.awt.Graphics2D; 005 import java.awt.Image; 006 import java.awt.image.BufferedImage; 007 008 /** 009 * Represents the palette that map items use. 010 * <p> 011 * These fields are hee base color ranges. Each entry corresponds to four 012 * colors of varying shades with values entry to entry + 3. 013 */ 014 public final class MapPalette { 015 // Internal mechanisms 016 private MapPalette() {} 017 018 private static Color c(int r, int g, int b) { 019 return new Color(r, g, b); 020 } 021 022 private static double getDistance(Color c1, Color c2) { 023 double rmean = (c1.getRed() + c2.getRed()) / 2.0; 024 double r = c1.getRed() - c2.getRed(); 025 double g = c1.getGreen() - c2.getGreen(); 026 int b = c1.getBlue() - c2.getBlue(); 027 double weightR = 2 + rmean / 256.0; 028 double weightG = 4.0; 029 double weightB = 2 + (255 - rmean) / 256.0; 030 return weightR * r * r + weightG * g * g + weightB * b * b; 031 } 032 033 private static final Color[] colors = { 034 new Color(0, 0, 0, 0), new Color(0, 0, 0, 0), 035 new Color(0, 0, 0, 0), new Color(0, 0, 0, 0), 036 c(89, 125, 39), c(109, 153, 48), c(127, 178, 56), c(67, 94, 29), 037 c(174, 164, 115), c(213, 201, 140), c(247, 233, 163), c(130, 123, 86), 038 c(117, 117, 117), c(144, 144, 144), c(167, 167, 167), c(88, 88, 88), 039 c(180, 0, 0), c(220, 0, 0), c(255, 0, 0), c(135, 0, 0), 040 c(112, 112, 180), c(138, 138, 220), c(160, 160, 255), c(84, 84, 135), 041 c(117, 117, 117), c(144, 144, 144), c(167, 167, 167), c(88, 88, 88), 042 c(0, 87, 0), c(0, 106, 0), c(0, 124, 0), c(0, 65, 0), 043 c(180, 180, 180), c(220, 220, 220), c(255, 255, 255), c(135, 135, 135), 044 c(115, 118, 129), c(141, 144, 158), c(164, 168, 184), c(86, 88, 97), 045 c(129, 74, 33), c(157, 91, 40), c(183, 106, 47), c(96, 56, 24), 046 c(79, 79, 79), c(96, 96, 96), c(112, 112, 112), c(59, 59, 59), 047 c(45, 45, 180), c(55, 55, 220), c(64, 64, 255), c(33, 33, 135), 048 c(73, 58, 35), c(89, 71, 43), c(104, 83, 50), c(55, 43, 26), 049 c(180, 177, 172), c(220, 217, 211), c(255, 252, 245), c(135, 133, 129), 050 c(152, 89, 36), c(186, 109, 44), c(216, 127, 51), c(114, 67, 27), 051 c(125, 53, 152), c(153, 65, 186), c(178, 76, 216), c(94, 40, 114), 052 c(72, 108, 152), c(88, 132, 186), c(102, 153, 216), c(54, 81, 114), 053 c(161, 161, 36), c(197, 197, 44), c(229, 229, 51), c(121, 121, 27), 054 c(89, 144, 17), c(109, 176, 21), c(127, 204, 25), c(67, 108, 13), 055 c(170, 89, 116), c(208, 109, 142), c(242, 127, 165), c(128, 67, 87), 056 c(53, 53, 53), c(65, 65, 65), c(76, 76, 76), c(40, 40, 40), 057 c(108, 108, 108), c(132, 132, 132), c(153, 153, 153), c(81, 81, 81), 058 c(53, 89, 108), c(65, 109, 132), c(76, 127, 153), c(40, 67, 81), 059 c(89, 44, 125), c(109, 54, 153), c(127, 63, 178), c(67, 33, 94), 060 c(36, 53, 125), c(44, 65, 153), c(51, 76, 178), c(27, 40, 94), 061 c(72, 53, 36), c(88, 65, 44), c(102, 76, 51), c(54, 40, 27), 062 c(72, 89, 36), c(88, 109, 44), c(102, 127, 51), c(54, 67, 27), 063 c(108, 36, 36), c(132, 44, 44), c(153, 51, 51), c(81, 27, 27), 064 c(17, 17, 17), c(21, 21, 21), c(25, 25, 25), c(13, 13, 13), 065 c(176, 168, 54), c(215, 205, 66), c(250, 238, 77), c(132, 126, 40), 066 c(64, 154, 150), c(79, 188, 183), c(92, 219, 213), c(48, 115, 112), 067 c(52, 90, 180), c(63, 110, 220), c(74, 128, 255), c(39, 67, 135), 068 c(0, 153, 40), c(0, 187, 50), c(0, 217, 58), c(0, 114, 30), 069 c(14, 14, 21), c(18, 17, 26), c(21, 20, 31), c(11, 10, 16), 070 c(79, 1, 0), c(96, 1, 0), c(112, 2, 0), c(59, 1, 0) 071 }; 072 073 // Interface 074 /** 075 * @deprecated Magic value 076 */ 077 @Deprecated 078 public static final byte TRANSPARENT = 0; 079 /** 080 * @deprecated Magic value 081 */ 082 @Deprecated 083 public static final byte LIGHT_GREEN = 4; 084 /** 085 * @deprecated Magic value 086 */ 087 @Deprecated 088 public static final byte LIGHT_BROWN = 8; 089 /** 090 * @deprecated Magic value 091 */ 092 @Deprecated 093 public static final byte GRAY_1 = 12; 094 /** 095 * @deprecated Magic value 096 */ 097 @Deprecated 098 public static final byte RED = 16; 099 /** 100 * @deprecated Magic value 101 */ 102 @Deprecated 103 public static final byte PALE_BLUE = 20; 104 /** 105 * @deprecated Magic value 106 */ 107 @Deprecated 108 public static final byte GRAY_2 = 24; 109 /** 110 * @deprecated Magic value 111 */ 112 @Deprecated 113 public static final byte DARK_GREEN = 28; 114 /** 115 * @deprecated Magic value 116 */ 117 @Deprecated 118 public static final byte WHITE = 32; 119 /** 120 * @deprecated Magic value 121 */ 122 @Deprecated 123 public static final byte LIGHT_GRAY = 36; 124 /** 125 * @deprecated Magic value 126 */ 127 @Deprecated 128 public static final byte BROWN = 40; 129 /** 130 * @deprecated Magic value 131 */ 132 @Deprecated 133 public static final byte DARK_GRAY = 44; 134 /** 135 * @deprecated Magic value 136 */ 137 @Deprecated 138 public static final byte BLUE = 48; 139 /** 140 * @deprecated Magic value 141 */ 142 @Deprecated 143 public static final byte DARK_BROWN = 52; 144 145 /** 146 * Resize an image to 128x128. 147 * 148 * @param image The image to resize. 149 * @return The resized image. 150 */ 151 public static BufferedImage resizeImage(Image image) { 152 BufferedImage result = new BufferedImage(128, 128, BufferedImage.TYPE_INT_ARGB); 153 Graphics2D graphics = result.createGraphics(); 154 graphics.drawImage(image, 0, 0, 128, 128, null); 155 graphics.dispose(); 156 return result; 157 } 158 159 /** 160 * Convert an Image to a byte[] using the palette. 161 * 162 * @param image The image to convert. 163 * @return A byte[] containing the pixels of the image. 164 * @deprecated Magic value 165 */ 166 @Deprecated 167 public static byte[] imageToBytes(Image image) { 168 BufferedImage temp = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB); 169 Graphics2D graphics = temp.createGraphics(); 170 graphics.drawImage(image, 0, 0, null); 171 graphics.dispose(); 172 173 int[] pixels = new int[temp.getWidth() * temp.getHeight()]; 174 temp.getRGB(0, 0, temp.getWidth(), temp.getHeight(), pixels, 0, temp.getWidth()); 175 176 byte[] result = new byte[temp.getWidth() * temp.getHeight()]; 177 for (int i = 0; i < pixels.length; i++) { 178 result[i] = matchColor(new Color(pixels[i], true)); 179 } 180 return result; 181 } 182 183 /** 184 * Get the index of the closest matching color in the palette to the given 185 * color. 186 * 187 * @param r The red component of the color. 188 * @param b The blue component of the color. 189 * @param g The green component of the color. 190 * @return The index in the palette. 191 * @deprecated Magic value 192 */ 193 @Deprecated 194 public static byte matchColor(int r, int g, int b) { 195 return matchColor(new Color(r, g, b)); 196 } 197 198 /** 199 * Get the index of the closest matching color in the palette to the given 200 * color. 201 * 202 * @param color The Color to match. 203 * @return The index in the palette. 204 * @deprecated Magic value 205 */ 206 @Deprecated 207 public static byte matchColor(Color color) { 208 if (color.getAlpha() < 128) return 0; 209 210 int index = 0; 211 double best = -1; 212 213 for (int i = 4; i < colors.length; i++) { 214 double distance = getDistance(color, colors[i]); 215 if (distance < best || best == -1) { 216 best = distance; 217 index = i; 218 } 219 } 220 221 // Minecraft has 143 colors, some of which have negative byte representations 222 return (byte) (index < 128 ? index : -129 + (index - 127)); 223 } 224 225 /** 226 * Get the value of the given color in the palette. 227 * 228 * @param index The index in the palette. 229 * @return The Color of the palette entry. 230 * @deprecated Magic value 231 */ 232 @Deprecated 233 public static Color getColor(byte index) { 234 if ((index > -113 && index < 0) || index > 127) { 235 throw new IndexOutOfBoundsException(); 236 } else { 237 // Minecraft has 143 colors, some of which have negative byte representations 238 return colors[index >= 0 ? index : index + 256]; 239 } 240 } 241 }