From dc2f4b6f590e65183cc3d11d6880bd0e6ce5bf17 Mon Sep 17 00:00:00 2001 From: Max Weber Date: Tue, 26 Nov 2019 22:27:45 -0700 Subject: [PATCH] ImageUtil: Rename methods to luminance, and work with non ARGB images --- .../client/plugins/config/PluginListItem.java | 4 +- .../plugins/config/PluginToggleButton.java | 2 +- .../screenmarkers/ui/ScreenMarkerPanel.java | 6 +-- .../timetracking/clocks/ClockTabPanel.java | 10 ++--- .../plugins/worldhopper/WorldTableHeader.java | 2 +- .../net/runelite/client/util/ImageUtil.java | 41 +++++++++++++------ .../runelite/client/util/ImageUtilTest.java | 34 +++++++-------- 7 files changed, 58 insertions(+), 41 deletions(-) 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 340e0982ba..d0a61f0b7d 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 @@ -79,9 +79,9 @@ class PluginListItem extends JPanel BufferedImage onStar = ImageUtil.getResourceStreamFromClass(ConfigPanel.class, "star_on.png"); CONFIG_ICON = new ImageIcon(configIcon); ON_STAR = new ImageIcon(onStar); - CONFIG_ICON_HOVER = new ImageIcon(ImageUtil.grayscaleOffset(configIcon, -100)); + CONFIG_ICON_HOVER = new ImageIcon(ImageUtil.luminanceOffset(configIcon, -100)); - BufferedImage offStar = ImageUtil.grayscaleOffset( + BufferedImage offStar = ImageUtil.luminanceScale( ImageUtil.grayscaleImage(onStar), 0.77f ); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginToggleButton.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginToggleButton.java index 0fb22dfbe0..a2eb72719f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginToggleButton.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginToggleButton.java @@ -42,7 +42,7 @@ class PluginToggleButton extends JToggleButton BufferedImage onSwitcher = ImageUtil.getResourceStreamFromClass(ConfigPanel.class, "switcher_on.png"); ON_SWITCHER = new ImageIcon(onSwitcher); OFF_SWITCHER = new ImageIcon(ImageUtil.flipImage( - ImageUtil.grayscaleOffset( + ImageUtil.luminanceScale( ImageUtil.grayscaleImage(onSwitcher), 0.61f ), 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 e9d827202b..782697f396 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 @@ -108,7 +108,7 @@ class ScreenMarkerPanel extends JPanel static { final BufferedImage borderImg = ImageUtil.getResourceStreamFromClass(ScreenMarkerPlugin.class, "border_color_icon.png"); - final BufferedImage borderImgHover = ImageUtil.grayscaleOffset(borderImg, -150); + final BufferedImage borderImgHover = ImageUtil.luminanceOffset(borderImg, -150); BORDER_COLOR_ICON = new ImageIcon(borderImg); BORDER_COLOR_HOVER_ICON = new ImageIcon(borderImgHover); @@ -116,7 +116,7 @@ class ScreenMarkerPanel extends JPanel NO_BORDER_COLOR_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(borderImgHover, -100)); final BufferedImage fillImg = ImageUtil.getResourceStreamFromClass(ScreenMarkerPlugin.class, "fill_color_icon.png"); - final BufferedImage fillImgHover = ImageUtil.grayscaleOffset(fillImg, -150); + final BufferedImage fillImgHover = ImageUtil.luminanceOffset(fillImg, -150); FILL_COLOR_ICON = new ImageIcon(fillImg); FILL_COLOR_HOVER_ICON = new ImageIcon(fillImgHover); @@ -124,7 +124,7 @@ class ScreenMarkerPanel extends JPanel NO_FILL_COLOR_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(fillImgHover, -100)); final BufferedImage opacityImg = ImageUtil.getResourceStreamFromClass(ScreenMarkerPlugin.class, "opacity_icon.png"); - final BufferedImage opacityImgHover = ImageUtil.grayscaleOffset(opacityImg, -150); + final BufferedImage opacityImgHover = ImageUtil.luminanceOffset(opacityImg, -150); FULL_OPACITY_ICON = new ImageIcon(opacityImg); FULL_OPACITY_HOVER_ICON = new ImageIcon(opacityImgHover); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockTabPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockTabPanel.java index 7eb2dfb9ca..cd1b1a5a2e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockTabPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockTabPanel.java @@ -75,15 +75,15 @@ public class ClockTabPanel extends TabContentPanel BufferedImage addIcon = ImageUtil.getResourceStreamFromClass(TimeTrackingPlugin.class, "add_icon.png"); DELETE_ICON = new ImageIcon(deleteIcon); - DELETE_ICON_HOVER = new ImageIcon(ImageUtil.grayscaleOffset(deleteIcon, -80)); + DELETE_ICON_HOVER = new ImageIcon(ImageUtil.luminanceOffset(deleteIcon, -80)); LAP_ICON = new ImageIcon(lapIcon); - LAP_ICON_HOVER = new ImageIcon(ImageUtil.grayscaleOffset(lapIcon, -80)); + LAP_ICON_HOVER = new ImageIcon(ImageUtil.luminanceOffset(lapIcon, -80)); PAUSE_ICON = new ImageIcon(pauseIcon); - PAUSE_ICON_HOVER = new ImageIcon(ImageUtil.grayscaleOffset(pauseIcon, -80)); + PAUSE_ICON_HOVER = new ImageIcon(ImageUtil.luminanceOffset(pauseIcon, -80)); RESET_ICON = new ImageIcon(resetIcon); - RESET_ICON_HOVER = new ImageIcon(ImageUtil.grayscaleOffset(resetIcon, -80)); + RESET_ICON_HOVER = new ImageIcon(ImageUtil.luminanceOffset(resetIcon, -80)); START_ICON = new ImageIcon(startIcon); - START_ICON_HOVER = new ImageIcon(ImageUtil.grayscaleOffset(startIcon, -80)); + START_ICON_HOVER = new ImageIcon(ImageUtil.luminanceOffset(startIcon, -80)); ADD_ICON = new ImageIcon(addIcon); ADD_ICON_HOVER = new ImageIcon(ImageUtil.alphaOffset(addIcon, 0.53f)); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableHeader.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableHeader.java index 2d7ef01406..6e3c094ef0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableHeader.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldTableHeader.java @@ -56,7 +56,7 @@ class WorldTableHeader extends JPanel { final BufferedImage arrowDown = ImageUtil.getResourceStreamFromClass(WorldHopperPlugin.class, "arrow_down.png"); final BufferedImage arrowUp = ImageUtil.rotateImage(arrowDown, Math.PI); - final BufferedImage arrowUpFaded = ImageUtil.grayscaleOffset(arrowUp, -80); + final BufferedImage arrowUpFaded = ImageUtil.luminanceOffset(arrowUp, -80); ARROW_UP = new ImageIcon(arrowUpFaded); final BufferedImage highlightArrowDown = ImageUtil.fillImage(arrowDown, HIGHLIGHT_COLOR); 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 47df1a4349..afe7054d43 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 @@ -70,23 +70,37 @@ public class ImageUtil return (BufferedImage) image; } - final BufferedImage out = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB); - final Graphics2D g2d = out.createGraphics(); + return toARGB(image); + } + + /** + * Creates an ARGB {@link BufferedImage} from an {@link Image}. + */ + public static BufferedImage toARGB(final Image image) + { + if (image instanceof BufferedImage && ((BufferedImage) image).getType() == BufferedImage.TYPE_INT_ARGB) + { + return (BufferedImage) image; + } + + BufferedImage out = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB); + 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. + * Offsets an image's luminance by a given value. * - * @param image The image to be darkened or brightened. + * @param rawImg The image to be darkened or brightened. * @param offset A signed 8-bit integer value to brighten or darken the image with. * Values above 0 will brighten, and values below 0 will darken. * @return The given image with its brightness adjusted by the given offset. */ - public static BufferedImage grayscaleOffset(final BufferedImage image, final int offset) + public static BufferedImage luminanceOffset(final Image rawImg, final int offset) { + BufferedImage image = toARGB(rawImg); final float offsetFloat = (float) offset; final int numComponents = image.getColorModel().getNumComponents(); final float[] scales = new float[numComponents]; @@ -104,15 +118,16 @@ public class ImageUtil } /** - * Offsets an image in the grayscale (darkens/brightens) by a given percentage. + * Changes an images luminance by a scaling factor * - * @param image The image to be darkened or brightened. + * @param rawImg 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) + public static BufferedImage luminanceScale(final Image rawImg, final float percentage) { + BufferedImage image = toARGB(rawImg); final int numComponents = image.getColorModel().getNumComponents(); final float[] scales = new float[numComponents]; final float[] offsets = new float[numComponents]; @@ -131,14 +146,15 @@ public class ImageUtil /** * Offsets an image's alpha component by a given offset. * - * @param image The image to be made more or less transparent. + * @param rawImg 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) + public static BufferedImage alphaOffset(final Image rawImg, final int offset) { + BufferedImage image = toARGB(rawImg); final float offsetFloat = (float) offset; final int numComponents = image.getColorModel().getNumComponents(); final float[] scales = new float[numComponents]; @@ -153,14 +169,15 @@ public class ImageUtil /** * Offsets an image's alpha component by a given percentage. * - * @param image The image to be made more or less transparent. + * @param rawImg 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) + public static BufferedImage alphaOffset(final Image rawImg, final float percentage) { + BufferedImage image = toARGB(rawImg); final int numComponents = image.getColorModel().getNumComponents(); final float[] scales = new float[numComponents]; final float[] offsets = new float[numComponents]; 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 829e90368b..44dc88d778 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 @@ -81,25 +81,25 @@ public class ImageUtilTest public void grayscaleOffset() { // grayscaleOffset(BufferedImage image, int offset) - assertTrue(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.grayscaleOffset(oneByOne(BLACK), -255))); - assertTrue(bufferedImagesEqual(oneByOne(new Color(50, 50, 50)), ImageUtil.grayscaleOffset(oneByOne(BLACK), 50))); - assertTrue(bufferedImagesEqual(oneByOne(GRAY), ImageUtil.grayscaleOffset(oneByOne(BLACK), 128))); - assertTrue(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.grayscaleOffset(oneByOne(GRAY), -255))); - assertTrue(bufferedImagesEqual(oneByOne(WHITE), ImageUtil.grayscaleOffset(oneByOne(BLACK), 255))); - assertTrue(bufferedImagesEqual(oneByOne(new Color(200, 200, 200)), ImageUtil.grayscaleOffset(oneByOne(WHITE), -55))); - assertTrue(bufferedImagesEqual(oneByOne(WHITE), ImageUtil.grayscaleOffset(oneByOne(WHITE), 55))); + assertTrue(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.luminanceOffset(oneByOne(BLACK), -255))); + assertTrue(bufferedImagesEqual(oneByOne(new Color(50, 50, 50)), ImageUtil.luminanceOffset(oneByOne(BLACK), 50))); + assertTrue(bufferedImagesEqual(oneByOne(GRAY), ImageUtil.luminanceOffset(oneByOne(BLACK), 128))); + assertTrue(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.luminanceOffset(oneByOne(GRAY), -255))); + assertTrue(bufferedImagesEqual(oneByOne(WHITE), ImageUtil.luminanceOffset(oneByOne(BLACK), 255))); + assertTrue(bufferedImagesEqual(oneByOne(new Color(200, 200, 200)), ImageUtil.luminanceOffset(oneByOne(WHITE), -55))); + assertTrue(bufferedImagesEqual(oneByOne(WHITE), ImageUtil.luminanceOffset(oneByOne(WHITE), 55))); // grayscaleOffset(BufferedImage image, float percentage) - assertTrue(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.grayscaleOffset(oneByOne(BLACK), 0f))); - assertTrue(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.grayscaleOffset(oneByOne(BLACK), 1f))); - assertTrue(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.grayscaleOffset(oneByOne(BLACK), 2f))); - assertTrue(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.grayscaleOffset(oneByOne(GRAY), 0f))); - assertTrue(bufferedImagesEqual(oneByOne(GRAY), ImageUtil.grayscaleOffset(oneByOne(GRAY), 1f))); - assertTrue(bufferedImagesEqual(oneByOne(WHITE), ImageUtil.grayscaleOffset(oneByOne(GRAY), 2f))); - assertTrue(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.grayscaleOffset(oneByOne(WHITE), 0f))); - assertTrue(bufferedImagesEqual(oneByOne(GRAY), ImageUtil.grayscaleOffset(oneByOne(WHITE), 0.503f))); // grayscaleOffset does Math.floor - assertTrue(bufferedImagesEqual(oneByOne(WHITE), ImageUtil.grayscaleOffset(oneByOne(WHITE), 1f))); - assertTrue(bufferedImagesEqual(oneByOne(WHITE), ImageUtil.grayscaleOffset(oneByOne(WHITE), 2f))); + assertTrue(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.luminanceScale(oneByOne(BLACK), 0f))); + assertTrue(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.luminanceScale(oneByOne(BLACK), 1f))); + assertTrue(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.luminanceScale(oneByOne(BLACK), 2f))); + assertTrue(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.luminanceScale(oneByOne(GRAY), 0f))); + assertTrue(bufferedImagesEqual(oneByOne(GRAY), ImageUtil.luminanceScale(oneByOne(GRAY), 1f))); + assertTrue(bufferedImagesEqual(oneByOne(WHITE), ImageUtil.luminanceScale(oneByOne(GRAY), 2f))); + assertTrue(bufferedImagesEqual(oneByOne(BLACK), ImageUtil.luminanceScale(oneByOne(WHITE), 0f))); + assertTrue(bufferedImagesEqual(oneByOne(GRAY), ImageUtil.luminanceScale(oneByOne(WHITE), 0.503f))); // grayscaleOffset does Math.floor + assertTrue(bufferedImagesEqual(oneByOne(WHITE), ImageUtil.luminanceScale(oneByOne(WHITE), 1f))); + assertTrue(bufferedImagesEqual(oneByOne(WHITE), ImageUtil.luminanceScale(oneByOne(WHITE), 2f))); } @Test