Add image utility class

This commit is contained in:
Jordan Atwood
2018-07-29 19:37:37 -07:00
parent f0799ffe79
commit 06cd5cd7d0
8 changed files with 369 additions and 86 deletions

View File

@@ -89,7 +89,7 @@ import net.runelite.client.ui.PluginPanel;
import net.runelite.client.ui.components.ComboBoxListRenderer;
import net.runelite.client.ui.components.IconButton;
import net.runelite.client.ui.components.IconTextField;
import net.runelite.client.util.SwingUtil;
import net.runelite.client.util.ImageUtil;
@Slf4j
public class ConfigPanel extends PluginPanel
@@ -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(SwingUtil.grayscaleOffset(backIcon, -100));
BACK_ICON_HOVER = new ImageIcon(ImageUtil.grayscaleOffset(backIcon, -100));
SEARCH = new ImageIcon(ImageIO.read(IconTextField.class.getResourceAsStream("search.png")));
}
}

View File

@@ -45,7 +45,7 @@ import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.ui.PluginPanel;
import net.runelite.client.ui.components.IconButton;
import net.runelite.client.util.SwingUtil;
import net.runelite.client.util.ImageUtil;
import org.apache.commons.text.similarity.JaroWinklerDistance;
class PluginListItem extends JPanel
@@ -98,7 +98,7 @@ class PluginListItem extends JPanel
OFF_STAR = new ImageIcon(ImageIO.read(ConfigPanel.class.getResourceAsStream("stars/off.png")));
}
CONFIG_ICON_HOVER = new ImageIcon(SwingUtil.grayscaleOffset(configIcon, -100));
CONFIG_ICON_HOVER = new ImageIcon(ImageUtil.grayscaleOffset(configIcon, -100));
}
catch (IOException e)
{

View File

@@ -52,7 +52,7 @@ import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.PluginPanel;
import net.runelite.client.util.SwingUtil;
import net.runelite.client.util.ImageUtil;
@Singleton
class KourendLibraryPanel extends PluginPanel
@@ -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(SwingUtil.grayscaleOffset(resetIcon, -100));
RESET_CLICK_ICON = new ImageIcon(ImageUtil.grayscaleOffset(resetIcon, -100));
}
}
catch (IOException e)

View File

@@ -32,8 +32,6 @@ import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Arrays;
@@ -60,6 +58,7 @@ import net.runelite.client.ui.overlay.OverlayPriority;
import net.runelite.client.ui.overlay.OverlayUtil;
import net.runelite.client.ui.overlay.components.BackgroundComponent;
import net.runelite.client.ui.overlay.components.TextComponent;
import net.runelite.client.util.ImageUtil;
@Slf4j
public class PuzzleSolverOverlay extends Overlay
@@ -448,7 +447,7 @@ public class PuzzleSolverOverlay extends Overlay
{
if (upArrow == null)
{
upArrow = getRotatedImage(getDownArrow(), Math.PI);
upArrow = ImageUtil.rotateImage(getDownArrow(), Math.PI);
}
return upArrow;
}
@@ -457,7 +456,7 @@ public class PuzzleSolverOverlay extends Overlay
{
if (leftArrow == null)
{
leftArrow = getRotatedImage(getDownArrow(), Math.PI / 2);
leftArrow = ImageUtil.rotateImage(getDownArrow(), Math.PI / 2);
}
return leftArrow;
}
@@ -466,16 +465,8 @@ public class PuzzleSolverOverlay extends Overlay
{
if (rightArrow == null)
{
rightArrow = getRotatedImage(getDownArrow(), 3 * Math.PI / 2);
rightArrow = ImageUtil.rotateImage(getDownArrow(), 3 * Math.PI / 2);
}
return rightArrow;
}
private BufferedImage getRotatedImage(BufferedImage image, double theta)
{
AffineTransform transform = new AffineTransform();
transform.rotate(theta, image.getWidth() / 2, image.getHeight() / 2);
AffineTransformOp transformOp = new AffineTransformOp(transform, AffineTransformOp.TYPE_BILINEAR);
return transformOp.filter(image, null);
}
}

View File

@@ -55,7 +55,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.FlatTextField;
import net.runelite.client.util.SwingUtil;
import net.runelite.client.util.ImageUtil;
class ScreenMarkerPanel extends JPanel
{
@@ -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(SwingUtil.grayscaleOffset(borderImg, -100));
BORDER_COLOR_HOVER_ICON = new ImageIcon(ImageUtil.grayscaleOffset(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(SwingUtil.grayscaleOffset(noBorderImg, -100));
NO_BORDER_COLOR_HOVER_ICON = new ImageIcon(ImageUtil.grayscaleOffset(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(SwingUtil.grayscaleOffset(fillImg, -100));
FILL_COLOR_HOVER_ICON = new ImageIcon(ImageUtil.grayscaleOffset(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(SwingUtil.grayscaleOffset(noFillImg, -100));
NO_FILL_COLOR_HOVER_ICON = new ImageIcon(ImageUtil.grayscaleOffset(noFillImg, -100));
BufferedImage opacityImg = ImageIO.read(ScreenMarkerPlugin.class.getResourceAsStream("opacity_icon.png"));
FULL_OPACITY_ICON = new ImageIcon(opacityImg);
OPACITY_HOVER_ICON = new ImageIcon(SwingUtil.grayscaleOffset(opacityImg, -100));
NO_OPACITY_ICON = new ImageIcon(SwingUtil.grayscaleOffset(opacityImg, -150));
OPACITY_HOVER_ICON = new ImageIcon(ImageUtil.grayscaleOffset(opacityImg, -100));
NO_OPACITY_ICON = new ImageIcon(ImageUtil.grayscaleOffset(opacityImg, -150));
BufferedImage visibleImg = ImageIO.read(ScreenMarkerPlugin.class.getResourceAsStream("visible_icon.png"));
VISIBLE_ICON = new ImageIcon(visibleImg);
VISIBLE_HOVER_ICON = new ImageIcon(SwingUtil.grayscaleOffset(visibleImg, -100));
VISIBLE_HOVER_ICON = new ImageIcon(ImageUtil.grayscaleOffset(visibleImg, -100));
BufferedImage invisibleImg = ImageIO.read(ScreenMarkerPlugin.class.getResourceAsStream("invisible_icon.png"));
INVISIBLE_ICON = new ImageIcon(invisibleImg);
INVISIBLE_HOVER_ICON = new ImageIcon(SwingUtil.grayscaleOffset(invisibleImg, -100));
INVISIBLE_HOVER_ICON = new ImageIcon(ImageUtil.grayscaleOffset(invisibleImg, -100));
BufferedImage deleteImg = ImageIO.read(ScreenMarkerPlugin.class.getResourceAsStream("delete_icon.png"));
DELETE_ICON = new ImageIcon(deleteImg);
DELETE_HOVER_ICON = new ImageIcon(SwingUtil.grayscaleOffset(deleteImg, -100));
DELETE_HOVER_ICON = new ImageIcon(ImageUtil.grayscaleOffset(deleteImg, -100));
}
}
catch (IOException e)

View File

@@ -0,0 +1,112 @@
/*
* Copyright (c) 2018, Jordan Atwood <jordan.atwood423@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.util;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.RescaleOp;
import java.util.Arrays;
/**
* Various Image/BufferedImage utilities.
*/
public class ImageUtil
{
/**
* Offsets an image in the grayscale (darkens/brightens) by a given offset.
*
* @param image 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)
{
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);
for (int i = 0; i < numComponents; i++)
{
offsets[i] = offsetFloat;
}
// Set alpha to not offset
offsets[numComponents - 1] = 0f;
return offset(image, scales, offsets);
}
/**
* Re-size a BufferedImage to the given dimensions.
*
* @param image the BufferedImage.
* @param newWidth The width to set the BufferedImage to.
* @param newHeight The height to set the BufferedImage to.
* @return The BufferedImage with the specified dimensions
*/
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;
}
/**
* Rotates an image around its center by a given number of radians.
*
* @param image The image to be rotated.
* @param theta The number of radians to rotate the image.
* @return The given image, rotated by the given theta.
*/
public static BufferedImage rotateImage(final BufferedImage image, final double theta)
{
AffineTransform transform = new AffineTransform();
transform.rotate(theta, image.getWidth() / 2.0, image.getHeight() / 2.0);
AffineTransformOp transformOp = new AffineTransformOp(transform, AffineTransformOp.TYPE_BILINEAR);
return transformOp.filter(image, null);
}
/**
* Performs a rescale operation on the image's color components.
*
* @param image The image to be adjusted.
* @param scales An array of scale operations to be performed on the image's color components.
* @param offsets An array of offset operations to be performed on the image's color components.
* @return The modified image after applying the given adjustments.
*/
private static BufferedImage offset(final BufferedImage image, final float[] scales, final float[] offsets)
{
return new RescaleOp(scales, offsets, null).filter(image, null);
}
}

View File

@@ -29,7 +29,6 @@ import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.SystemTray;
@@ -41,8 +40,6 @@ import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.awt.image.RescaleOp;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.concurrent.Callable;
import java.util.function.BiConsumer;
@@ -105,27 +102,6 @@ public class SwingUtil
System.setProperty("sun.awt.noerasebackground", "true");
}
/**
* Offsets an image in the grayscale (darkens/brightens) by an offset
*/
public static BufferedImage grayscaleOffset(BufferedImage image, 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);
for (int i = 0; i < numComponents; i++)
{
offsets[i] = offsetFloat;
}
// Set alpha to not offset
offsets[numComponents - 1] = 0f;
return offset(image, scales, offsets);
}
/**
* Safely sets Swing theme
*
@@ -266,25 +242,6 @@ public class SwingUtil
});
}
/**
* Re-size a BufferedImage to the given dimensions.
*
* @param image the BufferedImage.
* @param newWidth The width to set the BufferedImage to.
* @param newHeight The height to set the BufferedImage to.
* @return The BufferedImage with the specified dimensions
*/
private static BufferedImage resizeImage(BufferedImage image, int newWidth, 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;
}
/**
* Create swing button from navigation button.
*
@@ -300,7 +257,7 @@ public class SwingUtil
{
final BufferedImage scaledImage = iconSize > 0
? resizeImage(navigationButton.getIcon(), iconSize, iconSize)
? ImageUtil.resizeImage(navigationButton.getIcon(), iconSize, iconSize)
: navigationButton.getIcon();
final JButton button = new JButton();
@@ -350,17 +307,4 @@ public class SwingUtil
{
return SubstanceCoreUtilities.getTitlePaneComponent(frame) != null;
}
/**
* Performs a rescale operation on the image's color components.
*
* @param image The image to be adjusted.
* @param scales An array of scale operations to be performed on the image's color components.
* @param offsets An array of offset operations to be performed on the image's color components.
* @return The modified image after applying the given adjustments.
*/
private static BufferedImage offset(final BufferedImage image, final float[] scales, final float[] offsets)
{
return new RescaleOp(scales, offsets, null).filter(image, null);
}
}