I am trying to change the alpha value of an image, I have the code
public void changeImage (File currentImage) throws IOException {
BufferedImage img = ImageIO.read(currentImage);
for (int y = 0; y < img.getHeight(); y ) {
for (int x = 0; x < img.getWidth(); x ) {
int pixel = img.getRGB(x,y);
Color color = new Color(pixel);
int red = 10;
int green = 20;
int blue = 30;
int alpha = 40;
color = new Color(red, green, blue, alpha);
img.setRGB(x, y, color.getRGB());
}
}
File outputImage = new File(currentImage.getAbsolutePath().substring(0, currentImage.getAbsolutePath().length() - 4) "_encrypted.png");
ImageIO.write(img, "png", outputImage);
}
The colors change just fine and when I get Java to print the new photo's alpha value, it says it's 40 but it doesn't look less transparent at all. Like the colors obviously change but the transparency does not.
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
public static BufferedImage changeImage(BufferedImage master) {
BufferedImage img = new BufferedImage(master.getWidth(), master.getHeight(), BufferedImage.TYPE_INT_ARGB);
for (int y = 0; y < img.getHeight(); y ) {
for (int x = 0; x < img.getWidth(); x ) {
int pixel = master.getRGB(x, y);
Color color = new Color(pixel);
int red = color.getRed();
int green = color.getGreen();
int blue = color.getBlue();
int alpha = 40;
color = new Color(red, green, blue, alpha);
img.setRGB(x, y, color.getRGB());
}
}
return img;
}
public class TestPane extends JPanel {
private BufferedImage master;
private BufferedImage modified;
private BufferedImage alphaed;
public TestPane() throws IOException {
master = ImageIO.read(getClass().getResource("/images/MegaTokyo.png"));
modified = changeImage(master);
alphaed = new BufferedImage(master.getWidth(), master.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = alphaed.createGraphics();
g2d.setComposite(AlphaComposite.SrcOver.derive(0.156862745098039f));
g2d.drawImage(master, 0, 0, this);
g2d.dispose();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(master.getWidth() * 3, master.getHeight());
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.drawImage(master, 0, 0, this);
g2d.drawImage(modified, master.getWidth(), 0, this);
g2d.drawImage(alphaed, master.getWidth() * 2, 0, this);
g2d.dispose();
}
}
}
Now, it occurs to me that you might be trying to put a color "overlay" on top of the image
In which case you try doing something like...
BufferedImage colorOverlay = new BufferedImage(master.getWidth(), master.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = colorOverlay.createGraphics();
g2d.setColor(new Color(10, 20, 30, 192));
g2d.fillRect(0, 0, colorOverlay.getWidth(), colorOverlay.getHeight());
g2d.dispose();
alphaed = new BufferedImage(master.getWidth(), master.getHeight(), BufferedImage.TYPE_INT_ARGB);
g2d = alphaed.createGraphics();
g2d.drawImage(master, 0, 0, this);
g2d.drawImage(colorOverlay, 0, 0, this);
g2d.dispose();
which could be simplifed to something like...
alphaed = new BufferedImage(master.getWidth(), master.getHeight(), BufferedImage.TYPE_INT_ARGB);
g2d = alphaed.createGraphics();
g2d.drawImage(master, 0, 0, this);
g2d.setComposite(AlphaComposite.SrcOver.derive(0.75f));
g2d.setColor(new Color(10, 20, 30, 192));
g2d.fillRect(0, 0, alphaed.getWidth(), alphaed.getHeight());
g2d.dispose();
(nb: I tried using 40
as the alpha component, but it made such little difference, I changed it to 192
for demonstration purposes)
Runnable example
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
public static BufferedImage changeImage(BufferedImage master) {
BufferedImage img = new BufferedImage(master.getWidth(), master.getHeight(), BufferedImage.TYPE_INT_ARGB);
for (int y = 0; y < img.getHeight(); y ) {
for (int x = 0; x < img.getWidth(); x ) {
int pixel = master.getRGB(x, y);
Color color = new Color(pixel);
int red = color.getRed();
int green = color.getGreen();
int blue = color.getBlue();
int alpha = 40;
color = new Color(red, green, blue, alpha);
img.setRGB(x, y, color.getRGB());
}
}
return img;
}
public class TestPane extends JPanel {
private BufferedImage master;
private BufferedImage alphaed;
public TestPane() throws IOException {
master = ImageIO.read(getClass().getResource("/images/MegaTokyo.png"));
//--- This -----
BufferedImage colorOverlay = new BufferedImage(master.getWidth(), master.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = colorOverlay.createGraphics();
g2d.setColor(new Color(10, 20, 30, 192));
g2d.fillRect(0, 0, colorOverlay.getWidth(), colorOverlay.getHeight());
g2d.dispose();
alphaed = new BufferedImage(master.getWidth(), master.getHeight(), BufferedImage.TYPE_INT_ARGB);
g2d = alphaed.createGraphics();
g2d.drawImage(master, 0, 0, this);
g2d.drawImage(colorOverlay, 0, 0, this);
g2d.dispose();
//--------------
//--- Or This -----
// alphaed = new BufferedImage(master.getWidth(), master.getHeight(), BufferedImage.TYPE_INT_ARGB);
// g2d = alphaed.createGraphics();
// g2d.drawImage(master, 0, 0, this);
// g2d.setComposite(AlphaComposite.SrcOver.derive(0.75f));
// g2d.setColor(new Color(10, 20, 30, 192));
// g2d.fillRect(0, 0, alphaed.getWidth(), alphaed.getHeight());
// g2d.dispose();
//-----------------
}
@Override
public Dimension getPreferredSize() {
return new Dimension(master.getWidth() * 2, master.getHeight());
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.drawImage(master, 0, 0, this);
g2d.drawImage(alphaed, master.getWidth(), 0, this);
g2d.dispose();
}
}
}
CodePudding user response:
Check the type of the original image that you are loading. The image you've linked is of type 5 (TYPE_3BYTE_BGR).
The definition of TYPE_3BYTE_BGR from Javadocs is as follows:
Represents an image with 8-bit RGB color components, corresponding to a Windows-style BGR color model) with the colors Blue, Green, and Red stored in 3 bytes. There is no alpha. The image has a ComponentColorModel. When data with non-opaque alpha is stored in an image of this type, the color data must be adjusted to a non-premultiplied form and the alpha discarded, as described in the java.awt.AlphaComposite documentation.
Make sure that you are either loading in an image that has a type that supports the alpha channel, or convert your image to one of such a type.
Otherwise, what you are doing is correct.