@@ -31,21 +31,10 @@ public class MapRenderer {
3131 public static CanvasImage render (BufferedImage image , DitherMode mode , int width , int height ) {
3232 Image resizedImage = image .getScaledInstance (width , height , Image .SCALE_DEFAULT );
3333 BufferedImage resized = convertToBufferedImage (resizedImage );
34- int [][] pixels = convertPixelArray (resized );
35-
36- var state = new CanvasImage (width , height );
37-
38- for (int i = 0 ; i < width ; i ++) {
39- for (int j = 0 ; j < height ; j ++) {
40- if (mode .equals (DitherMode .FLOYD )) {
41- state .set (i , j , floydDither (pixels , i , j , pixels [j ][i ]));
42- } else {
43- state .set (i , j , CanvasUtils .findClosestColorARGB (pixels [j ][i ]));
44- }
45- }
46- }
47-
48- return state ;
34+ return switch (mode ) {
35+ case NONE -> CanvasImage .from (resized );
36+ case FLOYD -> CanvasImage .fromWithFloydSteinbergDither (resized );
37+ };
4938 }
5039
5140 public static List <ItemStack > toVanillaItems (CanvasImage image , ServerLevel world , String url ) {
@@ -90,111 +79,6 @@ public static List<ItemStack> toVanillaItems(CanvasImage image, ServerLevel worl
9079 return items ;
9180 }
9281
93- /*public static ItemStack render(BufferedImage image, DitherMode mode, ServerWorld world, int width, int height,
94- PlayerEntity player) {
95- // mojang removed the ability to set a map as locked via the "locked" field in
96- // 1.17, so we create and apply our own MapState instead
97- ItemStack stack = new ItemStack(Items.FILLED_MAP);
98- int id = world.getNextMapId();
99- NbtCompound nbt = new NbtCompound();
100-
101- nbt.putString("dimension", world.getRegistryKey().getValue().toString());
102- nbt.putInt("xCenter", (int) 0);
103- nbt.putInt("zCenter", (int) 0);
104- nbt.putBoolean("locked", true);
105- nbt.putBoolean("unlimitedTracking", false);
106- nbt.putBoolean("trackingPosition", false);
107- nbt.putByte("scale", (byte) 3);
108- MapState state = MapState.fromNbt(nbt);
109- world.putMapState(FilledMapItem.getMapName(id), state);
110- stack.getOrCreateNbt().putInt("map", id);
111-
112- Image resizedImage = image.getScaledInstance(128, 128, Image.SCALE_DEFAULT);
113- BufferedImage resized = convertToBufferedImage(resizedImage);
114- int width = resized.getWidth();
115- int height = resized.getHeight();
116- int[][] pixels = convertPixelArray(resized);
117- MapColor[] mapColors = MapColor.COLORS;
118- Color imageColor;
119- mapColors = Arrays.stream(mapColors).filter(Objects::nonNull).toArray(MapColor[]::new);
120-
121- for (int i = 0; i < width; i++) {
122- for (int j = 0; j < height; j++) {
123- imageColor = new Color(pixels[j][i], true);
124- if (mode.equals(DitherMode.FLOYD))
125- state.colors[i + j * width] = (byte) floydDither(mapColors, pixels, i, j, imageColor);
126- else
127- state.colors[i + j * width] = (byte) nearestColor(mapColors, imageColor);
128- }
129- }
130- return stack;
131- }*/
132-
133- private static CanvasColor floydDither (int [][] pixels , int x , int y , int imageColor ) {
134- var closestColor = CanvasUtils .findClosestColorARGB (imageColor );
135- var palletedColor = closestColor .getRgbColor ();
136-
137- var errorR = ARGB .red (imageColor ) - ARGB .red (palletedColor );
138- var errorG = ARGB .green (imageColor ) - ARGB .green (palletedColor );
139- var errorB = ARGB .blue (imageColor ) - ARGB .blue (palletedColor );
140- if (pixels [0 ].length > x + 1 ) {
141- pixels [y ][x + 1 ] = applyError (pixels [y ][x + 1 ], errorR , errorG , errorB , 7.0 / 16.0 );
142- }
143- if (pixels .length > y + 1 ) {
144- if (x > 0 ) {
145- pixels [y + 1 ][x - 1 ] = applyError (pixels [y + 1 ][x - 1 ], errorR , errorG , errorB , 3.0 / 16.0 );
146- }
147- pixels [y + 1 ][x ] = applyError (pixels [y + 1 ][x ], errorR , errorG , errorB , 5.0 / 16.0 );
148- if (pixels [0 ].length > x + 1 ) {
149- pixels [y + 1 ][x + 1 ] = applyError (pixels [y + 1 ][x + 1 ], errorR , errorG , errorB , 1.0 / 16.0 );
150- }
151- }
152-
153- return closestColor ;
154- }
155-
156- private static int applyError (int pixelColor , int errorR , int errorG , int errorB , double quantConst ) {
157- int pR = clamp ( ARGB .red (pixelColor ) + (int ) ((double ) errorR * quantConst ), 0 , 255 );
158- int pG = clamp (ARGB .green (pixelColor ) + (int ) ((double ) errorG * quantConst ), 0 , 255 );
159- int pB = clamp (ARGB .blue (pixelColor ) + (int ) ((double ) errorB * quantConst ), 0 , 255 );
160- return ARGB .color (ARGB .alpha (pixelColor ), pR , pG , pB );
161- }
162-
163- private static int clamp (int i , int min , int max ) {
164- if (min > max )
165- throw new IllegalArgumentException ("max value cannot be less than min value" );
166- if (i < min )
167- return min ;
168- if (i > max )
169- return max ;
170- return i ;
171- }
172-
173- private static int [][] convertPixelArray (BufferedImage image ) {
174-
175- final byte [] pixels = ((DataBufferByte ) image .getRaster ().getDataBuffer ()).getData ();
176- final int width = image .getWidth ();
177- final int height = image .getHeight ();
178-
179- int [][] result = new int [height ][width ];
180- final int pixelLength = 4 ;
181- for (int pixel = 0 , row = 0 , col = 0 ; pixel + 3 < pixels .length ; pixel += pixelLength ) {
182- int argb = 0 ;
183- argb += (((int ) pixels [pixel ] & 0xff ) << 24 ); // alpha
184- argb += ((int ) pixels [pixel + 1 ] & 0xff ); // blue
185- argb += (((int ) pixels [pixel + 2 ] & 0xff ) << 8 ); // green
186- argb += (((int ) pixels [pixel + 3 ] & 0xff ) << 16 ); // red
187- result [row ][col ] = argb ;
188- col ++;
189- if (col == width ) {
190- col = 0 ;
191- row ++;
192- }
193- }
194-
195- return result ;
196- }
197-
19882 private static BufferedImage convertToBufferedImage (Image image ) {
19983 BufferedImage newImage = new BufferedImage (image .getWidth (null ), image .getHeight (null ),
20084 BufferedImage .TYPE_4BYTE_ABGR );
0 commit comments