Ahh, you want to cut portion of an image out using a mask, my bad.
The simply solution - use a alpha based mask to start with. But I assume you don't have that option. I did try finding a solution which might do that, but instead, stumbled across this example instead.
Which is capable of producing the result you seem to be looking for

(blue is the background color of the panel)
The core functionality comes do to...
public void applyGrayscaleMaskToAlpha(BufferedImage image, BufferedImage mask) {
int width = image.getWidth();
int height = image.getHeight();
int[] imagePixels = image.getRGB(0, 0, width, height, null, 0, width);
int[] maskPixels = mask.getRGB(0, 0, width, height, null, 0, width);
for (int i = 0; i < imagePixels.length; i++) {
int color = imagePixels[i] & 0x00ffffff; // Mask preexisting alpha
int alpha = maskPixels[i] << 24; // Shift blue to alpha
imagePixels[i] = color | alpha;
}
image.setRGB(0, 0, width, height, imagePixels, 0, width);
}
But as a simple runnable example...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public void applyGrayscaleMaskToAlpha(BufferedImage image, BufferedImage mask) {
int width = image.getWidth();
int height = image.getHeight();
int[] imagePixels = image.getRGB(0, 0, width, height, null, 0, width);
int[] maskPixels = mask.getRGB(0, 0, width, height, null, 0, width);
for (int i = 0; i < imagePixels.length; i++) {
int color = imagePixels[i] & 0x00ffffff; // Mask preexisting alpha
int alpha = maskPixels[i] << 24; // Shift blue to alpha
imagePixels[i] = color | alpha;
}
image.setRGB(0, 0, width, height, imagePixels, 0, width);
}
public class TestPane extends JPanel {
private BufferedImage master;
private BufferedImage mask;
public TestPane() {
setBackground(Color.BLUE);
try {
master = ImageIO.read(new File("..."));
mask = ImageIO.read(new File("..."));
applyGrayscaleMaskToAlpha(master, mask);
} catch (IOException exp) {
exp.printStackTrace();
}
}
@Override
public Dimension getPreferredSize() {
Dimension size = super.getPreferredSize();
if (master != null && mask != null) {
size = new Dimension(master.getWidth() + mask.getWidth(), Math.max(master.getHeight(), mask.getHeight()));
}
return size;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int x = (getWidth() - (master.getWidth() + mask.getWidth())) / 2;
int y = (getHeight() - master.getHeight()) / 2;
g.drawImage(master, x, y, this);
x += mask.getWidth();
y = (getHeight() - mask.getHeight()) / 2;
g.drawImage(mask, x, y, this);
}
}
}
Sorry for the confusion
Updated - without "manipulating the data buffers"
I was looking for the Java API way of doing the same job without manipuating the bits
Okay, so I'd also prefer a solution which generated a alpha based image from a gray scale image, it fits better with the overall Graphics 2D API. So, after a little more reading of this question which keeps on giving, I stumbled across this idea...
public static BufferedImage grayScaleToTransparency(BufferedImage master) {
ImageFilter filter = new RGBImageFilter() {
public final int filterRGB(int x, int y, int rgb) {
return (rgb << 16) & 0xFF000000;
}
};
ImageProducer ip = new FilteredImageSource(master.getSource(), filter);
Image img = Toolkit.getDefaultToolkit().createImage(ip);
BufferedImage buffer = createCompatibleImage(img.getWidth(null), img.getHeight(null), Transparency.TRANSLUCENT);
Graphics2D g2d = buffer.createGraphics();
g2d.drawImage(img, 0, 0, null);
g2d.dispose();
return buffer;
}
Now, there might be away to get this using BufferedImageFilter
along with a BufferedImageOp
but I don't have the time or experience to investigate it further.
Using this technique I was able to produce...

Original Image | Original (gray scale) mask | Alpha based Mask | Masked image
Again, the blue is the background color of the panel.
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.awt.image.ImageProducer;
import java.awt.image.RGBImageFilter;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public static GraphicsConfiguration getGraphicsConfiguration() {
return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
}
public static BufferedImage createCompatibleImage(int width, int height, int transparency) {
BufferedImage image = getGraphicsConfiguration().createCompatibleImage(width, height, transparency);
image.coerceData(true);
return image;
}
public static void applyQualityRenderingHints(Graphics2D g2d) {
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
}
public static BufferedImage applyMask(BufferedImage master, BufferedImage mask) {
int imgWidth = master.getWidth();
int imgHeight = master.getHeight();
BufferedImage imgMask = createCompatibleImage(imgWidth, imgHeight, Transparency.TRANSLUCENT);
Graphics2D g2 = imgMask.createGraphics();
applyQualityRenderingHints(g2);
g2.drawImage(mask, 0, 0, null);
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN, 1f));
g2.drawImage(master, 0, 0, null);
g2.dispose();
return imgMask;
}
public static BufferedImage grayScaleToTransparency(BufferedImage master) {
ImageFilter filter = new RGBImageFilter() {
public final int filterRGB(int x, int y, int rgb) {
return (rgb << 16) & 0xFF000000;
}
};
ImageProducer ip = new FilteredImageSource(master.getSource(), filter);
Image img = Toolkit.getDefaultToolkit().createImage(ip);
BufferedImage buffer = createCompatibleImage(img.getWidth(null), img.getHeight(null), Transparency.TRANSLUCENT);
Graphics2D g2d = buffer.createGraphics();
g2d.drawImage(img, 0, 0, null);
g2d.dispose();
return buffer;
}
public class TestPane extends JPanel {
private BufferedImage master;
private BufferedImage originalMask;
private BufferedImage alphaMask;
private BufferedImage masked;
public TestPane() {
setBackground(Color.BLUE);
try {
master = ImageIO.read(new File("/Users/swhitehead/Downloads/lIceL.png"));
originalMask = ImageIO.read(new File("/Users/swhitehead/Downloads/MXmFp.png"));
alphaMask = grayScaleToTransparency(originalMask);
masked = applyMask(master, alphaMask);
// tinted = tint(master, mask);
} catch (IOException exp) {
exp.printStackTrace();
}
}
protected int desiredWidth() {
return master.getWidth() + originalMask.getWidth() + alphaMask.getWidth() + masked.getWidth();
}
protected int desiredHeight() {
return Math.max(Math.max(Math.max(master.getHeight(), originalMask.getHeight()), alphaMask.getHeight()), masked.getHeight());
}
@Override
public Dimension getPreferredSize() {
Dimension size = super.getPreferredSize();
if (master != null && originalMask != null) {
size = new Dimension(desiredWidth(),
desiredHeight());
}
return size;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int x = (getWidth() - desiredWidth()) / 2;
int y = (getHeight() - master.getHeight()) / 2;
g.drawImage(master, x, y, this);
x += originalMask.getWidth();
y = (getHeight() - originalMask.getHeight()) / 2;
g.drawImage(originalMask, x, y, this);
x += alphaMask.getWidth();
y = (getHeight() - alphaMask.getHeight()) / 2;
g.drawImage(alphaMask, x, y, this);
x += masked.getWidth();
y = (getHeight() - masked.getHeight()) / 2;
g.drawImage(masked, x, y, this);
}
}
}