draw transparent componet on bufferedimage?

A

aksel.schmidt

i have a component living in the glasspane, partly transparent to
allow see through to the background

now i want to take a 'snapshot' of the transparent component to make
som animations in the glasspane with (slide transition etc.) - but i
cannot make the transparency information appear on the buffered image
- i use:

public static BufferedImage createImage(JComponent component) {
Dimension d = component.getSize();
if (d.width == 0) {
d = component.getPreferredSize();
component.setSize(d);
}

GraphicsEnvironment ge =
GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gs = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gs.getDefaultConfiguration();

BufferedImage image = gc.createCompatibleImage(d.width,
d.height, Transparency.TRANSLUCENT);
Graphics2D g2d = image.createGraphics();
component.paint(g2d);
g2d.dispose();
return image;
}

how do i paint a transparent component on an image?

thanks!

Aksel,
denmark
 
K

Knute Johnson

aksel.schmidt said:
i have a component living in the glasspane, partly transparent to
allow see through to the background

now i want to take a 'snapshot' of the transparent component to make
som animations in the glasspane with (slide transition etc.) - but i
cannot make the transparency information appear on the buffered image
- i use:

public static BufferedImage createImage(JComponent component) {
Dimension d = component.getSize();
if (d.width == 0) {
d = component.getPreferredSize();
component.setSize(d);
}

GraphicsEnvironment ge =
GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gs = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gs.getDefaultConfiguration();

BufferedImage image = gc.createCompatibleImage(d.width,
d.height, Transparency.TRANSLUCENT);
Graphics2D g2d = image.createGraphics();
component.paint(g2d);
g2d.dispose();
return image;
}

how do i paint a transparent component on an image?

thanks!

Aksel,
denmark

Aksel:

It's not really clear what you want to do. An image can have
transparent pixels. Is the component.paint() that you are referencing
above draw transparent pixels onto the component? It is also possible
to draw an image using an AlphaComposite with less than 100% to create a
transparent look. We either need more code or a better explanation.
 
A

aksel.schmidt

We either need more code or a better explanation.
The component i want to 'snapshot' is made of a jpanel with a alpha
value background (half see through) - with other components on it
(more alpha values here) - so it is not simply transparent/not
transparent pixels on the component
/aksel
 
K

Knute Johnson

aksel.schmidt said:
The component i want to 'snapshot' is made of a jpanel with a alpha
value background (half see through) - with other components on it
(more alpha values here) - so it is not simply transparent/not
transparent pixels on the component
/aksel

I'm still not sure what you are trying to do Aksel. But try this and
let me know if that is the direction you are trying to go.

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
import javax.swing.*;

public class test5 extends JPanel {
public test5() {
setLayout(new FlowLayout());

JLabel l = new JLabel("Label");
l.setOpaque(false);
add(l);

JTextField tf = new JTextField("TextField");
tf.setOpaque(false);
add(tf);

JButton b = new JButton("Image");
b.setOpaque(false); // i think this is overridden by laf
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
BufferedImage bi = new
BufferedImage(getWidth(),getHeight(),
BufferedImage.TYPE_INT_BGR);
Graphics g = bi.createGraphics();
test5.this.paint(g);
try {
ImageIO.write(bi,"JPEG",new File("test.jpg"));
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
});
add(b);
}

public void paintComponent(Graphics g) {
super.paintComponent(g);

g.setColor(new Color(0,0,255,50));
g.fillRect(0,0,getWidth(),getHeight());
g.setColor(Color.BLACK);
g.drawLine(0,0,getWidth(),getHeight());
g.drawLine(getWidth(),0,0,getHeight());
g.drawLine(0,getHeight()/2,getWidth(),getHeight()/2);
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
test5 t5 = new test5();
f.add(t5);
f.pack();
f.setVisible(true);
}
});
}
}
 
A

aksel.schmidt

thanks for the effort
this code explains my problem:
when i press the button, i want to copy a panel (living in the
glasspane on the left side) into an image and be able to draw this
image on the right side - completely with alpha values etc.
what it does right now is just removing the alpha values...

import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Transparency;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;

public class CreateImageTest {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

JPanel panel = new JPanel();
final JPanel panel1 = new JPanel();
final JPanel panel2 = new JPanel();

JButton b = new JButton("copy");
final JLabel label2 = new JLabel();
label2.setOpaque(false);
b.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Image c = createImage(panel1);
label2.setIcon(new ImageIcon(c));
panel2.repaint();
}
});
panel1.add(b);
panel1.add(new JLabel("haj"));
panel1.add(new MyAplhaComponent());
panel1.setOpaque(false);

Dimension preferedSize = new Dimension(100, 100);
panel1.setPreferredSize(preferedSize);

panel2.add(label2);
panel2.setPreferredSize(preferedSize);
panel2.setOpaque(false);
panel2.setBackground(Color.BLUE);

panel.add(panel1);
panel.add(panel2);
panel.setBackground(Color.GREEN);
panel.setOpaque(false);
frame.setGlassPane(panel);
frame.getGlassPane().setVisible(true);
JPanel backgroundPanel = new JPanel();
JTextArea textArea = new JTextArea("iufpf w fw ffjoifopfree ef
\n" + ", joiewfeeffjepfie wfeifoewfjepf e\n"
+ " huep heufhfewfeefehufehfueoie\n" + "w
eifehfwefefheo");
textArea.setPreferredSize(new Dimension(200, 200));
backgroundPanel.add(textArea);
frame.getContentPane().add(backgroundPanel,
BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}

public static BufferedImage createImage(JComponent component) {
Dimension d = component.getSize();
if (d.width == 0) {
d = component.getPreferredSize();
component.setSize(d);
}

// GraphicsEnvironment ge =
GraphicsEnvironment.getLocalGraphicsEnvironment();
// GraphicsDevice gs = ge.getDefaultScreenDevice();
// GraphicsConfiguration gc = gs.getDefaultConfiguration();
//
// BufferedImage image = gc.createCompatibleImage(d.width,
d.height, Transparency.TRANSLUCENT);
// Graphics2D g2d = image.createGraphics();
// component.paint(g2d);
// g2d.dispose();

BufferedImage bi = new BufferedImage(d.width, d.height,
BufferedImage.TYPE_INT_BGR);
Graphics g = bi.createGraphics();
component.paint(g);
return bi;
}

public static class MyAplhaComponent extends JComponent {
{
setPreferredSize(new Dimension(40, 40));
}

@Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g.setColor(new Color(255, 0, 0, 140));
g2d.setStroke(new BasicStroke(10, BasicStroke.CAP_ROUND,
BasicStroke.JOIN_BEVEL));
g.drawLine(0, 0, 24, 25);
}
}
}

/aksel
 
A

Andrew Thompson

aksel.schmidt said:
thanks for the effort
this code explains my problem:
when i press the button, i want to copy a panel (living in the
glasspane on the left side) into an image and be able to draw this
image on the right side - completely with alpha values etc.
what it does right now is just removing the alpha values...

Like this?

<sscce>
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.*;

public class CreateImageTest {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

final JPanel panel = new JPanel();
final JPanel panel1 = new JPanel();
final JPanel panel2 = new JPanel();
final JPanel backgroundPanel = new JPanel();

JButton b = new JButton("copy");
final JLabel label2 = new JLabel();
label2.setOpaque(false);
b.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Image c = createImage(backgroundPanel, panel1);
label2.setIcon(new ImageIcon(c));
panel2.repaint();
}
});
panel1.add(b);
panel1.add(new JLabel("haj"));
panel1.add(new MyAplhaComponent());
panel1.setOpaque(false);

Dimension preferedSize = new Dimension(100, 100);
panel1.setPreferredSize(preferedSize);

panel2.add(label2);
panel2.setPreferredSize(preferedSize);
panel2.setOpaque(false);
panel2.setBackground(Color.BLUE);

panel.add(panel1);
panel.add(panel2);
panel.setBackground(Color.GREEN);
panel.setOpaque(false);
frame.setGlassPane(panel);
frame.getGlassPane().setVisible(true);
JTextArea textArea = new JTextArea(
"iufpf w fw ffjoifopfree ef\n" +
", joiewfeeffjepfie wfeifoewfjepf e\n" +
" huep heufhfewfeefehufehfueoie\n" +
"weifehfwefefheo");
textArea.setPreferredSize(new Dimension(200, 200));
backgroundPanel.add(textArea);
frame.getContentPane().add(backgroundPanel,
BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}

public static BufferedImage createImage(JComponent background,
JComponent component) {
Dimension d = component.getSize();
if (d.width == 0) {
d = component.getPreferredSize();
component.setSize(d);
}
BufferedImage bi = new BufferedImage(d.width, d.height,
BufferedImage.TYPE_INT_ARGB);
Graphics g = bi.createGraphics();
background.paint(g);
component.paint(g);
return bi;
}

public static BufferedImage createImage(JComponent component) {
Dimension d = component.getSize();
if (d.width == 0) {
d = component.getPreferredSize();
component.setSize(d);
}

// Note carefully the 'A'
BufferedImage bi = new BufferedImage(d.width, d.height,
BufferedImage.TYPE_INT_ARGB);
Graphics g = bi.createGraphics();
component.paint(g);
return bi;
}

public static class MyAplhaComponent extends JComponent {
{
setPreferredSize(new Dimension(40, 40));
}

@Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g.setColor(new Color(255, 0, 0, 140));
g2d.setStroke(new BasicStroke(10,
BasicStroke.CAP_ROUND,
BasicStroke.JOIN_BEVEL));
g.drawLine(0, 0, 24, 25);
}
}
}
</sscce>

--
Andrew Thompson
http://www.physci.org/

Message posted via JavaKB.com
http://www.javakb.com/Uwe/Forums.aspx/java-general/200712/1
 
A

aksel.schmidt

again -thanks for the effort - but it doesn't work

the right side of the glass pane is supposed to draw the image of the
left side of the glasspane - complete with half-transparent red line
etc ABOVE the text that is on the background textarea

/aksel
 
A

Andrew Thompson

aksel.schmidt said:
again -thanks for the effort - but it doesn't work

According to my understanding of the requirement, it works
here using Java 1.6.0_02 on Win XP.

Here is a screenshot of the GUI as it first appears.
the right side of the glass pane is supposed to draw the image of the
left side of the glasspane - complete with half-transparent red line
etc ABOVE the text that is on the background textarea

And a screenshot after I click the button..
<http://www.physci.org/test/screenshot/transs02.png>

Are you seeing something different?
 
A

aksel.schmidt

hi

its the same as what i see - but not the desired functionality
as you see, the image drawn on the right side is not transparent - the
text in the background is not seen anymore as desired

/aksel
 
A

aksel.schmidt

found a solution: use paintComponents intead of paint..
package aks;

import java.awt.BasicStroke;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;

public class CreateImageTest {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

final JPanel panel = new JPanel();
final JPanel panel1 = new JPanel();
final JPanel panel2 = new JPanel();
final JPanel backgroundPanel = new JPanel();

JButton b = new JButton("copy");
final JLabel label2 = new JLabel();
label2.setOpaque(false);
b.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Image c = createImage(panel1);
label2.setIcon(new ImageIcon(c));
panel2.repaint();
}
});
panel1.add(b);
panel1.add(new JLabel("haj"));
panel1.add(new MyAplhaComponent());
panel1.setOpaque(false);

Dimension preferedSize = new Dimension(100, 100);
panel1.setPreferredSize(preferedSize);

panel2.add(label2);
panel2.setPreferredSize(preferedSize);
panel2.setOpaque(false);
panel2.setBackground(Color.BLUE);

panel.add(panel1);
panel.add(panel2);
panel.setBackground(Color.GREEN);
panel.setOpaque(false);
frame.setGlassPane(panel);
frame.getGlassPane().setVisible(true);
JTextArea textArea = new JTextArea("iufpf w fw ffjoifopfree ef
\n" + ", joiewfeeffjepfie wfeifoewfjepf e\n"
+ " huep heufhfewfeefehufehfueoie\n" +
"weifehfwefefheo");
textArea.setPreferredSize(new Dimension(200, 200));
backgroundPanel.add(textArea);
frame.getContentPane().add(backgroundPanel,
BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}

public static BufferedImage createImage(JComponent component) {
Dimension d = component.getSize();
if (d.width == 0) {
d = component.getPreferredSize();
component.setSize(d);
}

// Note carefully the 'A'
BufferedImage bi = new BufferedImage(d.width, d.height,
BufferedImage.TYPE_INT_ARGB);
Graphics g = bi.createGraphics();
component.paintComponents(g);
return bi;
}

public static class MyAplhaComponent extends JComponent {
{
setPreferredSize(new Dimension(40, 40));
}

@Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g.setColor(new Color(255, 0, 0, 140));
g2d.setStroke(new BasicStroke(10, BasicStroke.CAP_ROUND,
BasicStroke.JOIN_BEVEL));
g.drawLine(0, 0, 24, 25);
}
}
}
 
A

Andrew Thompson

aksel.schmidt said:
found a solution: use paintComponents intead of paint..

Congratulations! *Now* I understand what you meant.
A picture paints a thousand words. :)

Well, at least, 'now' after I fixed the line-wrap that broke
both examples when I tried to compile them. It is best
to keep code posting width to less than around 62 chars,
so line-wrap is not a problem. My SSCCE earlier,
showed how to reorganise the code so that the longest
lines were shorter.

Here is a tool to help check line width.
<http://www.physci.org/twc.jnlp>

But finally.. (to self and nobody else in particular).
// Note carefully the 'A'
BufferedImage bi = new BufferedImage(d.width, d.height,
BufferedImage.TYPE_INT_ARGB);

Ha! I 'knew' transparency in the BufferedImage
would somehow be important. ;-)

--
Andrew Thompson
http://www.physci.org/

Message posted via JavaKB.com
http://www.javakb.com/Uwe/Forums.aspx/java-general/200712/1
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,225
Members
46,815
Latest member
treekmostly22

Latest Threads

Top