I have created pptx and ppt converter to images using apache poi but while converting some file i have an exception after two or three converts.
Exception in thread "main" java.lang.IllegalArgumentException: Color parameter outside of expected range: Red
Main converter from both pptx and ppt
import org.apache.poi.hslf.model.Slide;
import org.apache.poi.hslf.usermodel.SlideShow;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFSlide;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
public class Application {
public static void main(String[] args) throws Exception {
System.out.println("working");
String directory = System.getProperty("user.home") + "/Desktop/";
//creating an empty presentation
File file=new File(directory + "test6.pptx");
String fileName = file.getName();
// Identify the file whether it is ppt or pptx
String extension = fileName.substring(fileName.lastIndexOf(".") + 1);
FileInputStream inputStream = new FileInputStream(directory + fileName);
if (extension.equals("pptx")) {
XMLSlideShow pptx = new XMLSlideShow(inputStream);
//getting the dimensions and size of the slide
Dimension pgsize = pptx.getPageSize();
java.util.List<XSLFSlide> pptxSlide = Arrays.asList(pptx.getSlides());
for (int i = 0; i < pptxSlide.size(); i++) {
BufferedImage img = new BufferedImage(pgsize.width, pgsize.height,BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = createImage(img, pgsize);
//render
pptxSlide.get(i).draw(graphics);
graphics.setComposite(AlphaComposite.DstOver);
graphics.setPaint(Color.WHITE);
//creating an image file as output
imageFile(i, img);
graphics.dispose();
}
}else if(extension.equals("ppt")){
SlideShow ppt = new SlideShow(inputStream);
//getting the dimensions and size of the slide
Dimension pgsize = ppt.getPageSize();
List<Slide> slide = Arrays.asList(ppt.getSlides());
for (int i = 0; i < slide.size(); i++) {
BufferedImage img = new BufferedImage(pgsize.width, pgsize.height,BufferedImage.TYPE_INT_RGB);
//render
slide.get(i).draw(createImage(img, pgsize));
//creating an image file as output
imageFile(i, img);
}
}else {
throw new Exception("Not compatible type ");
}
}
private static void imageFile(int i, BufferedImage img) throws IOException {
FileOutputStream out = new FileOutputStream("ppt_image_" + i + ".png");
javax.imageio.ImageIO.write(img, "png", out);
System.out.println("Image successfully created");
out.close();
}
private static Graphics2D createImage(BufferedImage img, Dimension pgsize){
Graphics2D graphics = img.createGraphics();
//clear the drawing area
graphics.setPaint(Color.white);
graphics.fill(new Rectangle2D.Float(0, 0, pgsize.width, pgsize.height));
// default rendering options
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
graphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
graphics.setComposite(AlphaComposite.DstOver);
return graphics;
}
}
The main problem is that I want to convert any pptx file any kind of with gradient or simple colors to images.
Converted gradient slide [greyed]
What is the shortest code one can write in java to break an image (say 200x1000) into 10 images of a tenth height but same width (200x 100)?
Mine is a pretty long code; the main part , I am just giving:
for (int i_=0;i_<10;i_++)
{
for(int k=i_*100;k<i_*100+h/10;k++)
{
for(int j_=0;j_<w;j_++)
{
int pixv=img.getRGB(j_,k);
r=(pixv>>16)&0xff;
g=(pixv>>8)&0xff;
b=(pixv)&0xff;
int rgb=new Color(r,g,b).getRGB();
img.setRGB(j_,k-i_*200,rgb);
}
}
// Here I am writing the img to a new .bmp file thus creating 10 seperate files
}
Here img is a BufferedImage
w,h the width and height of large image
you can get a sub image from BufferedImage using getSubimage(int x,int y,int w,int h). Try this:
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class NewClass9 {
public static void main(String[] args) throws IOException{
BufferedImage img = null;
img = ImageIO.read(new File("C:\\users\\uzochi\\desktop\\Penguins.jpg"));
for(int i = 0;i<10;i++){
BufferedImage sub = img.getSubimage(0, i*(img.getHeight()/10), img.getWidth(), img.getHeight()/10);
File f = new File("C:\\users\\uzochi\\desktop\\SubImage"+i+".png");
ImageIO.write(sub, "png", f);
}
}
}
I've coded up a program that can read rgb values off of a jpg file, but when i test it with a solid color i'm getting rgb results that are slightly inaccurate. Does anyone know if its my code or if its java that is inaccurate?
RGB
red=64 green=0 blue=128
RESULT
red=65 green=0 blue=128
CODE
import java.awt.*;
import java.awt.image.*;
import java.io.*;
import java.util.ArrayList;
import javax.imageio.*;
public class Program {
public int[][] rgbValues;
public File imagePath = new File("src/image3.jpg");
public BufferedImage image;
public Program() throws IOException{
image = ImageIO.read(imagePath);
rgbValues = new int[image.getWidth()][image.getHeight()];
}
public void run() throws IOException{
getData();
analyzeData();
}
private void getData() throws IOException{
for (int y = 0; y < image.getHeight(); y++){
for (int x = 0; x < image.getWidth(); x++){
rgbValues[y][x] = image.getRGB(x, y);
}
}
}
private void analyzeData() throws IOException{
boolean f = image.getAlphaRaster() != null;
Color color = new Color(rgbValues[10][10], f);
System.out.println(color.getRed());
System.out.println(color.getGreen());
System.out.println(color.getBlue());
}
}
Code seems correct and results as well, Paint says the image is also (65,0,128)
So I have an animated gif that I load into an ImageIcon like this:
Image image = new ImageIcon("image.gif").getImage();
and I can draw it using this:
g.drawImage(image, x, y, null);
I know that I can mirror it on the fly using AffineTransform, but I need to be able to mirror it horizontally after loading, so that I can draw the mirrored one instead if needed without the overhead of transforming it every time it gets redrawn. Is there a way to do this using swing/awt?
A library that could do this would also be a huge help.
The problem is, as you have pointed out, is the fact the gif's are animated.
Unless you desperately want to take over the job of having to render each frame yourself, the only choice you have is to use an AffineTransform with in the paint method.
Generally speaking, you shouldn't see a significant difference (in rendering).
If you are really desperate, you could simply pre-render the gif externally and provide a mirrored version
Updated with a "kind of" working example
This is a combination of this and this answers, using this GIF writer.
Basically what this example does is it reads an original gif image, mirrors it frame by frame, and writes back out to a mirrored file.
It then loads both the original and mirrored files back in as ImageIcons, mostly because I'm not really up to re-inventing the wheel for display animated gifs. Yes, you could do it and everything you would need is provided within..
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.imageio.IIOException;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataNode;
import javax.imageio.stream.FileImageOutputStream;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.ImageOutputStream;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class MirrorImage {
public static void main(String[] args) {
new MirrorImage();
}
public MirrorImage() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private ImageIcon orig;
private ImageIcon mirror;
public TestPane() {
mirror(new File("java_animated.gif"), new File("Mirror.gif"));
orig = new ImageIcon("java_animated.gif");
mirror = new ImageIcon("Mirror.gif");
}
#Override
public Dimension getPreferredSize() {
return mirror == null ? new Dimension(200, 200) : new Dimension(orig.getIconWidth(), orig.getIconHeight() * 2);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (orig != null) {
Graphics2D g2d = (Graphics2D) g.create();
int x = (getWidth() - orig.getIconWidth()) / 2;
int y = (getHeight() - (orig.getIconHeight() * 2)) / 2;
g2d.drawImage(orig.getImage(), x, y, this);
// AffineTransform at = new AffineTransform();
// at.setToScale(1, -1);
// at.translate(0, -mirror.getIconHeight());
// g2d.setTransform(at);
g2d.drawImage(mirror.getImage(), x, y + mirror.getIconHeight(), this);
g2d.dispose();
}
}
}
public static void mirror(File source, File dest) {
List<BufferedImage> images = new ArrayList<>(25);
List<Integer> delays = new ArrayList<>(25);
int delay = 0;
ImageOutputStream output = null;
GifSequenceWriter writer = null;
try {
String[] imageatt = new String[]{
"imageLeftPosition",
"imageTopPosition",
"imageWidth",
"imageHeight"
};
ImageReader reader = (ImageReader) ImageIO.getImageReadersByFormatName("gif").next();
ImageInputStream ciis = ImageIO.createImageInputStream(source);
reader.setInput(ciis, false);
int noi = reader.getNumImages(true);
BufferedImage master = null;
for (int i = 0; i < noi; i++) {
BufferedImage image = reader.read(i);
IIOMetadata metadata = reader.getImageMetadata(i);
Node tree = metadata.getAsTree("javax_imageio_gif_image_1.0");
NodeList children = tree.getChildNodes();
for (int j = 0; j < children.getLength(); j++) {
Node nodeItem = children.item(j);
System.out.println(nodeItem.getNodeName());
if (nodeItem.getNodeName().equals("ImageDescriptor")) {
Map<String, Integer> imageAttr = new HashMap<String, Integer>();
NamedNodeMap attr = nodeItem.getAttributes();
// for (int index = 0; index < attr.getLength(); index++) {
// Node node = attr.item(index);
// System.out.println("----> " + node.getNodeName() + "=" + node.getNodeValue());
// }
for (int k = 0; k < imageatt.length; k++) {
Node attnode = attr.getNamedItem(imageatt[k]);
imageAttr.put(imageatt[k], Integer.valueOf(attnode.getNodeValue()));
}
if (master == null) {
master = new BufferedImage(imageAttr.get("imageWidth"), imageAttr.get("imageHeight"), BufferedImage.TYPE_INT_ARGB);
}
Graphics2D g2d = master.createGraphics();
g2d.drawImage(image, imageAttr.get("imageLeftPosition"), imageAttr.get("imageTopPosition"), null);
g2d.dispose();
BufferedImage frame = mirror(copyImage(master));
ImageIO.write(frame, "png", new File("img" + i + ".png"));
images.add(frame);
} else if (nodeItem.getNodeName().equals("GraphicControlExtension")) {
NamedNodeMap attr = nodeItem.getAttributes();
Node delayNode = attr.getNamedItem("delayTime");
if (delayNode != null) {
delay = Math.max(delay, Integer.valueOf(delayNode.getNodeValue()));
delays.add(delay);
}
}
}
}
output = new FileImageOutputStream(dest);
writer = new GifSequenceWriter(output, images.get(0).getType(), delay * 10, true);
for (int i = 0; i < images.size(); i++) {
BufferedImage nextImage = images.get(i);
writer.writeToSequence(nextImage);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
writer.close();
} catch (Exception e) {
}
try {
output.close();
} catch (Exception e) {
}
}
}
public static BufferedImage mirror(BufferedImage img) {
BufferedImage mirror = createCompatibleImage(img);
Graphics2D g2d = mirror.createGraphics();
AffineTransform at = new AffineTransform();
at.setToScale(1, -1);
at.translate(0, -img.getHeight());
g2d.setTransform(at);
g2d.drawImage(img, 0, 0, null);
g2d.dispose();
return mirror;
}
public static BufferedImage copyImage(BufferedImage img) {
int width = img.getWidth();
int height = img.getHeight();
BufferedImage newImage = createCompatibleImage(img);
Graphics graphics = newImage.createGraphics();
int x = (width - img.getWidth()) / 2;
int y = (height - img.getHeight()) / 2;
graphics.drawImage(img, x, y, img.getWidth(), img.getHeight(), null);
graphics.dispose();
return newImage;
}
public static BufferedImage createCompatibleImage(BufferedImage image) {
return getGraphicsConfiguration().createCompatibleImage(image.getWidth(), image.getHeight(), image.getTransparency());
}
public static GraphicsConfiguration getGraphicsConfiguration() {
return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
}
public static class GifSequenceWriter {
protected ImageWriter gifWriter;
protected ImageWriteParam imageWriteParam;
protected IIOMetadata imageMetaData;
/**
* Creates a new GifSequenceWriter
*
* #param outputStream the ImageOutputStream to be written to
* #param imageType one of the imageTypes specified in BufferedImage
* #param timeBetweenFramesMS the time between frames in miliseconds
* #param loopContinuously wether the gif should loop repeatedly
* #throws IIOException if no gif ImageWriters are found
*
* #author Elliot Kroo (elliot[at]kroo[dot]net)
*/
public GifSequenceWriter(
ImageOutputStream outputStream,
int imageType,
int timeBetweenFramesMS,
boolean loopContinuously) throws IIOException, IOException {
// my method to create a writer
gifWriter = getWriter();
imageWriteParam = gifWriter.getDefaultWriteParam();
ImageTypeSpecifier imageTypeSpecifier
= ImageTypeSpecifier.createFromBufferedImageType(imageType);
imageMetaData
= gifWriter.getDefaultImageMetadata(imageTypeSpecifier,
imageWriteParam);
String metaFormatName = imageMetaData.getNativeMetadataFormatName();
IIOMetadataNode root = (IIOMetadataNode) imageMetaData.getAsTree(metaFormatName);
IIOMetadataNode graphicsControlExtensionNode = getNode(
root,
"GraphicControlExtension");
graphicsControlExtensionNode.setAttribute("disposalMethod", "none");
graphicsControlExtensionNode.setAttribute("userInputFlag", "FALSE");
graphicsControlExtensionNode.setAttribute(
"transparentColorFlag",
"FALSE");
graphicsControlExtensionNode.setAttribute(
"delayTime",
Integer.toString(timeBetweenFramesMS / 10));
graphicsControlExtensionNode.setAttribute(
"transparentColorIndex",
"0");
IIOMetadataNode commentsNode = getNode(root, "CommentExtensions");
commentsNode.setAttribute("CommentExtension", "Created by MAH");
IIOMetadataNode appEntensionsNode = getNode(
root,
"ApplicationExtensions");
IIOMetadataNode child = new IIOMetadataNode("ApplicationExtension");
child.setAttribute("applicationID", "NETSCAPE");
child.setAttribute("authenticationCode", "2.0");
int loop = loopContinuously ? 0 : 1;
child.setUserObject(new byte[]{0x1, (byte) (loop & 0xFF), (byte) ((loop >> 8) & 0xFF)});
appEntensionsNode.appendChild(child);
imageMetaData.setFromTree(metaFormatName, root);
gifWriter.setOutput(outputStream);
gifWriter.prepareWriteSequence(null);
}
public void writeToSequence(RenderedImage img) throws IOException {
gifWriter.writeToSequence(
new IIOImage(
img,
null,
imageMetaData),
imageWriteParam);
}
/**
* Close this GifSequenceWriter object. This does not close the underlying
* stream, just finishes off the GIF.
*/
public void close() throws IOException {
gifWriter.endWriteSequence();
}
/**
* Returns the first available GIF ImageWriter using
* ImageIO.getImageWritersBySuffix("gif").
*
* #return a GIF ImageWriter object
* #throws IIOException if no GIF image writers are returned
*/
private static ImageWriter getWriter() throws IIOException {
Iterator<ImageWriter> iter = ImageIO.getImageWritersBySuffix("gif");
if (!iter.hasNext()) {
throw new IIOException("No GIF Image Writers Exist");
} else {
return iter.next();
}
}
/**
* Returns an existing child node, or creates and returns a new child node
* (if the requested node does not exist).
*
* #param rootNode the <tt>IIOMetadataNode</tt> to search for the child
* node.
* #param nodeName the name of the child node.
*
* #return the child node, if found or a new node created with the given
* name.
*/
private static IIOMetadataNode getNode(
IIOMetadataNode rootNode,
String nodeName) {
int nNodes = rootNode.getLength();
for (int i = 0; i < nNodes; i++) {
if (rootNode.item(i).getNodeName().compareToIgnoreCase(nodeName)
== 0) {
return ((IIOMetadataNode) rootNode.item(i));
}
}
IIOMetadataNode node = new IIOMetadataNode(nodeName);
rootNode.appendChild(node);
return (node);
}
}
}
Caveats
The Gif writer currently only works with fixed rate gifs. It should be possible to change this, but I didn't have the time.
Basically, as I understand it, you would need to pass a "frame" delay to the writeToSquence method. Within this method you would need to construct an appropriate IIOMetadata with all the required properties, plus your frame delay...
Updated after playing with original gif
The GIF I was playing with was optimised. That is, each frame "added" to the animation, rather then being a brand new frame. Yours is the other way round. Each frame is an entire image.
Now, there are probably lots of ways you could check for this, but right now, I can't be bothered...
Instead...in the mirror(File, File) method, I changed it so that rather then using a single "master" image, each frame creates a new BufferedImage
BufferedImage frame = new BufferedImage(imageAttr.get("imageWidth"), imageAttr.get("imageHeight"), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = frame.createGraphics();
g2d.drawImage(image, imageAttr.get("imageLeftPosition"), imageAttr.get("imageTopPosition"), null);
g2d.dispose();
frame = mirror(frame);
ImageIO.write(frame, "png", new File("img" + i + ".png"));
images.add(frame);
I also updated the GifSequenceWriter to set the meta data to more closely match the original as well...
graphicsControlExtensionNode.setAttribute("disposalMethod", "restoreToBackgroundColor");
graphicsControlExtensionNode.setAttribute("userInputFlag", "FALSE");
graphicsControlExtensionNode.setAttribute(
"transparentColorFlag",
"TRUE");
..overhead of transforming it every time..
That overhead is just about 0. But if you don't want to use AffineTransform simply change the x,y in a loop.
See also Show an animated BG in Swing for more tips.
Note
This:
g.drawImage(image, x, y, null);
Should be:
g.drawImage(image, x, y, this); // containers are typically an ImageObserver!
For non-animated images, you can create a mirrored image.
// Width and height
int w = image.getWidth(null);
int h = image.getHeight(null);
// Create a new BufferedImage
BufferedImage mirror = new BufferedImage(w, h);
// Draw the image flipping it horizontally
Graphics2D g = mirror.createGraphics();
g.drawImage(image, 0, 0, w, h, w, 0, 0, h, null);
// Dispose the graphics.
g.dispose();
You can then use mirror which is already mirrored horizontally.
I am trying to make image from BufferImage, but it's not working. here is my code ...
This code is not working, can anyone please help me ...
try {
BufferedImage bimage = (BufferedImage)(new ImageIcon("str")).getImage();
BufferedImage image = new BufferedImage(500, 500, bimage.TYPE_BYTE_GRAY);
File outputfile = new File("saved.png");
ImageIO.write(image, "png", outputfile);
Image image_1 = ImageIO.read(new File("saved.png"));
lp2_2.setIcon(new ImageIcon(image_1));
} catch (IOException e) {}
Maybe your way of converting IconImage to BufferedImageis not right.
So you can try the following snippet
BufferedImage bi = new BufferedImage(icon.getIconWidth(),icon.getIconHeight(), BufferedImage.TYPE_INT_RGB);
Graphics g = bi.createGraphics();
// paint the Icon to the BufferedImage.
icon.paintIcon(null, g, 0,0);
g.dispose();
After this you can use BufferdImage as you are already using.
Or you can look this question Java converting Image to BufferedImage
if you want to see how to convert Image to 'BifferedImage' because as given in this post you can't just cast Image to BufferedImage.
Although i would request you to add more information like what error or exception you are getting and may be if there is an exception add the stacktrace .
Hopefully this will work better, I have tried it many times.
public void writeImage(String output, String fileName, BufferedImage img) throws IOException {
File file = new File(output + "\\HE\\" + fileName + ".bmp");
ImageIO.write(img, "bmp", file);
}
=================================================================================
If you want to use this image in any JPanel then here is code for it, it is already working fine,
import java.awt.BorderLayout;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class ShowImage {
public ShowImage(final String filename) throws Exception {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame editorFrame = new JFrame("My Frame " +filename);
editorFrame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
BufferedImage image = null;
try {
image = ImageIO.read(new File(filename));
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
ImageIcon imageIcon = new ImageIcon(image);
JLabel jLabel = new JLabel();
jLabel.setIcon(imageIcon);
editorFrame.getContentPane().add(jLabel, BorderLayout.CENTER);
editorFrame.pack();
editorFrame.setLocationRelativeTo(null);
editorFrame.setVisible(true);
}
});
}
}
here is my new code and its working properly ... thank you all for your kind support ...
try{
BufferedImage cat = ImageIO.read(new File(str));
for (int w = 0; w < cat.getWidth(); w++) {
for (int h = 0; h < cat.getHeight(); h++) {
Color color = new Color(cat.getRGB(w, h));
//int averageColor = ((color.getRed() + color.getGreen() + color.getBlue()) / 3);
//int averageColor = int((color.getRed())*0.21 +(color.getGreen())*0.71+(color.getBlue())*0.07);
double r =color.getRed()*0.21;
double g =color.getGreen()*0.71;
double b =color.getBlue()*0.07;
int averageColor = (int)(r+g+b);
Color avg = new Color(averageColor, averageColor, averageColor);
cat.setRGB(w, h, avg.getRGB());
}
}
ImageIO.write(cat, "jpg", new File("image_greyscale.jpg"));
lp2_2.setIcon(new ImageIcon((new ImageIcon("image_greyscale.jpg")).getImage().getScaledInstance( 600, 600, java.awt.Image.SCALE_SMOOTH )));
}catch(IOException e){
e.printStackTrace();
System.exit(1);}
Everyone here missed the point. A BufferedImage is an Image.