Skip to content

Commit 7ed28e3

Browse files
committed
Add support for webp
1 parent 6a63651 commit 7ed28e3

6 files changed

Lines changed: 40 additions & 128 deletions

File tree

build.gradle

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,17 @@ dependencies {
3030
modImplementation include("eu.pb4:map-canvas-api:${project.mapcanvas_version}")
3131
modImplementation include("eu.pb4:sgui:${project.sgui_version}")
3232
modImplementation include("me.lucko:fabric-permissions-api:0.6.0-patbox")
33-
//implementation include("com.twelvemonkeys.imageio:imageio-webp:3.12.0")
33+
34+
[
35+
"imageio:imageio-core",
36+
"imageio:imageio-webp",
37+
"imageio:imageio-metadata",
38+
"common:common-lang",
39+
"common:common-io",
40+
"common:common-image",
41+
].forEach {
42+
implementation include("com.twelvemonkeys.${it}:3.12.0")
43+
}
3444
}
3545

3646
loom {

gradle.properties

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,19 @@ org.gradle.jvmargs=-Xmx1G
33

44
# Fabric Properties
55
# check these on https://fabricmc.net/versions.html
6-
minecraft_version=1.21.11-rc3
7-
yarn_mappings=1.21.11-rc3+build.1
8-
loader_version=0.18.1
6+
minecraft_version=1.21.11
7+
yarn_mappings=1.21.11+build.1
8+
loader_version=0.18.2
99
loom_version=1.13-SNAPSHOT
1010

1111
# Fabric API
1212
fabric_version=0.139.4+1.21.11
1313

1414
# Mod Properties
15-
mod_version = 0.12.0+1.21.11
15+
mod_version = 0.12.1+1.21.11
1616
maven_group = space.essem
1717
archives_base_name = image2map
1818

1919
# Dependencies
20-
mapcanvas_version=0.6.0+1.21.9
20+
mapcanvas_version=0.7.0+1.21.11
2121
sgui_version=1.11.0+1.21.9

src/main/java/space/essem/image2map/Image2Map.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ private int openPreview(CommandContext<CommandSourceStack> context) throws Comma
128128

129129
source.sendSuccess(() -> Component.literal("Getting image..."), false);
130130

131-
getImage(input).orTimeout(20, TimeUnit.SECONDS).handleAsync((image, ex) -> {
131+
getImage(input).orTimeout(30, TimeUnit.SECONDS).handleAsync((image, ex) -> {
132132
if (ex instanceof TimeoutException) {
133133
source.sendSuccess(() -> Component.literal("Downloading or reading of the image took too long!"), false);
134134
return null;
@@ -205,6 +205,7 @@ private CompletableFuture<BufferedImage> getImage(String input) {
205205
return null;
206206
}
207207
} catch (Throwable e) {
208+
LOGGER.warn("Failed to load the image!", e);
208209
throw new RuntimeException(e);
209210
}
210211
});
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package space.essem.image2map;
2+
3+
import net.fabricmc.loader.api.entrypoint.PreLaunchEntrypoint;
4+
5+
import javax.imageio.ImageIO;
6+
7+
public class ImageIoBootstrap implements PreLaunchEntrypoint {
8+
@Override
9+
public void onPreLaunch() {
10+
try {
11+
ImageIO.scanForPlugins();
12+
} catch (Throwable e) {
13+
throw new RuntimeException(e);
14+
}
15+
}
16+
}

src/main/java/space/essem/image2map/renderer/MapRenderer.java

Lines changed: 4 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -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);

src/main/resources/fabric.mod.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
"space.essem.image2map.Image2Map"
2424
],
2525
"preLaunch": [
26-
"space.essem.image2map.CardboardWarning"
26+
"space.essem.image2map.CardboardWarning",
27+
"space.essem.image2map.ImageIoBootstrap"
2728
]
2829
},
2930
"accessWidener": "image2map.accesswidener",

0 commit comments

Comments
 (0)