Save AWT/Swing screen as Image.

Jitu
Jitu used Ask the Experts™
on
I have an applet that displays in a web page.
What i want to do is to, display an image instead of an applet. The image would be exactly what the applet would look like.

In other words, i do not want to show the applet at all on my web page. Instead capture whatever the applet would have displayed as , save it as a image and show it to the user.

How can i do this ?
Best would have been that i display the applet, give user a button called 'Save as Image', which would save the applet as an image. But this is not possible due to security restrictions.

And i do not want to rewrite any code, but just do a small add on to the code, so that the applet (never gets displayed), instead gets saved as an image on the server side itself, and i show the image to the user.


Thanks
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Mick BarryJava Developer
Top Expert 2010

Commented:
If you don't want to run the applet then how would you have a 'save as image' button anyway.

Author

Commented:
As i said above...
The reason i dont want to run the applet is that 'save as image' button would be useless anyway, as the browser Security Restrictions would not allow for this operation. And i am not considering signed applets.
So i was just giving an example of why i am not taking that approach.

Mick BarryJava Developer
Top Expert 2010

Commented:
your applet will need to get permissions from the user to save to local disk.
Another option would be to save the image to the server instead of the local disk.
Expert Spotlight: Joe Anderson (DatabaseMX)

We’ve posted a new Expert Spotlight!  Joe Anderson (DatabaseMX) has been on Experts Exchange since 2006. Learn more about this database architect, guitar aficionado, and Microsoft MVP.

Commented:
> What i want to do is to, display an image instead of an applet. The image would be exactly what the applet would look like.


so make a screenshot of the applet and convert it to .gif file ?

Author

Commented:
>so make a screenshot of the applet and convert it to .gif file ?

How do i do this programmitcally.. this exactly is my question. The applet code has been written by someone else. And there is no user interaction with it. It;s display is based on some internal calculations and is not same everytime you invoke it.

>Objects
>Another option would be to save the image to the server instead of the local disk.
Yes, this too can be done. I am ok with displaying the image, having a save button, and then as a result saving the image on the server. This is fine.
But how do i do this ? How do i capture the applet's display and save it as a gif/jpg

Commented:
>so make a screenshot of the applet and convert it to .gif file ?

How do i do this programmitcally..


why do you need to do it programmitcally ? just press "Print Screen" button.

> How do i capture the applet's display and save it as a gif/jpg.

you can capture everything rendered on some Graphics object, extract the Colors and encode it to a .gif file.

a small problem is that Java 1.1 does not have native GIF / JPG encoders available

Author

Commented:
>so make a screenshot of the applet and convert it to .gif file ?
>How do i do this programmitcally..
>why do you need to do it programmitcally ? just press "Print Screen" button.

?????????????

As i said the applet info. is not static, the gif file will have to be created everytime.
To simplify my explanation : Think about it like this. The applet displays the current date time of the server. Instead of displaying the applet i display the current date time of the server in a gif. Basically whatever applet would have displayed at that time, is displayed as a gif.

And i am ok with later versions of jdk. On the server side have the liberty of using any jdk i want.

Commented:
so you want to MODIFY existing applet so that you can uploaded whatever applet displays as an image file on the server, correct ? do you have the applet sources ?

Author

Commented:
Yes i do have the source.

Commented:
I will post some code in 30 minutes

Author

Commented:
Thanks...
(i shall get back on this tomorrow.)

Commented:
I think there's been some kind of confusion over what Jitu actually wants.
He said he's got this applet that displays some date/time of the server and requires no user interaction.
I think what he's trying to explain is that he doesn't want to run that applet on the client side AT ALL. He wants to run it on the server, capture the image and send the image to the client.
Jitu probably wants to do that because he sees no reason why there should be an applet running on the client side when the content (image) of that applet could just be generated server side and sent to the client as an image.

Jitu, correct me if my interpretation of your question is wrong.

In case it is right, then I am afraid you can't do what you want with applets. Applets are meant to be used on the client side only.
If you want the server to generate images dynamically (or any part of a page dynamically), use servlets or JSP...or any of the other technologies that will enable you to generate dynamic content on your pages server-side.

Commented:
> In case it is right, then I am afraid you can't do what you want with applets. Applets are meant to be used on the client side only.

applet are just Java objects that run inside Java VM. you can run Java VM anywhere you like.
Commented:
for capturing Component "image" you can use the following code. if you have to generate it on client side and upload it to server, you will have to add an upload routine.


import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import com.sun.image.codec.jpeg.*;

public class jpegTest implements WindowListener, ActionListener
{
  public static void main(String args[])
  {
    jpegTest c = new jpegTest();
    c.startClient(args);
  }
  private void startClient(String args[])
  {
    try
    {
      myComponent = new MyComponent();
      Button button = new Button("Save .jpeg");
      myComponent.setLayout(new FlowLayout());
      myComponent.add(button);

      Frame f = new Frame();
      f.setLayout(new GridLayout(1, 1));
      f.add(myComponent);

      button.addActionListener(this);
      f.addWindowListener(this);
     
      f.setBounds(100, 100, 600, 300);
      f.setVisible(true);
     
     
    } catch (Throwable x)
    {
      x.printStackTrace();
      System.exit(-1);
    }
  }

  public MyComponent myComponent;
 
  private byte[] captureComponentViewInJpeg(Component c) throws IOException
  {
    Dimension size = c.getSize();
   
    BufferedImage bufferedImage = new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_RGB);
    Graphics bufferedGraphics = bufferedImage.createGraphics();
    myComponent.paint(bufferedGraphics);
   
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(bos);
    encoder.encode(bufferedImage);
   
    byte[] jpgData = bos.toByteArray();
    return jpgData;
  }
 
  public void actionPerformed(ActionEvent e)
  {
    try
    {
      byte[] jpgData = captureComponentViewInJpeg(myComponent);
     
      FileOutputStream fos = new FileOutputStream("c:/1.jpg");
      fos.write(jpgData);
      fos.close();
    } catch (IOException x)
    {
      x.printStackTrace();
    }
  }
 
  public void windowClosing(WindowEvent e)
  {
    System.exit(-1);
  }

  public void windowOpened(WindowEvent e){}
  public void windowClosed(WindowEvent e){}
  public void windowIconified(WindowEvent e){}
  public void windowDeiconified(WindowEvent e){}
  public void windowActivated(WindowEvent e){}
  public void windowDeactivated(WindowEvent e){}
}


class MyComponent extends Container
{
  public void paint(Graphics g)
  {
    Dimension d = getSize();
    g.setColor(getBackground());
    g.fillRect(0, 0, d.width, d.height);
   
   
    g.setColor(Color.green);
    g.drawOval(5, 5, 40, 40);
  }
}

Commented:
> applet are just Java objects that run inside Java VM. you can run Java VM anywhere you like.

True, and I never said anything that would imply the opposite.
All I said is that if this is what he wants, then he won't be able to do it using applets.
Of course he could run the applet on the server, but that alone wouldn't enable him to do what I think he wants to do.

Commented:
i do this.

it is a reasonable thing to want.  in my case, i generate an image based on some coordinate data in the database, then take a snapshot of the generated image (on the server) and send it as a gif to the browser...

works well.

if you can't get the posted code working, ill send you what i use.

randy

Author

Commented:
Thanks. That was brilliant.
I found that using
   myComponent.printAll(bufferedGraphics);
Instead of
   myComponent.paint(bufferedGraphics);
works better.  The component is forced to paint itself in its entirety and you don't have to worry about whether it is completely visible.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial