diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java index e5636314f9..49dc527f3d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java @@ -130,7 +130,7 @@ public class ConfigPanel extends PluginPanel { BufferedImage backIcon = ImageIO.read(ConfigPanel.class.getResourceAsStream("config_back_icon.png")); BACK_ICON = new ImageIcon(backIcon); - BACK_ICON_HOVER = new ImageIcon(ImageUtil.grayscaleOffset(backIcon, -100)); + BACK_ICON_HOVER = new ImageIcon(ImageUtil.alphaOffset(backIcon, -100)); SEARCH = new ImageIcon(ImageIO.read(IconTextField.class.getResourceAsStream("search.png"))); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListItem.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListItem.java index 27b96d2c27..b9ba675b80 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListItem.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListItem.java @@ -92,13 +92,21 @@ class PluginListItem extends JPanel { configIcon = ImageIO.read(ConfigPanel.class.getResourceAsStream("config_edit_icon.png")); CONFIG_ICON = new ImageIcon(configIcon); - ON_SWITCHER = new ImageIcon(ImageIO.read(ConfigPanel.class.getResourceAsStream("switchers/on.png"))); - OFF_SWITCHER = new ImageIcon(ImageIO.read(ConfigPanel.class.getResourceAsStream("switchers/off.png"))); - ON_STAR = new ImageIcon(ImageIO.read(ConfigPanel.class.getResourceAsStream("stars/on.png"))); - OFF_STAR = new ImageIcon(ImageIO.read(ConfigPanel.class.getResourceAsStream("stars/off.png"))); + ON_SWITCHER = new ImageIcon(ImageIO.read(ConfigPanel.class.getResourceAsStream("switcher_on.png"))); + ON_STAR = new ImageIcon(ImageIO.read(ConfigPanel.class.getResourceAsStream("star_on.png"))); } - CONFIG_ICON_HOVER = new ImageIcon(ImageUtil.grayscaleOffset(configIcon, -100)); + BufferedImage offSwitcherImage = ImageUtil.bufferedImageFromImage(ON_SWITCHER.getImage()); + offSwitcherImage = ImageUtil.grayscaleImage(offSwitcherImage); + offSwitcherImage = ImageUtil.grayscaleOffset(offSwitcherImage, 0.61f); + offSwitcherImage = ImageUtil.flipImage(offSwitcherImage, true, false); + OFF_SWITCHER = new ImageIcon(offSwitcherImage); + BufferedImage offStarImage = ImageUtil.bufferedImageFromImage(ON_STAR.getImage()); + offStarImage = ImageUtil.grayscaleImage(offStarImage); + offStarImage = ImageUtil.grayscaleOffset(offStarImage, 0.77f); + OFF_STAR = new ImageIcon(offStarImage); + + CONFIG_ICON_HOVER = new ImageIcon(ImageUtil.alphaOffset(configIcon, -100)); } catch (IOException e) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeOfferSlot.java b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeOfferSlot.java index 356d6f843c..45fdbe5371 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeOfferSlot.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeOfferSlot.java @@ -54,6 +54,7 @@ import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.FontManager; import net.runelite.client.ui.components.ThinProgressBar; import net.runelite.client.util.ColorUtil; +import net.runelite.client.util.ImageUtil; import net.runelite.client.util.StackFormatter; @Slf4j @@ -87,8 +88,8 @@ public class GrandExchangeOfferSlot extends JPanel { synchronized (ImageIO.class) { - RIGHT_ARROW_ICON = new ImageIcon(ImageIO.read(GrandExchangeOfferSlot.class.getResourceAsStream("arrow_right.png"))); - LEFT_ARROW_ICON = new ImageIcon(ImageIO.read(GrandExchangeOfferSlot.class.getResourceAsStream("arrow_left.png"))); + RIGHT_ARROW_ICON = new ImageIcon(ImageUtil.alphaOffset(ImageIO.read(GrandExchangeOfferSlot.class.getResourceAsStream("/util/arrow_right.png")), 0.25f)); + LEFT_ARROW_ICON = new ImageIcon(ImageUtil.flipImage(ImageUtil.bufferedImageFromImage(RIGHT_ARROW_ICON.getImage()), true, false)); } } catch (IOException e) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeSearchPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeSearchPanel.java index 05e92315c4..2cf3eca92d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeSearchPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangeSearchPanel.java @@ -49,6 +49,7 @@ import net.runelite.client.game.ItemManager; import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.components.IconTextField; import net.runelite.client.ui.components.PluginErrorPanel; +import net.runelite.client.util.ImageUtil; import net.runelite.http.api.item.Item; import net.runelite.http.api.item.ItemPrice; import net.runelite.http.api.item.SearchResult; @@ -99,7 +100,7 @@ class GrandExchangeSearchPanel extends JPanel { synchronized (ImageIO.class) { - SEARCH_ICON = new ImageIcon(ImageIO.read(IconTextField.class.getResourceAsStream("search_darker.png"))); + SEARCH_ICON = new ImageIcon(ImageUtil.alphaOffset(ImageUtil.grayscaleOffset(ImageIO.read(IconTextField.class.getResourceAsStream("search.png")), 0f), 1.75f)); LOADING_ICON = new ImageIcon(IconTextField.class.getResource("loading_spinner.gif")); ERROR_ICON = new ImageIcon(ImageIO.read(IconTextField.class.getResourceAsStream("error.png"))); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPanel.java index 7415591e34..6309d289d0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/info/InfoPanel.java @@ -96,7 +96,7 @@ public class InfoPanel extends PluginPanel { synchronized (ImageIO.class) { - ARROW_RIGHT_ICON = new ImageIcon(ImageIO.read(InfoPanel.class.getResourceAsStream("arrow_right.png"))); + ARROW_RIGHT_ICON = new ImageIcon(ImageIO.read(InfoPanel.class.getResourceAsStream("/util/arrow_right.png"))); GITHUB_ICON = new ImageIcon(ImageIO.read(InfoPanel.class.getResourceAsStream("github_icon.png"))); DISCORD_ICON = new ImageIcon(ImageIO.read(InfoPanel.class.getResourceAsStream("discord_icon.png"))); PATREON_ICON = new ImageIcon(ImageIO.read(InfoPanel.class.getResourceAsStream("patreon_icon.png"))); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/KourendLibraryPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/KourendLibraryPanel.java index cd66a57229..3dcf7e6542 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/KourendLibraryPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/kourendlibrary/KourendLibraryPanel.java @@ -73,7 +73,7 @@ class KourendLibraryPanel extends PluginPanel { BufferedImage resetIcon = ImageIO.read(KourendLibraryPanel.class.getResourceAsStream("reset.png")); RESET_ICON = new ImageIcon(resetIcon); - RESET_CLICK_ICON = new ImageIcon(ImageUtil.grayscaleOffset(resetIcon, -100)); + RESET_CLICK_ICON = new ImageIcon(ImageUtil.alphaOffset(resetIcon, -100)); } } catch (IOException e) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerCreationPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerCreationPanel.java index 6385fa3163..3cc7162752 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerCreationPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerCreationPanel.java @@ -29,6 +29,7 @@ import java.awt.Color; import java.awt.GridLayout; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.awt.image.BufferedImage; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.ImageIcon; @@ -39,6 +40,7 @@ import net.runelite.client.plugins.screenmarkers.ScreenMarkerPlugin; import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.FontManager; import net.runelite.client.ui.components.shadowlabel.JShadowedLabel; +import net.runelite.client.util.ImageUtil; public class ScreenMarkerCreationPanel extends JPanel { @@ -59,16 +61,18 @@ public class ScreenMarkerCreationPanel extends JPanel synchronized (ImageIO.class) { CONFIRM_ICON = new ImageIcon(ImageIO.read(ScreenMarkerPlugin.class.getResourceAsStream("confirm_icon.png"))); - CONFIRM_HOVER_ICON = new ImageIcon(ImageIO.read(ScreenMarkerPlugin.class.getResourceAsStream("confirm_hover_icon.png"))); - CONFIRM_LOCKED_ICON = new ImageIcon(ImageIO.read(ScreenMarkerPlugin.class.getResourceAsStream("confirm_locked_icon.png"))); CANCEL_ICON = new ImageIcon(ImageIO.read(ScreenMarkerPlugin.class.getResourceAsStream("cancel_icon.png"))); - CANCEL_HOVER_ICON = new ImageIcon(ImageIO.read(ScreenMarkerPlugin.class.getResourceAsStream("cancel_hover_icon.png"))); } } catch (IOException e) { throw new RuntimeException(e); } + + final BufferedImage confirmIcon = ImageUtil.bufferedImageFromImage(CONFIRM_ICON.getImage()); + CONFIRM_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(confirmIcon, 0.54f)); + CONFIRM_LOCKED_ICON = new ImageIcon(ImageUtil.grayscaleImage(confirmIcon)); + CANCEL_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(ImageUtil.bufferedImageFromImage(CANCEL_ICON.getImage()), 0.6f)); } ScreenMarkerCreationPanel(ScreenMarkerPlugin plugin) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java index def79500dd..0741875188 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPanel.java @@ -114,36 +114,36 @@ class ScreenMarkerPanel extends JPanel { BufferedImage borderImg = ImageIO.read(ScreenMarkerPlugin.class.getResourceAsStream("border_color_icon.png")); BORDER_COLOR_ICON = new ImageIcon(borderImg); - BORDER_COLOR_HOVER_ICON = new ImageIcon(ImageUtil.grayscaleOffset(borderImg, -100)); + BORDER_COLOR_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(borderImg, -100)); BufferedImage noBorderImg = ImageIO.read(ScreenMarkerPlugin.class.getResourceAsStream("no_border_color_icon.png")); NO_BORDER_COLOR_ICON = new ImageIcon(noBorderImg); - NO_BORDER_COLOR_HOVER_ICON = new ImageIcon(ImageUtil.grayscaleOffset(noBorderImg, -100)); + NO_BORDER_COLOR_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(noBorderImg, -100)); BufferedImage fillImg = ImageIO.read(ScreenMarkerPlugin.class.getResourceAsStream("fill_color_icon.png")); FILL_COLOR_ICON = new ImageIcon(fillImg); - FILL_COLOR_HOVER_ICON = new ImageIcon(ImageUtil.grayscaleOffset(fillImg, -100)); + FILL_COLOR_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(fillImg, -100)); BufferedImage noFillImg = ImageIO.read(ScreenMarkerPlugin.class.getResourceAsStream("no_fill_color_icon.png")); NO_FILL_COLOR_ICON = new ImageIcon(noFillImg); - NO_FILL_COLOR_HOVER_ICON = new ImageIcon(ImageUtil.grayscaleOffset(noFillImg, -100)); + NO_FILL_COLOR_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(noFillImg, -100)); BufferedImage opacityImg = ImageIO.read(ScreenMarkerPlugin.class.getResourceAsStream("opacity_icon.png")); FULL_OPACITY_ICON = new ImageIcon(opacityImg); - OPACITY_HOVER_ICON = new ImageIcon(ImageUtil.grayscaleOffset(opacityImg, -100)); - NO_OPACITY_ICON = new ImageIcon(ImageUtil.grayscaleOffset(opacityImg, -150)); + OPACITY_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(opacityImg, -100)); + NO_OPACITY_ICON = new ImageIcon(ImageUtil.alphaOffset(opacityImg, -150)); BufferedImage visibleImg = ImageIO.read(ScreenMarkerPlugin.class.getResourceAsStream("visible_icon.png")); VISIBLE_ICON = new ImageIcon(visibleImg); - VISIBLE_HOVER_ICON = new ImageIcon(ImageUtil.grayscaleOffset(visibleImg, -100)); + VISIBLE_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(visibleImg, -100)); BufferedImage invisibleImg = ImageIO.read(ScreenMarkerPlugin.class.getResourceAsStream("invisible_icon.png")); INVISIBLE_ICON = new ImageIcon(invisibleImg); - INVISIBLE_HOVER_ICON = new ImageIcon(ImageUtil.grayscaleOffset(invisibleImg, -100)); + INVISIBLE_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(invisibleImg, -100)); BufferedImage deleteImg = ImageIO.read(ScreenMarkerPlugin.class.getResourceAsStream("delete_icon.png")); DELETE_ICON = new ImageIcon(deleteImg); - DELETE_HOVER_ICON = new ImageIcon(ImageUtil.grayscaleOffset(deleteImg, -100)); + DELETE_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(deleteImg, -100)); } } catch (IOException e) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPluginPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPluginPanel.java index 9dca4e8d11..2b58291b28 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPluginPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ui/ScreenMarkerPluginPanel.java @@ -47,6 +47,7 @@ import net.runelite.client.plugins.screenmarkers.ScreenMarkerPlugin; import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.PluginPanel; import net.runelite.client.ui.components.PluginErrorPanel; +import net.runelite.client.util.ImageUtil; @Singleton public class ScreenMarkerPluginPanel extends PluginPanel @@ -85,13 +86,14 @@ public class ScreenMarkerPluginPanel extends PluginPanel synchronized (ImageIO.class) { ADD_ICON = new ImageIcon(ImageIO.read(ScreenMarkerPlugin.class.getResourceAsStream("add_icon.png"))); - ADD_HOVER_ICON = new ImageIcon(ImageIO.read(ScreenMarkerPlugin.class.getResourceAsStream("add_hover_icon.png"))); } } catch (IOException e) { throw new RuntimeException(e); } + + ADD_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(ImageUtil.bufferedImageFromImage(ADD_ICON.getImage()), 0.53f)); } public void init() diff --git a/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java b/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java index 0539517a65..15882be372 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java @@ -70,6 +70,7 @@ import net.runelite.client.events.NavigationButtonAdded; import net.runelite.client.events.NavigationButtonRemoved; import net.runelite.client.input.KeyManager; import net.runelite.client.ui.skin.SubstanceRuneLiteLookAndFeel; +import net.runelite.client.util.ImageUtil; import net.runelite.client.util.OSType; import net.runelite.client.util.OSXUtil; import net.runelite.client.util.SwingUtil; @@ -97,7 +98,6 @@ public class ClientUI { BufferedImage icon; BufferedImage sidebarOpen; - BufferedImage sidebarClose; try { @@ -105,7 +105,6 @@ public class ClientUI { icon = ImageIO.read(ClientUI.class.getResourceAsStream("/runelite.png")); sidebarOpen = ImageIO.read(ClientUI.class.getResourceAsStream("open.png")); - sidebarClose = ImageIO.read(ClientUI.class.getResourceAsStream("close.png")); } } catch (IOException e) @@ -115,7 +114,7 @@ public class ClientUI ICON = icon; SIDEBAR_OPEN = sidebarOpen; - SIDEBAR_CLOSE = sidebarClose; + SIDEBAR_CLOSE = ImageUtil.flipImage(SIDEBAR_OPEN, true, false); } @Getter 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 c2aa18f999..13828dad52 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 @@ -31,12 +31,33 @@ import java.awt.image.AffineTransformOp; import java.awt.image.BufferedImage; import java.awt.image.RescaleOp; import java.util.Arrays; +import javax.swing.GrayFilter; /** * Various Image/BufferedImage utilities. */ public class ImageUtil { + /** + * Creates a {@link BufferedImage} from an {@link Image}. + * + * @param image An Image to be converted to a BufferedImage. + * @return A BufferedImage instance of the same given image. + */ + public static BufferedImage bufferedImageFromImage(final Image image) + { + if (image instanceof BufferedImage) + { + return (BufferedImage) image; + } + + final BufferedImage out = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB); + final Graphics2D g2d = out.createGraphics(); + g2d.drawImage(image, 0, 0, null); + g2d.dispose(); + return out; + } + /** * Offsets an image in the grayscale (darkens/brightens) by a given offset. * @@ -63,6 +84,86 @@ public class ImageUtil return offset(image, scales, offsets); } + /** + * Offsets an image in the grayscale (darkens/brightens) by a given percentage. + * + * @param image The image to be darkened or brightened. + * @param percentage The ratio to darken or brighten the given image. + * Values above 1 will brighten, and values below 1 will darken. + * @return The given image with its brightness scaled by the given percentage. + */ + public static BufferedImage grayscaleOffset(final BufferedImage image, final float percentage) + { + final int numComponents = image.getColorModel().getNumComponents(); + final float[] scales = new float[numComponents]; + final float[] offsets = new float[numComponents]; + + Arrays.fill(offsets, 0f); + for (int i = 0; i < numComponents; i++) + { + scales[i] = percentage; + } + // Set alpha to not scale + scales[numComponents - 1] = 1f; + + return offset(image, scales, offsets); + } + + /** + * Offsets an image's alpha component by a given offset. + * + * @param image The image to be made more or less transparent. + * @param offset A signed 8-bit integer value to modify the image's alpha component with. + * Values above 0 will increase transparency, and values below 0 will decrease + * transparency. + * @return The given image with its alpha component adjusted by the given offset. + */ + public static BufferedImage alphaOffset(final BufferedImage image, final int offset) + { + final float offsetFloat = (float) offset; + final int numComponents = image.getColorModel().getNumComponents(); + final float[] scales = new float[numComponents]; + final float[] offsets = new float[numComponents]; + + Arrays.fill(scales, 1f); + Arrays.fill(offsets, 0f); + offsets[numComponents - 1] = offsetFloat; + return offset(image, scales, offsets); + } + + /** + * Offsets an image's alpha component by a given percentage. + * + * @param image The image to be made more or less transparent. + * @param percentage The ratio to modify the image's alpha component with. + * Values above 1 will increase transparency, and values below 1 will decrease + * transparency. + * @return The given image with its alpha component scaled by the given percentage. + */ + public static BufferedImage alphaOffset(final BufferedImage image, final float percentage) + { + final int numComponents = image.getColorModel().getNumComponents(); + final float[] scales = new float[numComponents]; + final float[] offsets = new float[numComponents]; + + Arrays.fill(scales, 1f); + Arrays.fill(offsets, 0f); + scales[numComponents - 1] = percentage; + return offset(image, scales, offsets); + } + + /** + * Creates a grayscale image from the given image. + * + * @param image The source image to be converted. + * @return A copy of the given imnage, with colors converted to grayscale. + */ + public static BufferedImage grayscaleImage(final BufferedImage image) + { + final Image grayImage = GrayFilter.createDisabledImage(image); + return ImageUtil.bufferedImageFromImage(grayImage); + } + /** * Re-size a BufferedImage to the given dimensions. * @@ -73,13 +174,8 @@ public class ImageUtil */ public static BufferedImage resizeImage(final BufferedImage image, final int newWidth, final int newHeight) { - final Image tmp = image.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH); - final BufferedImage dimg = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB); - - final Graphics2D g2d = dimg.createGraphics(); - g2d.drawImage(tmp, 0, 0, null); - g2d.dispose(); - return dimg; + final Image resized = image.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH); + return ImageUtil.bufferedImageFromImage(resized); } /** @@ -97,6 +193,42 @@ public class ImageUtil return transformOp.filter(image, null); } + /** + * Flips an image horizontally and/or vertically. + * + * @param image The image to be flipped. + * @param horizontal Whether the image should be flipped horizontally. + * @param vertical Whether the image should be flipped vertically. + * @return The given image, flipped horizontally and/or vertically. + */ + public static BufferedImage flipImage(final BufferedImage image, final boolean horizontal, final boolean vertical) + { + int x = 0; + int y = 0; + int w = image.getWidth(); + int h = image.getHeight(); + + final BufferedImage out = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); + final Graphics2D g2d = out.createGraphics(); + + if (horizontal) + { + x = w; + w *= -1; + } + + if (vertical) + { + y = h; + h *= -1; + } + + g2d.drawImage(image, x, y, w, h, null); + g2d.dispose(); + + return out; + } + /** * Performs a rescale operation on the image's color components. * diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/config/stars/on.png b/runelite-client/src/main/resources/net/runelite/client/plugins/config/star_on.png similarity index 100% rename from runelite-client/src/main/resources/net/runelite/client/plugins/config/stars/on.png rename to runelite-client/src/main/resources/net/runelite/client/plugins/config/star_on.png diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/config/stars/off.png b/runelite-client/src/main/resources/net/runelite/client/plugins/config/stars/off.png deleted file mode 100644 index b030162e0c..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/config/stars/off.png and /dev/null differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/config/switchers/on.png b/runelite-client/src/main/resources/net/runelite/client/plugins/config/switcher_on.png similarity index 100% rename from runelite-client/src/main/resources/net/runelite/client/plugins/config/switchers/on.png rename to runelite-client/src/main/resources/net/runelite/client/plugins/config/switcher_on.png diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/config/switchers/off.png b/runelite-client/src/main/resources/net/runelite/client/plugins/config/switchers/off.png deleted file mode 100644 index ff25cc611a..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/config/switchers/off.png and /dev/null differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/grandexchange/arrow_left.png b/runelite-client/src/main/resources/net/runelite/client/plugins/grandexchange/arrow_left.png deleted file mode 100644 index 480358e6a1..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/grandexchange/arrow_left.png and /dev/null differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/grandexchange/arrow_right.png b/runelite-client/src/main/resources/net/runelite/client/plugins/grandexchange/arrow_right.png deleted file mode 100644 index 63ab23f273..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/grandexchange/arrow_right.png and /dev/null differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/add_hover_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/add_hover_icon.png deleted file mode 100644 index 9eb7fe3baa..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/add_hover_icon.png and /dev/null differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/cancel_hover_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/cancel_hover_icon.png deleted file mode 100644 index d1ddc4ef67..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/cancel_hover_icon.png and /dev/null differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/confirm_hover_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/confirm_hover_icon.png deleted file mode 100644 index e5b7199658..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/confirm_hover_icon.png and /dev/null differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/confirm_locked_icon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/confirm_locked_icon.png deleted file mode 100644 index d6300bc3e9..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/plugins/screenmarkers/confirm_locked_icon.png and /dev/null differ diff --git a/runelite-client/src/main/resources/net/runelite/client/ui/close.png b/runelite-client/src/main/resources/net/runelite/client/ui/close.png deleted file mode 100644 index 4e016c4872..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/ui/close.png and /dev/null differ diff --git a/runelite-client/src/main/resources/net/runelite/client/ui/components/search_darker.png b/runelite-client/src/main/resources/net/runelite/client/ui/components/search_darker.png deleted file mode 100644 index 0d5d4608a6..0000000000 Binary files a/runelite-client/src/main/resources/net/runelite/client/ui/components/search_darker.png and /dev/null differ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/info/arrow_right.png b/runelite-client/src/main/resources/util/arrow_right.png similarity index 100% rename from runelite-client/src/main/resources/net/runelite/client/plugins/info/arrow_right.png rename to runelite-client/src/main/resources/util/arrow_right.png diff --git a/runelite-client/src/test/java/net/runelite/client/util/ImageUtilTest.java b/runelite-client/src/test/java/net/runelite/client/util/ImageUtilTest.java index a1caa7f1ae..1156557160 100644 --- a/runelite-client/src/test/java/net/runelite/client/util/ImageUtilTest.java +++ b/runelite-client/src/test/java/net/runelite/client/util/ImageUtilTest.java @@ -36,6 +36,7 @@ import java.awt.image.DataBuffer; import java.awt.image.DataBufferInt; import java.util.Arrays; import javax.annotation.Nonnull; +import org.apache.commons.lang3.ArrayUtils; import static org.junit.Assert.assertEquals; import org.junit.Test; @@ -66,9 +67,17 @@ public class ImageUtilTest BLACK_PIXEL_BOTTOM_RIGHT.setRGB(1, 1, BLACK.getRGB()); } + @Test + public void bufferedImageFromImage() + { + final BufferedImage buffered = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB); + assertEquals(buffered, ImageUtil.bufferedImageFromImage(buffered)); + } + @Test public void grayscaleOffset() { + // grayscaleOffset(BufferedImage image, int offset) assert(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.grayscaleOffset(oneByOne(BLACK), -255))); assert(bufferedImagesEqual(oneByOne(new Color(50, 50, 50)), ImageUtil.grayscaleOffset(oneByOne(BLACK), 50))); assert(bufferedImagesEqual(oneByOne(GRAY), ImageUtil.grayscaleOffset(oneByOne(BLACK), 128))); @@ -76,6 +85,73 @@ public class ImageUtilTest assert(bufferedImagesEqual(oneByOne(WHITE), ImageUtil.grayscaleOffset(oneByOne(BLACK), 255))); assert(bufferedImagesEqual(oneByOne(new Color(200, 200, 200)), ImageUtil.grayscaleOffset(oneByOne(WHITE), -55))); assert(bufferedImagesEqual(oneByOne(WHITE), ImageUtil.grayscaleOffset(oneByOne(WHITE), 55))); + + // grayscaleOffset(BufferedImage image, float percentage) + assert(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.grayscaleOffset(oneByOne(BLACK), 0f))); + assert(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.grayscaleOffset(oneByOne(BLACK), 1f))); + assert(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.grayscaleOffset(oneByOne(BLACK), 2f))); + assert(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.grayscaleOffset(oneByOne(GRAY), 0f))); + assert(bufferedImagesEqual(oneByOne(GRAY), ImageUtil.grayscaleOffset(oneByOne(GRAY), 1f))); + assert(bufferedImagesEqual(oneByOne(WHITE), ImageUtil.grayscaleOffset(oneByOne(GRAY), 2f))); + assert(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.grayscaleOffset(oneByOne(WHITE), 0f))); + assert(bufferedImagesEqual(oneByOne(GRAY), ImageUtil.grayscaleOffset(oneByOne(WHITE), 0.503f))); // grayscaleOffset does Math.floor + assert(bufferedImagesEqual(oneByOne(WHITE), ImageUtil.grayscaleOffset(oneByOne(WHITE), 1f))); + assert(bufferedImagesEqual(oneByOne(WHITE), ImageUtil.grayscaleOffset(oneByOne(WHITE), 2f))); + } + + @Test + public void alphaOffset() + { + // alphaOffset(BufferedImage image, int offset) + assert(bufferedImagesEqual(oneByOne(BLACK_TRANSPARENT), ImageUtil.alphaOffset(oneByOne(BLACK_TRANSPARENT), -255))); + assert(bufferedImagesEqual(oneByOne(new Color(0, 0, 0, 50)), ImageUtil.alphaOffset(oneByOne(BLACK_TRANSPARENT), 50))); + assert(bufferedImagesEqual(oneByOne(BLACK_HALF_TRANSPARENT), ImageUtil.alphaOffset(oneByOne(BLACK_TRANSPARENT), 128))); + assert(bufferedImagesEqual(oneByOne(BLACK_TRANSPARENT), ImageUtil.alphaOffset(oneByOne(BLACK_HALF_TRANSPARENT), -255))); + assert(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.alphaOffset(oneByOne(BLACK_TRANSPARENT), 255))); + assert(bufferedImagesEqual(oneByOne(new Color(0, 0, 0, 200)), ImageUtil.alphaOffset(oneByOne(BLACK), -55))); + assert(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.alphaOffset(oneByOne(BLACK), 255))); + + // alphaOffset(BufferedImage image, float offset) + assert(bufferedImagesEqual(oneByOne(BLACK_TRANSPARENT), ImageUtil.alphaOffset(oneByOne(BLACK_TRANSPARENT), 0f))); + assert(bufferedImagesEqual(oneByOne(BLACK_TRANSPARENT), ImageUtil.alphaOffset(oneByOne(BLACK_TRANSPARENT), 1f))); + assert(bufferedImagesEqual(oneByOne(BLACK_TRANSPARENT), ImageUtil.alphaOffset(oneByOne(BLACK_TRANSPARENT), 2f))); + assert(bufferedImagesEqual(oneByOne(BLACK_TRANSPARENT), ImageUtil.alphaOffset(oneByOne(BLACK_HALF_TRANSPARENT), 0f))); + assert(bufferedImagesEqual(oneByOne(BLACK_HALF_TRANSPARENT), ImageUtil.alphaOffset(oneByOne(BLACK_HALF_TRANSPARENT), 1f))); + assert(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.alphaOffset(oneByOne(BLACK_HALF_TRANSPARENT), 2f))); + assert(bufferedImagesEqual(oneByOne(BLACK_TRANSPARENT), ImageUtil.alphaOffset(oneByOne(BLACK), 0f))); + assert(bufferedImagesEqual(oneByOne(BLACK_HALF_TRANSPARENT), ImageUtil.alphaOffset(oneByOne(BLACK), 0.503f))); // opacityOffset does Math.floor + assert(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.alphaOffset(oneByOne(BLACK), 1f))); + assert(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.alphaOffset(oneByOne(BLACK), 2f))); + } + + @Test + public void grayscaleImage() + { + final BufferedImage[] grayscaleColors = new BufferedImage[] { + oneByOne(WHITE), + oneByOne(GRAY), + oneByOne(BLACK), + oneByOne(BLACK_HALF_TRANSPARENT), + oneByOne(BLACK_TRANSPARENT), + }; + final BufferedImage[] nonGrayscaleColors = new BufferedImage[] { + oneByOne(RED), + oneByOne(GREEN), + oneByOne(BLUE), + }; + + for (BufferedImage image : grayscaleColors) + { + assert(isGrayscale(image)); + } + for (BufferedImage image : nonGrayscaleColors) + { + assert(!isGrayscale(image)); + } + for (BufferedImage image : ArrayUtils.addAll(grayscaleColors, nonGrayscaleColors)) + { + assert(isGrayscale(ImageUtil.grayscaleImage(image))); + } } @Test @@ -145,6 +221,15 @@ public class ImageUtilTest assert(bufferedImagesEqual(twoByOneLeft, ImageUtil.rotateImage(twoByOneLeft, Math.PI * 2))); } + @Test + public void flipImage() + { + assert(bufferedImagesEqual(BLACK_PIXEL_TOP_LEFT, ImageUtil.flipImage(BLACK_PIXEL_TOP_LEFT, false, false))); + assert(bufferedImagesEqual(BLACK_PIXEL_TOP_RIGHT, ImageUtil.flipImage(BLACK_PIXEL_TOP_LEFT, true, false))); + assert(bufferedImagesEqual(BLACK_PIXEL_BOTTOM_LEFT, ImageUtil.flipImage(BLACK_PIXEL_TOP_LEFT, false, true))); + assert(bufferedImagesEqual(BLACK_PIXEL_BOTTOM_RIGHT, ImageUtil.flipImage(BLACK_PIXEL_TOP_LEFT, true, true))); + } + /** * Compares whether two {@link BufferedImage}s are equal in data. * @@ -187,6 +272,32 @@ public class ImageUtilTest return true; } + /** + * Returns whether a {@link BufferedImage} contains only grayscale pixel data. + * + * @param image The image to be checked. + * @return A boolean indicating whether all of the given image's pixels are grayscale. + */ + private boolean isGrayscale(final @Nonnull BufferedImage image) + { + for (int x = 0; x < image.getWidth(); x++) + { + for (int y = 0; y < image.getHeight(); y++) + { + final int color = image.getRGB(x, y); + final int red = (color & 0xff0000) >> 16; + final int green = (color & 0xff00) >> 8; + final int blue = color & 0xff; + if (red != green + || green != blue) + { + return false; + } + } + } + return true; + } + /** * Creates a {@link BufferedImage} of a 1-by-1px image of the given color. *