diff --git a/runelite-api/src/main/java/net/runelite/api/SpritePixels.java b/runelite-api/src/main/java/net/runelite/api/SpritePixels.java index df4c31396a..dbc3c6c3bb 100644 --- a/runelite-api/src/main/java/net/runelite/api/SpritePixels.java +++ b/runelite-api/src/main/java/net/runelite/api/SpritePixels.java @@ -33,4 +33,6 @@ public interface SpritePixels int getWidth(); int getHeight(); + + int[] getPixels(); } diff --git a/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java b/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java index 2bab56cf5b..458d7ebf1c 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java +++ b/runelite-client/src/main/java/net/runelite/client/game/ItemManager.java @@ -25,9 +25,16 @@ package net.runelite.client.game; import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; + +import java.awt.image.BufferedImage; import java.io.IOException; +import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; + +import net.runelite.api.Client; +import net.runelite.api.SpritePixels; import net.runelite.client.RuneLite; import net.runelite.http.api.item.ItemClient; import net.runelite.http.api.item.ItemPrice; @@ -44,15 +51,30 @@ public class ItemManager */ static final ItemPrice NONE = new ItemPrice(); - private final ItemClient client = new ItemClient(); + + private final ItemClient itemClient = new ItemClient(); private final LoadingCache itemPrices; + private static LoadingCache itemImages; + public ItemManager(RuneLite runelite) { itemPrices = CacheBuilder.newBuilder() .maximumSize(512L) .expireAfterAccess(1, TimeUnit.HOURS) - .build(new ItemPriceLoader(runelite, client)); + .build(new ItemPriceLoader(runelite, itemClient)); + + itemImages = CacheBuilder.newBuilder() + .maximumSize(200) + .expireAfterAccess(1, TimeUnit.HOURS) + .build(new CacheLoader() + { + @Override + public BufferedImage load(Integer itemId) throws Exception + { + return loadImage(itemId); + } + }); } /** @@ -88,7 +110,7 @@ public class ItemManager return itemPrice == NONE ? null : itemPrice; } - itemPrice = client.lookupItemPrice(itemId); + itemPrice = itemClient.lookupItemPrice(itemId); itemPrices.put(itemId, itemPrice); return itemPrice; } @@ -113,4 +135,48 @@ public class ItemManager return "" + quantity; } + + /** + * Loads item sprite from game, makes transparent, and generates image + * @param itemId + * @return + */ + private BufferedImage loadImage(int itemId) + { + Client client = RuneLite.getClient(); + SpritePixels sprite = client.createItemSprite(itemId, 1, 1, SpritePixels.DEFAULT_SHADOW_COLOR, 0, false); + int[] pixels = sprite.getPixels(); + int[] transPixels = new int[pixels.length]; + BufferedImage img = new BufferedImage(sprite.getWidth(), sprite.getHeight(), BufferedImage.TYPE_INT_ARGB); + + for (int i = 0; i < pixels.length; i++) + { + if (pixels[i] != 0) + { + transPixels[i] = pixels[i] | 0xff000000; + } + } + + img.setRGB(0, 0, sprite.getWidth(), sprite.getHeight(), transPixels, 0, sprite.getWidth()); + + return img; + } + + /** + * Get item sprite image as BufferedImage + * + * @param itemId + * @return + */ + public static BufferedImage getImage(int itemId) + { + try + { + return itemImages.get(itemId); + } + catch (ExecutionException ex) + { + return null; + } + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingSpot.java b/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingSpot.java index 6b9823c618..b3b889a8f6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingSpot.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingSpot.java @@ -93,7 +93,7 @@ public enum FishingSpot private static final Map fishingSpots = new HashMap<>(); private final String name; - private final int itemSpriteId; + private final int fishSpriteId; private final int[] spots; static @@ -109,10 +109,10 @@ public enum FishingSpot } } - FishingSpot(String spot, int itemSpriteId, int... spots) + FishingSpot(String spot, int fishSpriteId, int... spots) { this.name = spot; - this.itemSpriteId = itemSpriteId; + this.fishSpriteId = fishSpriteId; this.spots = spots; } @@ -121,9 +121,9 @@ public enum FishingSpot return name; } - public int getItemSpriteId() + public int getFishSpriteId() { - return itemSpriteId; + return fishSpriteId; } public int[] getIds() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingSpotOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingSpotOverlay.java index 8f2cc6503c..084b46cd32 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingSpotOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingSpotOverlay.java @@ -28,14 +28,15 @@ import com.google.common.primitives.Ints; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; +import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.List; import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.NPC; -import net.runelite.api.SpritePixels; import net.runelite.api.queries.NPCQuery; import net.runelite.client.RuneLite; +import net.runelite.client.game.ItemManager; import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayPosition; import net.runelite.client.ui.overlay.OverlayUtil; @@ -81,10 +82,10 @@ class FishingSpotOverlay extends Overlay Color color = npc.getId() == FishingSpot.FLYING_FISH ? Color.RED : Color.CYAN; if (config.showIcons()) { - SpritePixels fishSprite = getFishSprite(spot); - if (fishSprite != null) + BufferedImage fishImage = getFishImage(spot); + if (fishImage != null) { - OverlayUtil.renderActorOverlaySprite(graphics, npc, fishSprite, color.darker()); + OverlayUtil.renderActorOverlayImage(graphics, npc, fishImage, color.darker()); } } else @@ -97,9 +98,10 @@ class FishingSpotOverlay extends Overlay return null; } - private SpritePixels getFishSprite(FishingSpot spot) + private BufferedImage getFishImage(FishingSpot spot) { - return client.createItemSprite(spot.getItemSpriteId(), 5, 1, SpritePixels.DEFAULT_SHADOW_COLOR, 0, false); + BufferedImage fishImage = ItemManager.getImage(spot.getFishSpriteId()); + return fishImage; } public void updateConfig() diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSSpritePixels.java b/runescape-api/src/main/java/net/runelite/rs/api/RSSpritePixels.java index f59d6a34f4..9d2ae3ff63 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSSpritePixels.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSSpritePixels.java @@ -40,4 +40,8 @@ public interface RSSpritePixels extends SpritePixels @Import("width") @Override int getWidth(); + + @Import("pixels") + @Override + int[] getPixels(); }