views:

609

answers:

1

Hi,

I am creating a simple applet for avatar-making. You can choose face, hair, eyes, etc and then save it to a disc as a png file. The simple version (without the interface for the simplicity purpose) looks like this:

import java.awt.*;
import java.applet.*;
import java.net.*;

public class Example extends Applet
 {

 Image my_gif;
 Image my_gif2;
 URL base;
 MediaTracker mt;

 public void init() 
 {
        mt = new MediaTracker(this);
     try {
             base = getDocumentBase();
     }
     catch (Exception e) {}

       my_gif = getImage(base,"1.gif");
       my_gif2 = getImage(base,"2.gif");

       mt.addImage(my_gif,1);
       mt.addImage(my_gif2,2);

      try {
           mt.waitForAll();
      }
      catch (InterruptedException  e) {}
  }
 public void paint(Graphics g) 
 {
       g.drawImage(my_gif,0,0,this);
     g.drawImage(my_gif2,0,0,this);
 }
 }

This example consists of two files. When run they are visible in a correct way. Now I would like to save it to a disc - I can save one image using BufferedImage but I want to "flatten" two or more images and save it. Any help would be greatly appreciated. I also agree that perhaps my approach is not the right one and would be grateful for any corrections.

+2  A: 

Beware quickly written and untested code!

The basic concept is this: You load the images from which you combine the avatar, then you create a new empty image and draw each part of the avatar onto it. After that you just save the newly created image to a file.

Important note: The getPath() Method will fail for unsigned applets cause of a AccessViolation. I suppose a FileChooser would be a better approach here.

import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import javax.imageio.ImageIO;

public class Avatar {
    // Graphics
    private GraphicsConfiguration config = GraphicsEnvironment
      .getLocalGraphicsEnvironment().getDefaultScreenDevice()
      .getDefaultConfiguration();

    private BufferedImage faceImage;
    private BufferedImage hairImage;
    private BufferedImage mouthImage;

    public Avatar(final String face, final String hair, final String mouth,
      final String out) {

     // Load the Image parts
     faceImage = load(face);
     hairImage = load(hair);
     mouthImage = load(mouth);

     // Combine the images
     BufferedImage outImage = combine();

     // Save the new image
     try {
      ImageIO.write(outImage, "png", new File(getPath()
        + "screenshot.png"));
     } catch (IOException e) {
     }
    }

    // Combine
    private BufferedImage combine() {
     // Create an empty image
     BufferedImage buffer = create(200, 400, true);

     // Get the graphics context
     Graphics2D g = buffer.createGraphics();

     // Draw all 3 images onto the empty one
     g.drawImage(faceImage, 0, 0, null);
     g.drawImage(hairImage, 0, 0, null);
     g.drawImage(mouthImage, 0, 0, null);

     // Get rid of the graphics context
     g.dispose();
     return buffer;
    }

    // Image
    private URL getURL(final String filename) {
     URL url = Avatar.class.getResource(filename);
     return url;
    }

    private BufferedImage load(final String file) {
     URL filename = getURL(file);
     if (filename == null) {
      return null;
     } else {
      try {
       return ImageIO.read(filename);
      } catch (IOException e) {
       return null;
      }
     }
    }

    private BufferedImage create(final int width, final int height,
      final boolean alpha) {
     BufferedImage buffer = config.createCompatibleImage(width, height,
       alpha ? Transparency.TRANSLUCENT : Transparency.OPAQUE);
     return buffer;
    }

    // Path
    private final String getPath() {
     String path = currentPath();
     if (currentPath().toLowerCase().endsWith(".jar")) {
      path = path.substring(0, path.lastIndexOf("/") + 1);
     }
     return path;

    }

    private String currentPath() {
     try {
      return this.getClass().getProtectionDomain().getCodeSource()
        .getLocation().toURI().getPath();
     } catch (URISyntaxException e) {
      return "";
     }
    }
}
Ivo Wetzel
Thanks a lot! It works like a charm.
nupek
Is the applet signed? If saving the result is the only reason you need to run as a signed applet, you might be able to have the applet POST the image bytes[] to the server, and then redirect the browser to download the resulting PNG image.
Sam Barnum