From 1cd1bbb005a89ad466ebacb67a010698627b9c6c Mon Sep 17 00:00:00 2001 From: Lotto Date: Sun, 12 May 2019 01:43:19 +0200 Subject: [PATCH] client: add BufferedImage -> IndexedSprite converter to ImageUtil --- .../net/runelite/client/util/ImageUtil.java | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/runelite-client/src/main/java/net/runelite/client/util/ImageUtil.java b/runelite-client/src/main/java/net/runelite/client/util/ImageUtil.java index 16a6b1c78a..d7f579b722 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/ImageUtil.java +++ b/runelite-client/src/main/java/net/runelite/client/util/ImageUtil.java @@ -24,6 +24,7 @@ */ package net.runelite.client.util; +import com.google.common.primitives.Ints; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Image; @@ -34,12 +35,15 @@ import java.awt.image.DirectColorModel; import java.awt.image.PixelGrabber; import java.awt.image.RescaleOp; import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import javax.imageio.ImageIO; import javax.swing.GrayFilter; import java.util.function.Predicate; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; +import net.runelite.api.IndexedSprite; import net.runelite.api.SpritePixels; /** @@ -448,4 +452,74 @@ public class ImageUtil return client.createSpritePixels(pixels, image.getWidth(), image.getHeight()); } + + /** + * Converts an image into an {@code IndexedSprite} instance. + * + * The passed in image can only have at max 255 different colors. + * + * @param image The image to be converted + * @param client Current client instance + * @return The image as an {@code IndexedSprite} + */ + public static IndexedSprite getImageIndexedSprite(BufferedImage image, Client client) + { + final byte[] pixels = new byte[image.getWidth() * image.getHeight()]; + final List palette = new ArrayList<>(); + /* + When drawing the indexed sprite, palette idx 0 is seen as fully transparent, + so pad the palette out so that our colors start at idx 1. + */ + palette.add(0); + + final int[] sourcePixels = image.getRGB(0, 0, + image.getWidth(), image.getHeight(), + null, 0, image.getWidth()); + + /* + Build a color palette and assign the pixels to positions in the palette. + */ + for (int j = 0; j < sourcePixels.length; j++) + { + final int argb = sourcePixels[j]; + final int a = (argb >> 24) & 0xFF; + final int rgb = argb & 0xFF_FF_FF; + + // Default to not drawing the pixel. + int paletteIdx = 0; + + // If the pixel is fully opaque, draw it. + if (a == 0xFF) + { + paletteIdx = palette.indexOf(rgb); + + if (paletteIdx == -1) + { + paletteIdx = palette.size(); + palette.add(rgb); + } + } + + pixels[j] = (byte) paletteIdx; + } + + if (palette.size() > 256) + { + throw new RuntimeException("Passed in image had " + (palette.size() - 1) + + " different colors, exceeding the max of 255."); + } + + final IndexedSprite sprite = client.createIndexedSprite(); + + sprite.setPixels(pixels); + sprite.setPalette(Ints.toArray(palette)); + sprite.setWidth(image.getWidth()); + sprite.setHeight(image.getHeight()); + sprite.setOriginalWidth(image.getWidth()); + sprite.setOriginalHeight(image.getHeight()); + sprite.setOffsetX(0); + sprite.setOffsetY(0); + + return sprite; + } }