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.
解决方案
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 "";
}
}
}