Minor refactoring to move image scaling code to ImageUtils

This commit is contained in:
dragonmacher 2019-04-24 10:26:32 -04:00
parent 24313e73ee
commit 286c25137f
5 changed files with 73 additions and 122 deletions

View File

@ -22,7 +22,6 @@ import java.awt.image.BufferedImage;
import java.awt.image.VolatileImage; import java.awt.image.VolatileImage;
import generic.util.image.ImageUtils; import generic.util.image.ImageUtils;
import resources.ResourceManager;
public class Callout { public class Callout {
@ -386,7 +385,7 @@ public class Callout {
double magnification = calloutInfo.getMagnification(); double magnification = calloutInfo.getMagnification();
int newWidth = (int) (compImage.getWidth(null) * magnification); int newWidth = (int) (compImage.getWidth(null) * magnification);
int newHeight = (int) (compImage.getHeight(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(); Rectangle bounds = imageShape.getBounds();
VolatileImage image = VolatileImage image =

View File

@ -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. * @return a new image based on the given image, cropped to the given bounds.
*/ */
public static Image crop(Image i, Rectangle bounds) { public static Image crop(Image i, Rectangle bounds) {
@ -216,15 +218,6 @@ public class ImageUtils {
return false; 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 * Write the specified image to file in PNG format
* @param i the image to save * @param i the image to save
@ -299,6 +292,26 @@ public class ImageUtils {
return new ImageIcon(newImage); 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 * Creates a disabled version of the given image. The disabled version will be grayed
* and have the varying gray levels blended together. * and have the varying gray levels blended together.
@ -332,38 +345,6 @@ public class ImageUtils {
return destImage; return destImage;
} }
/**
* Takes in RGB pixel data and then converts the pixel into a gray color with a brightness
* based upon <tt>brightnessPercent</tt>.
*
* @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 <tt>destination</tt> 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 * Creates a new image that is the same as the given image but has the given colored
* pixels replaced with the given new color * pixels replaced with the given new color
@ -400,6 +381,47 @@ public class ImageUtils {
return destImage; 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 <tt>brightnessPercent</tt>.
*
* @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 <tt>destination</tt> 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, private static int[] filterRgbChangeColor(int[] rgbPixels, int[] destination, int[] oldRgb,
int[] newRgb) { int[] newRgb) {

View File

@ -15,13 +15,13 @@
*/ */
package resources; package resources;
import java.awt.*; import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.*; import java.io.*;
import java.net.*; import java.net.*;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.*; import java.util.*;
import java.util.List;
import java.util.jar.JarEntry; import java.util.jar.JarEntry;
import java.util.jar.JarFile; import java.util.jar.JarFile;
import java.util.stream.Collectors; 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); 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. * Get the disabled rendering of the given icon.
* @param icon The icon to disable. * @param icon The icon to disable.
@ -421,24 +370,6 @@ public class ResourceManager {
return new DisabledImageIconWrapper(icon, brightnessPercent); return new DisabledImageIconWrapper(icon, brightnessPercent);
} }
/**
* Algorithm for filtering an image to make it appear disabled
*
* <P>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 <tt>ImageIcon</tt> * Creates an image icon from the given image. This method will create an <tt>ImageIcon</tt>
* the <a href="safe">"safe"</a> way by avoiding the constructor * the <a href="safe">"safe"</a> way by avoiding the constructor

View File

@ -20,7 +20,7 @@ import java.awt.*;
import javax.swing.Icon; import javax.swing.Icon;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
import resources.ResourceManager; import generic.util.image.ImageUtils;
public class ScaledImageIconWrapper extends ImageIconWrapper { public class ScaledImageIconWrapper extends ImageIconWrapper {
@ -58,8 +58,7 @@ public class ScaledImageIconWrapper extends ImageIconWrapper {
@Override @Override
protected ImageIcon createImageIcon() { protected ImageIcon createImageIcon() {
ImageIcon baseIcon = super.createImageIcon(); ImageIcon baseIcon = super.createImageIcon();
Image scaledImage = Image scaledImage = ImageUtils.createScaledImage(baseIcon.getImage(), width, height, hints);
ResourceManager.createScaledImage(baseIcon.getImage(), width, height, hints);
return new ImageIcon(scaledImage, getImageName()); return new ImageIcon(scaledImage, getImageName());
} }
} }

View File

@ -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.decorators.EdgeShape;
import edu.uci.ics.jung.visualization.renderers.Renderer; import edu.uci.ics.jung.visualization.renderers.Renderer;
import generic.util.image.ImageUtils;
import ghidra.graph.*; import ghidra.graph.*;
import ghidra.graph.algo.GraphAlgorithmStatusListener; import ghidra.graph.algo.GraphAlgorithmStatusListener;
import ghidra.graph.graphs.DefaultVisualGraph; import ghidra.graph.graphs.DefaultVisualGraph;
@ -40,7 +41,6 @@ import ghidra.graph.viewer.vertex.VisualVertexRenderer;
import ghidra.util.Msg; import ghidra.util.Msg;
import ghidra.util.exception.CancelledException; import ghidra.util.exception.CancelledException;
import ghidra.util.task.SwingUpdateManager; import ghidra.util.task.SwingUpdateManager;
import resources.ResourceManager;
public class TestGraphAlgorithmSteppingViewerPanel<V, E extends GEdge<V>> extends JPanel { public class TestGraphAlgorithmSteppingViewerPanel<V, E extends GEdge<V>> extends JPanel {
@ -212,8 +212,8 @@ public class TestGraphAlgorithmSteppingViewerPanel<V, E extends GEdge<V>> extend
int h = image.getHeight(); int h = image.getHeight();
double sw = w * scale; double sw = w * scale;
double sh = h * scale; double sh = h * scale;
Image scaledImage = ResourceManager.createScaledImage(image, (int) sw, (int) sh, Image scaledImage =
Image.SCALE_AREA_AVERAGING); ImageUtils.createScaledImage(image, (int) sw, (int) sh, Image.SCALE_AREA_AVERAGING);
JLabel label = new JLabel(new ImageIcon(scaledImage)); JLabel label = new JLabel(new ImageIcon(scaledImage));
phasesPanel.add(label); phasesPanel.add(label);
}); });