From 286c25137f8450078438bf443073df615953fe1c Mon Sep 17 00:00:00 2001 From: dragonmacher <48328597+dragonmacher@users.noreply.github.com> Date: Wed, 24 Apr 2019 10:26:32 -0400 Subject: [PATCH] Minor refactoring to move image scaling code to ImageUtils --- .../main/java/docking/util/image/Callout.java | 3 +- .../java/generic/util/image/ImageUtils.java | 106 +++++++++++------- .../main/java/resources/ResourceManager.java | 75 +------------ .../icons/ScaledImageIconWrapper.java | 5 +- ...TestGraphAlgorithmSteppingViewerPanel.java | 6 +- 5 files changed, 73 insertions(+), 122 deletions(-) diff --git a/Ghidra/Framework/Docking/src/main/java/docking/util/image/Callout.java b/Ghidra/Framework/Docking/src/main/java/docking/util/image/Callout.java index 5b1aabe15b..db51026361 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/util/image/Callout.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/util/image/Callout.java @@ -22,7 +22,6 @@ import java.awt.image.BufferedImage; import java.awt.image.VolatileImage; import generic.util.image.ImageUtils; -import resources.ResourceManager; public class Callout { @@ -386,7 +385,7 @@ public class Callout { double magnification = calloutInfo.getMagnification(); int newWidth = (int) (compImage.getWidth(null) * magnification); int newHeight = (int) (compImage.getHeight(null) * magnification); - compImage = ResourceManager.createScaledImage(compImage, newWidth, newHeight, 0); + compImage = ImageUtils.createScaledImage(compImage, newWidth, newHeight, 0); Rectangle bounds = imageShape.getBounds(); VolatileImage image = diff --git a/Ghidra/Framework/Generic/src/main/java/generic/util/image/ImageUtils.java b/Ghidra/Framework/Generic/src/main/java/generic/util/image/ImageUtils.java index 4d246a1cc7..3593cd28b5 100644 --- a/Ghidra/Framework/Generic/src/main/java/generic/util/image/ImageUtils.java +++ b/Ghidra/Framework/Generic/src/main/java/generic/util/image/ImageUtils.java @@ -67,8 +67,10 @@ public class ImageUtils { } /** - * Crops the given image, keeping the given bounds. + * Crops the given image, keeping the given bounds * + * @param i the image to crop + * @param bounds the new bounds * @return a new image based on the given image, cropped to the given bounds. */ public static Image crop(Image i, Rectangle bounds) { @@ -216,15 +218,6 @@ public class ImageUtils { return false; } - private static synchronized JComponent getMediaTrackerComponent() { - if (mediaTrackerComponent == null) { - mediaTrackerComponent = new JComponent() { - // dummy component - }; - } - return mediaTrackerComponent; - } - /** * Write the specified image to file in PNG format * @param i the image to save @@ -299,6 +292,26 @@ public class ImageUtils { return new ImageIcon(newImage); } + /** + * Creates a scaled image based upon the given image. + * NOTE: Avoid invocation by a static initializer. + * @param image the image to scale + * @param width the new width + * @param height the new height + * @param hints {@link RenderingHints} used by {@link Graphics2D} + * @return a scaled version of the given image + */ + public static Image createScaledImage(Image image, int width, int height, int hints) { + BufferedImage scaledImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + Graphics graphics = scaledImage.getGraphics(); + Graphics2D g2 = (Graphics2D) graphics; + g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, + RenderingHints.VALUE_INTERPOLATION_BILINEAR); + graphics.drawImage(image, 0, 0, width, height, null); + graphics.dispose(); + return scaledImage; + } + /** * Creates a disabled version of the given image. The disabled version will be grayed * and have the varying gray levels blended together. @@ -332,38 +345,6 @@ public class ImageUtils { return destImage; } - /** - * Takes in RGB pixel data and then converts the pixel into a gray color with a brightness - * based upon brightnessPercent. - * - * @param rgbPixels The RGB pixel data for a given pixel. - * @param destination The converted pixel data. - * @param brightnessPercent The amount of brightness to include in the gray value, where 100 - * percent is the brightest possible value. - * @return The destination array filled with the new pixel data. - */ - private static int[] filterRgbDisabledImage(int[] rgbPixels, int[] destination, - int brightnessPercent) { - - // preserve the luminance - // Humans have the most sensitivity to green, least sensitivity to blue - int r = (int) (0.30 * (rgbPixels[0] & 0xff)); - int g = (int) (0.59 * (rgbPixels[1] & 0xff)); - int b = (int) (0.11 * (rgbPixels[2] & 0xff)); - - // average the values together to blend the pixels so that the image is not as crisp - int gray = (r + g + b) / 3; - - gray = (255 - ((255 - gray) * (100 - brightnessPercent) / 100)); - gray = MathUtilities.clamp(gray, 0, 255); - - destination[0] = gray; - destination[1] = gray; - destination[2] = gray; - destination[3] = rgbPixels[3]; - return destination; - } - /** * Creates a new image that is the same as the given image but has the given colored * pixels replaced with the given new color @@ -400,6 +381,47 @@ public class ImageUtils { return destImage; } + private static synchronized JComponent getMediaTrackerComponent() { + if (mediaTrackerComponent == null) { + mediaTrackerComponent = new JComponent() { + // dummy component + }; + } + return mediaTrackerComponent; + } + + /** + * Takes in RGB pixel data and then converts the pixel into a gray color with a brightness + * based upon brightnessPercent. + * + * @param rgbPixels The RGB pixel data for a given pixel. + * @param destination The converted pixel data. + * @param brightnessPercent The amount of brightness to include in the gray value, where 100 + * percent is the brightest possible value. + * @return The destination array filled with the new pixel data. + */ + private static int[] filterRgbDisabledImage(int[] rgbPixels, int[] destination, + int brightnessPercent) { + + // preserve the luminance + // Humans have the most sensitivity to green, least sensitivity to blue + int r = (int) (0.30 * (rgbPixels[0] & 0xff)); + int g = (int) (0.59 * (rgbPixels[1] & 0xff)); + int b = (int) (0.11 * (rgbPixels[2] & 0xff)); + + // average the values together to blend the pixels so that the image is not as crisp + int gray = (r + g + b) / 3; + + gray = (255 - ((255 - gray) * (100 - brightnessPercent) / 100)); + gray = MathUtilities.clamp(gray, 0, 255); + + destination[0] = gray; + destination[1] = gray; + destination[2] = gray; + destination[3] = rgbPixels[3]; + return destination; + } + private static int[] filterRgbChangeColor(int[] rgbPixels, int[] destination, int[] oldRgb, int[] newRgb) { diff --git a/Ghidra/Framework/Generic/src/main/java/resources/ResourceManager.java b/Ghidra/Framework/Generic/src/main/java/resources/ResourceManager.java index eb424a3536..910b2e65dd 100644 --- a/Ghidra/Framework/Generic/src/main/java/resources/ResourceManager.java +++ b/Ghidra/Framework/Generic/src/main/java/resources/ResourceManager.java @@ -15,13 +15,13 @@ */ package resources; -import java.awt.*; +import java.awt.Image; +import java.awt.MediaTracker; import java.awt.image.BufferedImage; import java.io.*; import java.net.*; import java.nio.file.Path; import java.util.*; -import java.util.List; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.stream.Collectors; @@ -311,7 +311,7 @@ public class ResourceManager { } //================================================================================================== -// Image Related Methods +// Icon Related Methods //================================================================================================== /** @@ -340,57 +340,6 @@ public class ResourceManager { return new ScaledImageIconWrapper(icon, width, height); } - /** - * This is really a package-level method. From outside of this package you should instead - * be calling {@link ResourceManager#getScaledIcon(Icon, int, int, int)}. - * - * @param icon the icon to scale - * @param width the new width - * @param height the new height - * @param hints any hints to apply to the scaling operation - * @return the new icon - * @deprecated use {@link #getScaledIcon(Icon, int, int, int)} instead - */ - @Deprecated - public static ImageIcon createScaledIcon(Icon icon, int width, int height, int hints) { - return getScaledIcon(icon, width, height, hints); - } - - /** - * This is really a package-level method. From outside of this package you should instead - * be calling {@link ResourceManager#getScaledIcon(Icon, int, int)}. - * - * @param icon the icon to scale - * @param width the new width - * @param height the new height - * @return the new icon - * @deprecated use {@link #getScaledIcon(Icon, int, int, int)} instead - */ - @Deprecated - public static ImageIcon createScaledIcon(Icon icon, int width, int height) { - return getScaledIcon(icon, width, height, Image.SCALE_AREA_AVERAGING); - } - - /** - * Creates a scaled image based upon the given image. - * NOTE: Avoid invocation by a static initializer. - * @param image the image to scale - * @param width the new width - * @param height the new height - * @param hints {@link RenderingHints} used by {@link Graphics2D} - * @return a scaled version of the given image - */ - public static Image createScaledImage(Image image, int width, int height, int hints) { - BufferedImage scaledImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); - Graphics graphics = scaledImage.getGraphics(); - Graphics2D g2 = (Graphics2D) graphics; - g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, - RenderingHints.VALUE_INTERPOLATION_BILINEAR); - graphics.drawImage(image, 0, 0, width, height, null); - graphics.dispose(); - return scaledImage; - } - /** * Get the disabled rendering of the given icon. * @param icon The icon to disable. @@ -421,24 +370,6 @@ public class ResourceManager { return new DisabledImageIconWrapper(icon, brightnessPercent); } - /** - * Algorithm for filtering an image to make it appear disabled - * - *

Note: you should use one of the {@link #getDisabledIcon(Icon)} methods, as this is - * an internal API method. - * - * @param icon the icon - * @param brightnessPercent the percentage of brightness, 0-100, with 100 being the - * brightest possible value - * @return the new icon - * @see #getDisabledIcon(Icon) - * @deprecated use {@link #getDisabledIcon(Icon)} instead - */ - @Deprecated - public static ImageIcon createDisabledIcon(Icon icon, final int brightnessPercent) { - return getDisabledIcon(icon, brightnessPercent); - } - /** * Creates an image icon from the given image. This method will create an ImageIcon * the "safe" way by avoiding the constructor diff --git a/Ghidra/Framework/Generic/src/main/java/resources/icons/ScaledImageIconWrapper.java b/Ghidra/Framework/Generic/src/main/java/resources/icons/ScaledImageIconWrapper.java index eb95945da8..e5dca1e7fa 100644 --- a/Ghidra/Framework/Generic/src/main/java/resources/icons/ScaledImageIconWrapper.java +++ b/Ghidra/Framework/Generic/src/main/java/resources/icons/ScaledImageIconWrapper.java @@ -20,7 +20,7 @@ import java.awt.*; import javax.swing.Icon; import javax.swing.ImageIcon; -import resources.ResourceManager; +import generic.util.image.ImageUtils; public class ScaledImageIconWrapper extends ImageIconWrapper { @@ -58,8 +58,7 @@ public class ScaledImageIconWrapper extends ImageIconWrapper { @Override protected ImageIcon createImageIcon() { ImageIcon baseIcon = super.createImageIcon(); - Image scaledImage = - ResourceManager.createScaledImage(baseIcon.getImage(), width, height, hints); + Image scaledImage = ImageUtils.createScaledImage(baseIcon.getImage(), width, height, hints); return new ImageIcon(scaledImage, getImageName()); } } diff --git a/Ghidra/Framework/Graph/src/test/java/ghidra/graph/algo/viewer/TestGraphAlgorithmSteppingViewerPanel.java b/Ghidra/Framework/Graph/src/test/java/ghidra/graph/algo/viewer/TestGraphAlgorithmSteppingViewerPanel.java index b012c0c880..78f172b30c 100644 --- a/Ghidra/Framework/Graph/src/test/java/ghidra/graph/algo/viewer/TestGraphAlgorithmSteppingViewerPanel.java +++ b/Ghidra/Framework/Graph/src/test/java/ghidra/graph/algo/viewer/TestGraphAlgorithmSteppingViewerPanel.java @@ -27,6 +27,7 @@ import org.apache.commons.collections4.bidimap.DualHashBidiMap; import edu.uci.ics.jung.visualization.decorators.EdgeShape; import edu.uci.ics.jung.visualization.renderers.Renderer; +import generic.util.image.ImageUtils; import ghidra.graph.*; import ghidra.graph.algo.GraphAlgorithmStatusListener; import ghidra.graph.graphs.DefaultVisualGraph; @@ -40,7 +41,6 @@ import ghidra.graph.viewer.vertex.VisualVertexRenderer; import ghidra.util.Msg; import ghidra.util.exception.CancelledException; import ghidra.util.task.SwingUpdateManager; -import resources.ResourceManager; public class TestGraphAlgorithmSteppingViewerPanel> extends JPanel { @@ -212,8 +212,8 @@ public class TestGraphAlgorithmSteppingViewerPanel> extend int h = image.getHeight(); double sw = w * scale; double sh = h * scale; - Image scaledImage = ResourceManager.createScaledImage(image, (int) sw, (int) sh, - Image.SCALE_AREA_AVERAGING); + Image scaledImage = + ImageUtils.createScaledImage(image, (int) sw, (int) sh, Image.SCALE_AREA_AVERAGING); JLabel label = new JLabel(new ImageIcon(scaledImage)); phasesPanel.add(label); });