Dibujo de imágenes transparentes en Java Graphics2D
(1)
Estás usando la regla incorrecta, no uses AlphaComposite.CLEAR.
La API de AlphaComposite dice esto acerca de CLEAR:
Se borran tanto el color como el alfa del destino (regla Porter-Duff Clear). Ni la fuente ni el destino se utilizan como entrada.
Así que esto hará que la imagen desaparezca. Experimenta con otras reglas. Mientras estabas creando tu SSCCE, yo creé el mío. Vea qué sucede cuando comenta la línea de una regla para la otra. Por ejemplo cambiar esto
// int rule = AlphaComposite.CLEAR;
int rule = AlphaComposite.SRC_OVER;
a esto:
int rule = AlphaComposite.CLEAR;
// int rule = AlphaComposite.SRC_OVER;
Todo el SSCCE:
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.image.BufferedImage;
import javax.swing.*;
public class TestAlphaComposite extends JPanel {
private static final int PREF_W = 400;
private static final int PREF_H = PREF_W;
private static final Stroke BASIC_STROKE = new BasicStroke(6f);
BufferedImage backgroundImage;
BufferedImage overlayImage;
public TestAlphaComposite() {
backgroundImage = createBackGroundImage();
overlayImage = createOverlayImage();
}
private BufferedImage createBackGroundImage() {
BufferedImage img = new BufferedImage(PREF_W, PREF_H,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = img.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setStroke(BASIC_STROKE);
g2.setColor(Color.blue);
int circleCount = 10;
for (int i = 0; i < circleCount ; i++) {
int x = (i * PREF_W) / (2 * circleCount);
int y = x;
int w = PREF_W - 2 * x;
int h = w;
g2.drawOval(x, y, w, h);
}
g2.dispose();
return img;
}
private BufferedImage createOverlayImage() {
BufferedImage img = new BufferedImage(PREF_W, PREF_H,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = img.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setStroke(BASIC_STROKE);
g2.setColor(Color.red);
int circleCount = 10;
for (int i = 0; i < circleCount + 1; i++) {
int x1 = (i * PREF_W) / (circleCount);
int y1 = 0;
int x2 = PREF_W - x1;
int y2 = PREF_H;
float alpha = (float)i / circleCount;
if (alpha > 1f) {
alpha = 1f;
}
// int rule = AlphaComposite.CLEAR;
int rule = AlphaComposite.SRC_OVER;
Composite comp = AlphaComposite.getInstance(rule , alpha );
g2.setComposite(comp );
g2.drawLine(x1, y1, x2, y2);
}
g2.dispose();
return img;
}
@Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (backgroundImage != null) {
g.drawImage(backgroundImage, 0, 0, null);
}
if (overlayImage != null) {
g.drawImage(overlayImage, 0, 0, null);
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("TestAlphaComposite");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new TestAlphaComposite());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Por cierto, su SSCCE no es un verdadero SSCCE. No hay forma de que cualquiera de nosotros pueda compilar o ejecutar ese código ya que tiene dependencias a las que no tenemos acceso, a saber, "com.blazingkin.atrox.ScreenManager". Si necesita nuestra ayuda en el futuro, querrá escribir sscce''s mejor conformes.
Quiero dibujar una imagen PARCIALMENTE transparente encima de otra (Hacer sombras sobre cosas). Actualmente estoy usando la clase Graphics2D de java para renderizar, me han dicho que establezca el compuesto en AlphaComposite, pero eso solo lo establece completamente transparente.
¿Puedo hacer esto con mi configuración actual? ¿Qué tengo que hacer para solucionar esto?
Este es el código que me dijeron que lo haría parcialmente transparente:
AlphaComposite ac = java.awt.AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.5F);
g.setComposite(ac);
(Estoy usando imágenes png por cierto)
Aquí está su experiencia (todas son de diferentes clases, pero las puse juntas por simplicidad) (Yo uso una imagen llamada "Prueba" en la carpeta local "Imágenes", puede usar lo que sea, siempre que sea una imagen png llamada lo mismo
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.DisplayMode;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Window;
import javax.swing.ImageIcon;
import com.blazingkin.atrox.ScreenManager;
public class AtroxAdventrum{
public static void main(String[] args) {
new AtroxAdventrum().run();
}
private static DisplayMode modes[] = {
//new DisplayMode(1080,720,32,0),
//new DisplayMode(1080,720,24,0),
//new DisplayMode(1080,720,16,0),
//new DisplayMode(1440,900,32,0),
//new DisplayMode(1440,900,24,0),
//new DisplayMode(1440,900,16,0),
};
private boolean running = true;
public ScreenManager s;
public void stop(){
running = false;
}
public void run(){
try{
init();
gameLoop();
}finally{
s.restoreScreen();
}
}
public void init(){
s = new ScreenManager();
DisplayMode dm = s.findFirstCompatibleMode(modes);
s.setFullScreen(dm);
Window w = s.getFullScreenWindow();
w.setFont(new Font("Arial", Font.PLAIN, 20));
w.setBackground(Color.black);
w.setForeground(Color.white);
}
public void gameLoop(){
long startTime = System.currentTimeMillis();
long cumTime = startTime;
while (running)
{
long timePassed = System.currentTimeMillis() - cumTime;
cumTime += timePassed;
if (limitfps){
try{
Thread.sleep(15);
}catch(Exception e){}
}
update(timePassed);
Graphics2D g = s.getGraphics();
draw(g);
g.dispose();
s.update();
}
}
public void update(long timePassed){
}
public boolean limitfps = false;
public void draw(Graphics2D g){
g.clearRect(0, 0, s.getWidth(), s.getHeight());
AlphaComposite ac = java.awt.AlphaComposite.getInstance(AlphaComposite.CLEAR,0.5F);
g.setComposite(ac);
g.drawImage(new ImageIcon("Images/Test.png").getImage(), 30, 30, 30, 30, null);
}
}
Si ejecuta esto, tendrá que presionar alt + tab y finalizar el proceso (ya que no tiene nada en esta parte del código para hacer eso)