This program should first open an image, and then allow it to be manipulated via grayscale, scale, and rotate methods (not functional at the moment; disregard it). However, I'm not sure how I can call upon the updated image every time a method is performed. For example, if I grayscale an image, it goes to grayscale. But if I then scale it to a different size, the resulting image is a scaled version of the original image, not a scaled grayscale image. I tried putting in "image2 = image;" to no avail. How can I fix this?
Thanks.
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;
import javax.swing.*;
import java.awt.image.*;
import javax.imageio.ImageIO;
public class Picture{
JFileChooser fileChooser = new JFileChooser();
final JFrame frame = new JFrame("Edit Image");
Container content;
static BufferedImage image;
BufferedImage image2;
JLabel imageLabel;
public Picture() {
//asks for image file as input
fileChooser.setDialogTitle("Choose an image file to begin:");
fileChooser.showOpenDialog(frame);
File selectedFile = fileChooser.getSelectedFile();
if (fileChooser.getSelectedFile() != null) {
try {
//reads File as image
image = ImageIO.read(selectedFile);
}
catch (IOException e) {
System.out.println("Invalid image file: " + selectedFile);
System.exit(0);
}
}
else {
System.out.println("No File Selected!");
}
}
public int width() {
//returns width of present image
int width = image.getWidth();
return width;
}
public int height() {
//returns height of present image
int height = image.getHeight();
return height;
}
public void getImage() {
this.image2 = image;
}
public void saveImage() {
//saves current image as JPEG
fileChooser.setDialogTitle("Save this image?");
fileChooser.showSaveDialog(frame);
try {
//writes new file
ImageIO.write(this.image, "JPG", fileChooser.getSelectedFile());
}
catch (IOException f) {
System.out.println("Saving failed! Could not save image.");
}
}
public void show() {
//set frame title, set it visible, etc
content = frame.getContentPane();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
//add the image to the frame
ImageIcon icon = new ImageIcon(image);
imageLabel = new JLabel(icon);
frame.setContentPane(imageLabel);
//add a menubar on the frame with a single option: saving the image
JMenuBar menuBar = new JMenuBar();
frame.setJMenuBar(menuBar);
JMenu progName = new JMenu("Edit Image");
progName.setBackground(Color.RED);
menuBar.add(progName);
JMenu fileMenu = new JMenu("File");
menuBar.add(fileMenu);
JMenu editMenu = new JMenu("Edit");
menuBar.add(editMenu);
ImageIcon exitIcon = new ImageIcon("app-exit.png");
JMenuItem exitAction = new JMenuItem("Exit", exitIcon);
progName.add(exitAction);
exitAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ImageIcon saveIcon = new ImageIcon("save-icon.png");
int askSave = JOptionPane.showConfirmDialog(null,"Save current image?", "", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, saveIcon);
if (askSave == JOptionPane.YES_OPTION) {
//opens save image method, then exits
saveImage();
System.exit(0);
}
else {
//exits without saving
System.exit(0);
}
}
});
ImageIcon newIcon = new ImageIcon("new-image.png");
JMenuItem newAction = new JMenuItem("Open Image", newIcon);
fileMenu.add(newAction);
newAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ImageIcon saveIcon = new ImageIcon("save-icon.png");
int askSave = JOptionPane.showConfirmDialog(null,"Save current image?", "", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, saveIcon);
if (askSave == JOptionPane.YES_OPTION) {
//opens save image method, then asks asks for new image file
saveImage();
Picture p = new Picture();
imageLabel.setIcon(new ImageIcon(image));
//resizes canvas to fit new image
frame.setSize(width(), height());
}
else {
//asks for new image file since user did not want to save original
Picture p = new Picture();
imageLabel.setIcon(new ImageIcon(image));
//resizes canvas to fit new image
frame.setSize(width(), height());
}
}
});
ImageIcon saveIcon = new ImageIcon("save-image.png");
JMenuItem saveAction = new JMenuItem("Save Image As...", saveIcon);
fileMenu.add(saveAction);
saveAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//opens save image method
saveImage();
}
});
ImageIcon gsIcon = new ImageIcon("grayscale-image.png");
JMenuItem grayScale = new JMenuItem("Grayscale", gsIcon);
editMenu.add(grayScale);
grayScale.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//grabs height and width of image, then grayscales it
grayscale(width(), height());
}
});
ImageIcon scaleIcon = new ImageIcon("scale-image.png");
JMenuItem scaleImg = new JMenuItem("Scale Image", scaleIcon);
editMenu.add(scaleImg);
scaleImg.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//asks for height and width to create new image
ImageIcon widthIcon = new ImageIcon("LR-arrows.png");
String scaleWidth = (String)JOptionPane.showInputDialog(null,"What should the new width be?", "", JOptionPane.QUESTION_MESSAGE, widthIcon, null, null);
ImageIcon heightIcon = new ImageIcon("UD-arrows.png");
String scaleHeight = (String)JOptionPane.showInputDialog(null,"What should the new height be?", "", JOptionPane.QUESTION_MESSAGE, widthIcon, null, null);
//turns user input strings into doubles
double x = Double.parseDouble(scaleWidth);
double y = Double.parseDouble(scaleHeight);
//casts doubles as ints
int newWidth = (int)x;
int newHeight = (int)y;
//resizes frame to fit new image dimensions
frame.setSize(newWidth, newHeight);
//calls scale method to resize image using given dimensions
scale(newWidth, newHeight);
}
});
ImageIcon rotateIcon = new ImageIcon("rotate-image.png");
JMenuItem rotateImg = new JMenuItem("Rotate Image", rotateIcon);
editMenu.add(rotateImg);
rotateImg.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
//paint the frame
frame.pack();
frame.repaint();
frame.setVisible(true);
}
// convert to grayscale
public void grayscale(int width, int height) {
// create a grayscale image with original dimensions
image2 = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
// convert colored image to grayscale
ColorConvertOp grayScale = new ColorConvertOp(image.getColorModel().getColorSpace(),image2.getColorModel().getColorSpace(),null);
grayScale.filter(image,image2);
imageLabel.setIcon(new ImageIcon(image2));
getImage();
}
//scales image by a given factor
public void scale(int width, int height){
//uses user-input dimensions to create new image
image2 = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics g = image2.createGraphics();
//gets new dimensions and resizes image
g.drawImage(image, 0, 0, image2.getWidth(), image2.getHeight(), 0, 0, width(), height(), null);
imageLabel.setIcon(new ImageIcon(image2));
getImage();
}
//rotates the image
public void rotate(int width, int height, int theta) {
}
public static void main(String[] args) {
Picture p = new Picture();
p.show();
}
}
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;
import javax.swing.*;
import java.awt.image.*;
import javax.imageio.ImageIO;
public class Picture{
JFileChooser fileChooser = new JFileChooser();
final JFrame frame = new JFrame("Edit Image");
Container content;
static BufferedImage image;
BufferedImage image2;
JLabel imageLabel;
public Picture() {
//asks for image file as input
fileChooser.setDialogTitle("Choose an image file to begin:");
fileChooser.showOpenDialog(frame);
File selectedFile = fileChooser.getSelectedFile();
if (fileChooser.getSelectedFile() != null) {
try {
//reads File as image
image = ImageIO.read(selectedFile);
}
catch (IOException e) {
System.out.println("Invalid image file: " + selectedFile);
System.exit(0);
}
}
else {
System.out.println("No File Selected!");
}
}
public int width() {
//returns width of present image
int width = image.getWidth();
return width;
}
public int height() {
//returns height of present image
int height = image.getHeight();
return height;
}
/*
public void getImage() {
this.image2 = image;
}
*/
public void saveImage() {
//saves current image as JPEG
fileChooser.setDialogTitle("Save this image?");
fileChooser.showSaveDialog(frame);
try {
//writes new file
ImageIO.write(this.image, "JPG", fileChooser.getSelectedFile());
}
catch (IOException f) {
System.out.println("Saving failed! Could not save image.");
}
}
public void show() {
//set frame title, set it visible, etc
content = frame.getContentPane();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
//add the image to the frame
ImageIcon icon = new ImageIcon(image);
imageLabel = new JLabel(icon);
frame.setContentPane(imageLabel);
//add a menubar on the frame with a single option: saving the image
JMenuBar menuBar = new JMenuBar();
frame.setJMenuBar(menuBar);
JMenu progName = new JMenu("Edit Image");
progName.setBackground(Color.RED);
menuBar.add(progName);
JMenu fileMenu = new JMenu("File");
menuBar.add(fileMenu);
JMenu editMenu = new JMenu("Edit");
menuBar.add(editMenu);
ImageIcon exitIcon = new ImageIcon("app-exit.png");
JMenuItem exitAction = new JMenuItem("Exit", exitIcon);
progName.add(exitAction);
exitAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ImageIcon saveIcon = new ImageIcon("save-icon.png");
int askSave = JOptionPane.showConfirmDialog(null,"Save current image?", "", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, saveIcon);
if (askSave == JOptionPane.YES_OPTION) {
//opens save image method, then exits
saveImage();
System.exit(0);
}
else {
//exits without saving
System.exit(0);
}
}
});
ImageIcon newIcon = new ImageIcon("new-image.png");
JMenuItem newAction = new JMenuItem("Open Image", newIcon);
fileMenu.add(newAction);
newAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ImageIcon saveIcon = new ImageIcon("save-icon.png");
int askSave = JOptionPane.showConfirmDialog(null,"Save current image?", "", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, saveIcon);
if (askSave == JOptionPane.YES_OPTION) {
//opens save image method, then asks asks for new image file
saveImage();
Picture p = new Picture();
imageLabel.setIcon(new ImageIcon(image));
//resizes canvas to fit new image
frame.setSize(width(), height());
}
else {
//asks for new image file since user did not want to save original
Picture p = new Picture();
imageLabel.setIcon(new ImageIcon(image));
//resizes canvas to fit new image
frame.setSize(width(), height());
}
}
});
ImageIcon saveIcon = new ImageIcon("save-image.png");
JMenuItem saveAction = new JMenuItem("Save Image As...", saveIcon);
fileMenu.add(saveAction);
saveAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//opens save image method
saveImage();
}
});
ImageIcon gsIcon = new ImageIcon("grayscale-image.png");
JMenuItem grayScale = new JMenuItem("Grayscale", gsIcon);
editMenu.add(grayScale);
grayScale.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//grabs height and width of image, then grayscales it
grayscale(width(), height());
}
});
ImageIcon scaleIcon = new ImageIcon("scale-image.png");
JMenuItem scaleImg = new JMenuItem("Scale Image", scaleIcon);
editMenu.add(scaleImg);
scaleImg.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//asks for height and width to create new image
ImageIcon widthIcon = new ImageIcon("LR-arrows.png");
String scaleWidth = (String)JOptionPane.showInputDialog(null,"What should the new width be?", "", JOptionPane.QUESTION_MESSAGE, widthIcon, null, null);
ImageIcon heightIcon = new ImageIcon("UD-arrows.png");
String scaleHeight = (String)JOptionPane.showInputDialog(null,"What should the new height be?", "", JOptionPane.QUESTION_MESSAGE, widthIcon, null, null);
//turns user input strings into doubles
double x = Double.parseDouble(scaleWidth);
double y = Double.parseDouble(scaleHeight);
//casts doubles as ints
int newWidth = (int)x;
int newHeight = (int)y;
//resizes frame to fit new image dimensions
frame.setSize(newWidth, newHeight);
//calls scale method to resize image using given dimensions
scale(newWidth, newHeight);
}
});
ImageIcon rotateIcon = new ImageIcon("rotate-image.png");
JMenuItem rotateImg = new JMenuItem("Rotate Image", rotateIcon);
editMenu.add(rotateImg);
rotateImg.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
//paint the frame
frame.pack();
frame.repaint();
frame.setVisible(true);
}
// convert to grayscale
public void grayscale(int width, int height) {
// create a grayscale image with original dimensions
image2 = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
// convert colored image to grayscale
ColorConvertOp grayScale = new ColorConvertOp(image.getColorModel().getColorSpace(),image2.getColorModel().getColorSpace(),null);
grayScale.filter(image,image2);
imageLabel.setIcon(new ImageIcon(image2));
//getImage();
image = image2;
}
//scales image by a given factor
public void scale(int width, int height){
//uses user-input dimensions to create new image
image2 = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics g = image2.createGraphics();
//gets new dimensions and resizes image
g.drawImage(image, 0, 0, image2.getWidth(), image2.getHeight(), 0, 0, width(), height(), null);
imageLabel.setIcon(new ImageIcon(image2));
//getImage();
image = image2;
}
//rotates the image
public void rotate(int width, int height, int theta) {
}
public static void main(String[] args) {
Picture p = new Picture();
p.show();
}
}
public void getImage() {
this.image2 = image;
}
//..............................................
// convert to grayscale
public void grayscale(int width, int height) {
// create a grayscale image with original dimensions
image2 = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
// convert colored image to grayscale
ColorConvertOp grayScale = new ColorConvertOp(image.getColorModel().getColorSpace(),image2.getColorModel().getColorSpace(),null);
grayScale.filter(image,image2);
imageLabel.setIcon(new ImageIcon(image2));
getImage();
}
ColorConvertOp.filter(BufferedImage src, BufferedImage dest)
Your grayscale method has image2 as the dest, when you call getImage() it replaces image2 with the original not settieng the original to your new image2.
Either have grayscale(int, int) return a BuffereImage or change getImage to:
public void getImage() {
this.image = image2;
}
Related
I have the following problems:
I don't know why my function, when displaying already rotated images, shows only one in as many jpanels as there were photos given.
Let me give an example: I load 4 images into hashmap. Then I put them into my rotate function and try to display them. I end up with 4 tabs of one rotated image.
When I'm trying to rotate twice using the same deegres as used previously (I'm using slider to take degrees) it doesn't rotate anymore but if I touch slider and move it, the function rotates normally.
I had no idea how to convert an Image type into File object thus I converted it into BufferedImage and then to File. I browsed through the Internet but could not find anything helpful.
My main's class piece of code:
JPanel panel_2e = new JPanel();
panel_2e.setOpaque(true);
panel_2e.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED, Color.GRAY, Color.DARK_GRAY), "Rotate options"));
panel_2e.setLayout(new BoxLayout(panel_2e,BoxLayout.Y_AXIS));
JSlider slider = new JSlider(JSlider.HORIZONTAL, 0, 360, 180);
slider.setMinorTickSpacing(10);
slider.setMajorTickSpacing(90);
slider.setPaintTicks(true);
slider.setPaintLabels(true);
slider.setLabelTable(slider.createStandardLabels(45));
JPanel radio_buttons_rotate=new JPanel();
radio_buttons_rotate.setLayout(new BoxLayout(radio_buttons_rotate, BoxLayout.Y_AXIS));
JCheckBox cut_frame = new JCheckBox("Cut edges");
cut_frame.setSelected(true);
cut_frame.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
if(e.getStateChange() == ItemEvent.SELECTED)
{check = true;
System.out.println("Cut-edge mode selected");}
else
{check = false;
System.out.println("Cut-edge mode deselected");}
}
});
cut_frame.setBounds(78, 41, 60, 23);
radio_buttons_rotate.add(cut_frame);
JRadioButton black_rdbutton = new JRadioButton("Black background");
black_rdbutton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
black = true;
}
});
black_rdbutton.setBounds(78, 41, 60, 23);
radio_buttons_rotate.add(black_rdbutton);
JRadioButton white_rdbutton = new JRadioButton("White background");
white_rdbutton.setSelected(true);
white_rdbutton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
black = false;
}
});
white_rdbutton.setBounds(78, 41, 60, 23);
radio_buttons_rotate.add(white_rdbutton);
ButtonGroup group_frame_rotate = new ButtonGroup();
group_frame_rotate.add(black_rdbutton);
group_frame_rotate.add(white_rdbutton);
panel_2e.add(radio_buttons_rotate);
JLabel Rotate = new JLabel();
Rotate.setText(deg+"\u00b0");
panel_2e.add(slider);
JButton btnRotate = new JButton("Rotate");
JPanel RotatePanel=new JPanel();
RotatePanel.add(Rotate);
RotatePanel.add(btnRotate);
RotatePanel.setLayout(new FlowLayout());
btnRotate.setBounds(28, 158, 89, 23);
btnRotate.setBackground(Color.DARK_GRAY);
btnRotate.setForeground(Color.WHITE);
panel_2e.add(RotatePanel);
panel_2.add(panel_2e);
slider.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent ce) {
deg=((JSlider) ce.getSource()).getValue();
Rotate.setText(deg+"\u00b0"); }
});
btnRotate.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if(AddDirectory.all_chosen.isEmpty())
{Object[] options = {"OK"};
int n = JOptionPane.showOptionDialog(frame,
"Please choose at least 1 image to rotate.","Empty work list",
JOptionPane.PLAIN_MESSAGE,
JOptionPane.QUESTION_MESSAGE,
null,
options,
options[0]);}
else
{RotateFunction rot = new RotateFunction(AddDirectory.all_chosen);
rot.main();
BufferedImage kk = null;
Display disp= new Display(); // invoke Display class
for(File i : all_chosen_images.values()){
try{
kk = ImageIO.read(new File(i.getAbsolutePath()));
disp.createFrame(center, i, kk); //create new frame with image
}
catch (IOException es){
es.printStackTrace();
}
}
}
}
});
And here is my rotate function:
public class RotateFunction{
HashMap<JButton,File> map;
Image spiral;
RotateFunction(HashMap<JButton,File> source_of_image)
{
map = AddDirectory.all_chosen;
}
public void main(){
int counter = 0;
if (spiral == null){
for(Map.Entry<JButton, File> entry: map.entrySet()) //////Moving through hashMap
{
try {
spiral = getImage(entry.getValue().getAbsolutePath());
counter++;
System.out.println("Path of image " + counter + " : " +entry.getValue().getAbsolutePath());
if (PhotoEdit.check == true){
rotateImage(PhotoEdit.deg, null);
System.out.println("Rotating image "+counter+" by "+PhotoEdit.deg+" degrees (edge cut)");
}
else{
rotateImage1(PhotoEdit.deg, null);
System.out.println("Rotating image "+counter+" by "+PhotoEdit.deg+" degrees (bigger frame)");
}
BufferedImage tmp = toBufferedImage(spiral);
File f;
f = new File( "image.png" );
try
{
ImageIO.write( tmp, "PNG", f );
}
catch ( IOException x )
{
// Complain if there was any problem writing
// the output file.
x.printStackTrace();
}
map.put(entry.getKey(), f);
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
PhotoEdit.all_chosen_images.clear();
PhotoEdit.all_chosen_images.putAll(map); //Putting HashMap with rotated images into global HashMap
System.out.println("Images have been successfully rotated");
}
}
public Image getImage(String path){
Image tempImage = null;
try
{
tempImage = Toolkit.getDefaultToolkit().getImage(path);
}
catch (Exception e)
{
System.out.println("An error occured - " + e.getMessage());
}
return tempImage;
}
////////////////////////////////////////////////////////////////////
///////////////////IMAGE ROTATION /////////////////////////////////
public void rotateImage(double degrees, ImageObserver o){
ImageIcon icon = new ImageIcon(this.spiral);
BufferedImage blankCanvas = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = (Graphics2D)blankCanvas.getGraphics();
g2.rotate(Math.toRadians(degrees), icon.getIconWidth()/2, icon.getIconHeight()/2);
g2.drawImage(this.spiral, 0, 0, o);
this.spiral = blankCanvas;
}
public void rotateImage1(double degrees, ImageObserver o){
double sin = Math.abs(Math.sin(Math.toRadians(degrees)));
double cos = Math.abs(Math.cos(Math.toRadians(degrees)));
ImageIcon icon = new ImageIcon(this.spiral);
int w = icon.getIconWidth();
int h = icon.getIconHeight();
int neww = (int)Math.floor(w*cos+h*sin);
int newh = (int)Math.floor(h*cos+w*sin);
BufferedImage blankCanvas = new BufferedImage(neww, newh, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = (Graphics2D)blankCanvas.getGraphics();
g2.translate((neww-w)/2, (newh-h)/2);
g2.rotate(Math.toRadians(degrees), icon.getIconWidth()/2, icon.getIconHeight()/2);
g2.drawImage(this.spiral, 0, 0, o);
this.spiral = blankCanvas;
}
//////////////////////////////////////////////////////////////////////////
public static BufferedImage toBufferedImage(Image img)
{
if (img instanceof BufferedImage)
{
return (BufferedImage) img;
}
// Create a buffered image with transparency
BufferedImage bimage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
// Draw the image on to the buffered image
Graphics2D bGr = bimage.createGraphics();
bGr.drawImage(img, 0, 0, null);
bGr.dispose();
// Return the buffered image
return bimage;
}
}
In the display function i have the following arguments - createFrame(JDekstopPane where_to_put_the_image, File img, BufferedImage image)
HashMap - all_chosen_images is the global HashMap storing all the images
Really hope for your help.
Aleksander
I am trying to make a java desktop application. I have a JLabel where I am shuffling image but all image sizes are different so I want to fix size of the image on JLabel.
How can I do this?
Here is my code :
public class ImageShuffle1 extends JPanel {
private List<Icon> list = new ArrayList<Icon>();
private List<Icon> shuffled;
private JLabel label = new JLabel();
private Timer timer = new Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
update();
}
});
public ImageShuffle1() {
this.setLayout(new GridLayout(1, 0));
list.add(new ImageIcon("E:\\SOFTWARE\\TrainPIS\\res\\drawable\\e.jpg"));
list.add(new ImageIcon("E:\\SOFTWARE\\TrainPIS\\res\\drawable\\d.jpg"));
list.add(new ImageIcon("E:\\SOFTWARE\\TrainPIS\\res\\drawable\\yellow.png"));
list.add(new ImageIcon("E:\\SOFTWARE\\TrainPIS\\res\\drawable\\f.jpg"));
list.add(new ImageIcon("E:\\SOFTWARE\\TrainPIS\\res\\drawable\\l.jpg"));
//label.setIcon(UIManager.getIcon("OptionPane.informationIcon"));
for(Icon icon: list){
Image img = icon.getImage() ;
// put here the size properties
Image newimg = img.getScaledInstance( 45, 34, java.awt.Image.SCALE_SMOOTH ) ;
icon = new ImageIcon(newimg);
}
shuffled = new ArrayList<Icon>(list);
Collections.shuffle(shuffled);
timer.start();
}
private void update() {
if (shuffled.isEmpty()) {
shuffled = new ArrayList<Icon>(list);
Collections.shuffle(shuffled);
}
Icon icon = shuffled.remove(0);
label.setIcon(icon);
}
private void display() {
JFrame f = new JFrame("ImageShuffle");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.add(label);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new ImageShuffle1().display();
}
});
}
}
I am getting error herein this.
line/variable getimage can not found mage img = icon.getImage() ;
Thanks in advance
Use BufferedImage in place of Icon that has a functionality to re size it.
Here is the code
import java.awt.EventQueue;
import java.awt.Graphics2D;
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.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
public class ImageShuffle1 extends JPanel {
private List<BufferedImage> list = new ArrayList<BufferedImage>();
private List<BufferedImage> shuffled;
private JLabel label = new JLabel();
private int width = 50;
private int height = 100;
private Timer timer = new Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
update();
}
});
public ImageShuffle1() {
try {
list.add(resizeImage(ImageIO.read(new File("resources/1.png"))));
list.add(resizeImage(ImageIO.read(new File("resources/2.png"))));
list.add(resizeImage(ImageIO.read(new File("resources/6.png"))));
list.add(resizeImage(ImageIO.read(new File("resources/Tulips.jpg"))));
} catch (IOException e) {
e.printStackTrace();
}
shuffled = new ArrayList<BufferedImage>(list);
Collections.shuffle(shuffled);
timer.start();
}
private BufferedImage resizeImage(BufferedImage originalImage) throws IOException {
BufferedImage resizedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = resizedImage.createGraphics();
g.drawImage(originalImage, 0, 0, width, height, null);
g.dispose();
return resizedImage;
}
private void update() {
if (shuffled.isEmpty()) {
shuffled = new ArrayList<BufferedImage>(list);
Collections.shuffle(shuffled);
}
BufferedImage icon = shuffled.remove(0);
label.setIcon(new ImageIcon(icon));
}
private void display() {
JFrame f = new JFrame("ImageShuffle");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.add(label);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new ImageShuffle1().display();
}
});
}
}
Lets start with this...
for(Icon icon: list){
Image img = icon.getImage() ;
Icon does not have a method getImage, there is actually no way to get the "image" data maintained by the Icon class without first rendering it to something (like a BufferedImage)
A better solution might be to load the images into a List that supports BufferedImage. BufferedImage is a more versatile starting point and because it extends from Image, it can be used with ImageIcon. For example...
private List<BufferedImage> list = new ArrayList<BufferedImage>();
//...
list.add(ImageIO.read("E:\\SOFTWARE\\TrainPIS\\res\\drawable\\e.jpg"));
Take a look at Reading/Loading an Image
For scaling you might like to take a look at
The Perils of Image.getScaledInstance
Java: maintaining aspect ratio of JPanel background image
Quality of Image after resize very low -- Java
First you resize every image to a fixed size and it must be fit in JLabel
public static Boolean resizeImage(String sourceImage, String destinationImage, Integer Width, Integer Height) {
BufferedImage origImage;
try {
origImage = ImageIO.read(new File(sourceImage));
int type = origImage.getType() == 0? BufferedImage.TYPE_INT_ARGB : origImage.getType();
//*Special* if the width or height is 0 use image src dimensions
if (Width == 0) {
Width = origImage.getWidth();
}
if (Height == 0) {
Height = origImage.getHeight();
}
int fHeight = Height;
int fWidth = Width;
//Work out the resized width/height
if (origImage.getHeight() > Height || origImage.getWidth() > Width) {
fHeight = Height;
int wid = Width;
float sum = (float)origImage.getWidth() / (float)origImage.getHeight();
fWidth = Math.round(fHeight * sum);
if (fWidth > wid) {
//rezise again for the width this time
fHeight = Math.round(wid/sum);
fWidth = wid;
}
}
BufferedImage resizedImage = new BufferedImage(fWidth, fHeight, type);
Graphics2D g = resizedImage.createGraphics();
g.setComposite(AlphaComposite.Src);
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.drawImage(origImage, 0, 0, fWidth, fHeight, null);
g.dispose();
ImageIO.write(resizedImage, "png", new File(destinationImage));
...
I want to convert an JPanel to an image. I used the following method:
public BufferedImage createImage(){
int w = getWidth();
int h = getHeight();
BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bi.createGraphics();
paint(g);
return bi;
}
But the problem is that the JPanel is contained within a JScrollPane. So when I convert the jpanel to an image, the image contains only the parts visible in the jpanel and the parts that are hidden inside the scrollpane aren't contained in the image.
Are there any solutions to get the full content of the JPanel into an image?
But the problem is that the JPanel is contained within a JScrollPane.
So when I convert the jpanel to an image, the image contains only the
parts visible in the jpanel and the parts that are hidden inside the
scrollpane aren't contained in the image.
This doesnt happen to me... have you tried paintAll instead of paint?
Here is a great method which will capture the content of any Component visible or not (Its not mine I got it somewhere off the SO and have used it since):
public static BufferedImage componentToImage(Component component, boolean visible) {
if (visible) {
BufferedImage img = new BufferedImage(component.getWidth(), component.getHeight(), BufferedImage.TRANSLUCENT);
Graphics2D g2d = (Graphics2D) img.getGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
component.paintAll(g2d);
return img;
} else {
component.setSize(component.getPreferredSize());
layoutComponent(component);
BufferedImage img = new BufferedImage(component.getWidth(), component.getHeight(), BufferedImage.TRANSLUCENT);
CellRendererPane crp = new CellRendererPane();
crp.add(component);
crp.paintComponent(img.createGraphics(), component, crp, component.getBounds());
return img;
}
}
private static void layoutComponent(Component c) {
synchronized (c.getTreeLock()) {
c.doLayout();
if (c instanceof Container) {
for (Component child : ((Container) c).getComponents()) {
layoutComponent(child);
}
}
}
}
Here is an example showcasing the above:
The frame view:
capture of the panel:
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.CellRendererPane;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
public class Test {
public Test() {
createAndShowGui();
}
private void createAndShowGui() {
JFrame frame = new JFrame() {
#Override
public Dimension getPreferredSize() {//size frame purposefully smaller
return new Dimension(100, 100);
}
};
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
Image img = null;
try {
img = ImageIO.read(new URL("http://images4.wikia.nocookie.net/__cb20120515073660/naruto/images/0/09/Naruto_newshot.png")).getScaledInstance(200, 200, Image.SCALE_SMOOTH);
} catch (Exception ex) {
ex.printStackTrace();
}
final ImagePanel imagePanel = new ImagePanel(200, 200, img);
JScrollPane jsp = new JScrollPane(imagePanel);
frame.add(jsp);
frame.pack();
frame.setVisible(true);
BufferedImage bi = componentToImage(imagePanel, true);
try {
File outputfile = new File("c:/saved.png");
ImageIO.write(bi, "png", outputfile);
} catch (IOException e) {
e.printStackTrace();
}
}
public static BufferedImage componentToImage(Component component, boolean visible) {
if (visible) {
BufferedImage img = new BufferedImage(component.getWidth(), component.getHeight(), BufferedImage.TRANSLUCENT);
Graphics2D g2d = (Graphics2D) img.getGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
component.paintAll(g2d);
return img;
} else {
component.setSize(component.getPreferredSize());
layoutComponent(component);
BufferedImage img = new BufferedImage(component.getWidth(), component.getHeight(), BufferedImage.TRANSLUCENT);
CellRendererPane crp = new CellRendererPane();
crp.add(component);
crp.paintComponent(img.createGraphics(), component, crp, component.getBounds());
return img;
}
}
private static void layoutComponent(Component c) {
synchronized (c.getTreeLock()) {
c.doLayout();
if (c instanceof Container) {
for (Component child : ((Container) c).getComponents()) {
layoutComponent(child);
}
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Test();
}
});
}
}
class ImagePanel extends JPanel {
int width, height;
Image bg;
public ImagePanel(int width, int height, Image bg) {
this.width = width;
this.height = height;
this.bg = bg;
}
#Override
public Dimension getPreferredSize() {
return new Dimension(width, height);
}
#Override
protected void paintComponent(Graphics grphcs) {
super.paintComponent(grphcs);
grphcs.drawImage(bg, 0, 0, null);
}
}
UPDATE:
As per your comment:
I wrote the BufferedImage into a file by using
ImageIO.write(bufferedImage, "jpg" , file); this works fine for both
png and gif images, but jpg image shows a red background instead of
white. How can i slove that problem. Thanks
See this similar question/answer for more. You would do something like:
private static final int[] RGB_MASKS = {0xFF0000, 0xFF00, 0xFF};
private static final ColorModel RGB_OPAQUE = new DirectColorModel(32, RGB_MASKS[0], RGB_MASKS[1], RGB_MASKS[2]);
...
BufferedImage image = componentToImage(imagePanel, true);
saveJPeg(image, "c:/saved.jpg");
private void saveJPeg(BufferedImage image, String name) {
PixelGrabber pg = new PixelGrabber(image, 0, 0, -1, -1, true);
try {
pg.grabPixels();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
int width = pg.getWidth(), height = pg.getHeight();
DataBuffer buffer = new DataBufferInt((int[]) pg.getPixels(), pg.getWidth() * pg.getHeight());
WritableRaster raster = Raster.createPackedRaster(buffer, width, height, width, RGB_MASKS, null);
BufferedImage bi = new BufferedImage(RGB_OPAQUE, raster, false, null);
try {
ImageIO.write(bi, "jpg", new File(name));
} catch (IOException ex) {
ex.printStackTrace();
}
}
SwingUtilities.paintComponent does it:
static void drawComponent(JComponent c,
BufferedImage destination) {
JFrame frame = new JFrame();
Graphics g = destination.createGraphics();
SwingUtilities.paintComponent(g, c, frame.getContentPane(),
0, 0, destination.getWidth(), destination.getHeight());
g.dispose();
frame.dispose();
}
static BufferedImage createSnapshotOf(JComponent c) {
Dimension size = c.getSize();
if (size.width <= 0 || size.height <= 0) {
size = c.getPreferredSize();
}
BufferedImage snapshot =
new BufferedImage(size.width, size.height,
BufferedImage.TYPE_INT_ARGB);
drawComponent(c, snapshot);
return snapshot;
}
I don't know why you need to do something so complicated. As long as your Buffered image and paint function all use the component (huge) that is the in the JScroolPane, the whole thing should be saved.
//create a tree data structure
DefaultMutableTreeNode tree = new DefaultMutableTreeNode("root");
//optional: you can make the tree really big
//now show the tree
JFrame frame = new JFrame("TreeDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create a Jtree component to display your data structure
JTree treeDisplay = new JTree(tree);
//expand the tree all out
for(int i = 0; i < treeDisplay.getRowCount(); i++) {
treeDisplay.expandRow(i);
}
//put your tree display component in a scroll pane
frame.add(new JScrollPane(treeDisplay));
//Display the window.
frame.pack();
frame.setVisible(true);
//save tree in the window to a file
BufferedImage img = new BufferedImage(treeDisplay.getWidth(), treeDisplay.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = img.createGraphics();
//put graphics on the buffered image
treeDisplay.paintAll(graphics);
graphics.dispose();
try {
ImageIO.write(img, "png", new File("tree.png"));
}
catch (IOException e) {
e.printStackTrace();
}
I am loading a button picture which is png format. But the format is too large. How can i resize the width and height of that to defined range, but avoid using the image size.
Before:
public JButton createButton(String name, String toolTip) {
Image a = null;
try {
a = ImageIO.read((InputStream) Test.class.getResourceAsStream("/image/menu/" + name + ".png"));
} catch (IOException ex) {
ex.printStackTrace();
}
ImageIcon iconRollover = new ImageIcon(a);
int w = iconRollover.getIconWidth();
int h = iconRollover.getIconHeight();
// get the cursor for this button
Cursor cursor =
Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
// make translucent default image
//Image image = screen.createCompatibleImage(w, h, Transparency.TRANSLUCENT);
Graphics2D g = (Graphics2D) a.getGraphics();
Composite alpha = AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, .5f);
g.setComposite(alpha);
g.drawImage(iconRollover.getImage(), 0, 0, null);
g.dispose();
ImageIcon iconDefault = new ImageIcon(a);
ImageIcon iconPressed = new ImageIcon(a);
// create the button
JButton button = new JButton();
button.setIgnoreRepaint(true);
button.setFocusable(false);
button.setToolTipText(toolTip);
button.setBorder(null);
button.setContentAreaFilled(false);
button.setCursor(cursor);
button.setIcon(iconDefault);
button.setRolloverIcon(iconRollover);
button.setPressedIcon(iconPressed);
return button;
}
After:
Follow up:
public JButton createButton(String name, String toolTip) {
// Create image
BufferedImage a = null;
try {
a = ImageIO.read((InputStream) P2P.class.getResourceAsStream("/image/menu/" + name + ".png"));
} catch (IOException ex) {
ex.printStackTrace();
}
BufferedImage bi = new BufferedImage(70, 70, BufferedImage.TRANSLUCENT);
Graphics2D g = (Graphics2D) bi.getGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(a, 0, 0, 70, 70, null);
g.dispose();
// get the cursor for this button
Cursor cursor =
Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
ImageIcon iconRollover = new ImageIcon(bi);
ImageIcon iconDefault = new ImageIcon(bi);
ImageIcon iconPressed = new ImageIcon(bi);
// create the button
JButton button = new JButton();
//button.addActionListener(this);
button.setIgnoreRepaint(true);
button.setFocusable(false);
button.setToolTipText(toolTip);
button.setBorder(null);
button.setContentAreaFilled(false);
button.setCursor(cursor);
button.setIcon(iconDefault);
button.setRolloverIcon(iconRollover);
button.setPressedIcon(iconPressed);
return button;
}
Why not use the getScaledInstance() method on your Image instance like this:
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
static int width=300;//change this to your wanted size
static int height =500;
public class Main extends JFrame implements ActionListener {
Image img;
JButton getPictureButton = new JButton("Get Picture");
public static void main(String[] args) {
new Main();
}
public Main() {
this.setSize(600, 600);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel picPanel = new PicturePanel();
this.add(picPanel, BorderLayout.CENTER);
JPanel buttonPanel = new JPanel();
getPictureButton.addActionListener(this);
buttonPanel.add(getPictureButton);
this.add(buttonPanel, BorderLayout.SOUTH);
this.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
String file = "a.png";
if (file != null) {
Toolkit kit = Toolkit.getDefaultToolkit();
img = kit.getImage(file);
img = img.getScaledInstance(width, height, Image.SCALE_SMOOTH);//scale the image to wanted size
this.repaint();
}
}
class PicturePanel extends JPanel {
public void paintComponent(Graphics g) {
g.drawImage(img, 0, 0, this);
}
}
}
/**
* #param img image (Image or ImageIcon)
* #param w the width of the returned image
* #param h the height of the returned image
* #param imgW the width of the graphics in the returned image
* #param imgH the height of the graphics in the returned image
* #return ImageIcon
*/
public static ImageIcon resizeImage(Object img, Integer w, Integer h, Integer imgW, Integer imgH) {
Image image = objectToImage(img);
if(w == null)
w=image.getWidth(null);
if(h == null)
h=image.getHeight(null);
if(imgW == null)
imgW=w;
else if(imgH == null)
imgH=imgW;
if(imgH == null)
imgH=h;
BufferedImage resizedImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = resizedImage.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.drawImage(toBufferedImage(image), (w-imgW)/2, (h-imgH)/2, imgW, imgH, null);
g2d.dispose();
return new ImageIcon(resizedImage);
}
public static Image objectToImage(Object img) {
if(img instanceof ImageIcon)
return ((ImageIcon)img).getImage();
else if(img instanceof Image)
return (Image)img;
else
throw new ClassCastException();
}
public static BufferedImage toBufferedImage(Image img) {
BufferedImage bi = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = bi.createGraphics();
g2d.drawImage(img, 0, 0, null);
g2d.dispose();
return bi;
}
Works
public JButton createButton(String name, String toolTip) {
// Create image
BufferedImage a = null;
try {
a = ImageIO.read((InputStream) P2P.class.getResourceAsStream("/image/menu/" + name + ".png"));
} catch (IOException ex) {
ex.printStackTrace();
}
BufferedImage bi = new BufferedImage(70, 70, BufferedImage.TRANSLUCENT);
Graphics2D g = (Graphics2D) bi.getGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(a, 0, 0, 70, 70, null);
g.dispose();
// get the cursor for this button
Cursor cursor =
Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
ImageIcon iconRollover = new ImageIcon(bi);
ImageIcon iconDefault = new ImageIcon(bi);
ImageIcon iconPressed = new ImageIcon(bi);
// create the button
JButton button = new JButton();
//button.addActionListener(this);
button.setIgnoreRepaint(true);
button.setFocusable(false);
button.setToolTipText(toolTip);
button.setBorder(null);
button.setContentAreaFilled(false);
button.setCursor(cursor);
button.setIcon(iconDefault);
button.setRolloverIcon(iconRollover);
button.setPressedIcon(iconPressed);
return button;
}
I have an image editing program. It has several methods, such as grayscale, scale, merge images, etc. Each method works perfectly on its own. However, I am getting an error when calling grayScale method after mergeImg method has been called. It doesn't happen if I apply grayscale first.
Here is the error:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at Picture.width(Picture.java:51)
at Picture$4.actionPerformed(Picture.java:222)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.AbstractButton.doClick(AbstractButton.java:376)
at javax.swing.plaf.basic.BasicMenuItemUI.doClick(BasicMenuItemUI.java:833)
at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(BasicMenuItemUI.java:877)
at java.awt.Component.processMouseEvent(Component.java:6504)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
at java.awt.Component.processEvent(Component.java:6269)
at java.awt.Container.processEvent(Container.java:2229)
at java.awt.Component.dispatchEventImpl(Component.java:4860)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Component.dispatchEvent(Component.java:4686)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
at java.awt.Container.dispatchEventImpl(Container.java:2273)
at java.awt.Window.dispatchEventImpl(Window.java:2713)
at java.awt.Component.dispatchEvent(Component.java:4686)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:707)
at java.awt.EventQueue.access$000(EventQueue.java:101)
at java.awt.EventQueue$3.run(EventQueue.java:666)
at java.awt.EventQueue$3.run(EventQueue.java:664)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.awt.EventQueue$4.run(EventQueue.java:680)
at java.awt.EventQueue$4.run(EventQueue.java:678)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:677)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
And here is my code:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;
import javax.swing.*;
import java.awt.image.*;
import javax.imageio.ImageIO;
import java.lang.Math;
public class Picture{
JFileChooser fileChooser = new JFileChooser(); //file chooser
final JFrame frame = new JFrame("ImageEdit"); //creates JFrame
Container content; //creates container to place GUI objects in
static BufferedImage image; //original image
BufferedImage image2; //image after changes are made
BufferedImage mergeImage; //used for mergeImg method
JLabel imageLabel; //used to display image
//constructor; welcomes user, asks for image input
public Picture() {
//pops up prior to JFileChooser, intstructing user on what to do
Object[] options = {"Browse...", "Exit"};
ImageIcon welcomeIcon = new ImageIcon("GUI-images/welcome-icon.png");
int getFile = JOptionPane.showOptionDialog(frame, "Welcome to ImageEdit. To begin, please select an image file to edit.",
"Welcome!", JOptionPane.YES_NO_OPTION, JOptionPane.INFORMATION_MESSAGE, welcomeIcon, options, options[0]);
//if user selects browse option, do this:
if (getFile == JOptionPane.YES_OPTION) {
//asks for image file as input
browse();
}
//otherwise, exit program
else {
//exit program
System.exit(0);
}
}
//method returns width of image
public int width() {
int width = image.getWidth();
return width;
}
//method returns height of image
public int height() {
int height = image.getHeight();
return height;
}
//method sets updated image as "original" image
public void setImage() {
this.image = image2;
}
//method writes image in destination
public void saveImage() {
//gets file name & destination from user through JFileChooser
fileChooser.setDialogTitle("Save As...");
fileChooser.showSaveDialog(frame);
//writes image to new file with given name & location
try {
ImageIO.write(this.image, "JPG", fileChooser.getSelectedFile());
}
catch (IOException f) {
System.out.println("Saving failed! Could not save image.");
}
}
//method browses for new file
public void browse() {
//asks for new image file
fileChooser.setDialogTitle("Choose an image file:");
fileChooser.showOpenDialog(frame);
File selectedFile = fileChooser.getSelectedFile();
//if user has selected image file, continue
if (fileChooser.getSelectedFile() != null) {
try {
//reads selectedFile as image
image = ImageIO.read(selectedFile);
}
catch (IOException e) {
System.out.println("Invalid image file: " + selectedFile);
System.exit(0);
}
}
//else print error message
else {
System.out.println("Error! No File Selected.");
}
}
//method creates frame, adds menubar with options, provides parameters for other methods
public void show() {
//set frame title, set it visible, etc
content = frame.getContentPane();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
//add the image to the frame
ImageIcon icon = new ImageIcon(image);
imageLabel = new JLabel(icon);
frame.setContentPane(imageLabel);
//adds a menubar on the frame with program name, File & Edit menus
JMenuBar menuBar = new JMenuBar();
frame.setJMenuBar(menuBar);
JMenu progName = new JMenu("ImageEdit");
progName.setBackground(Color.RED);
menuBar.add(progName);
JMenu fileMenu = new JMenu("File");
menuBar.add(fileMenu);
JMenu editMenu = new JMenu("Edit");
menuBar.add(editMenu);
//adds options to JMenus
//option to exit application
ImageIcon exitIcon = new ImageIcon("GUI-images/app-exit.png");
JMenuItem exitAction = new JMenuItem("Exit", exitIcon);
progName.add(exitAction);
//if exit option is selected, do this:
exitAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//prompts to save file before exiting
ImageIcon saveIcon = new ImageIcon("GUI-images/save-icon.png");
int askSave = JOptionPane.showConfirmDialog(null,"Save image before exit?", "Save...",
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, saveIcon);
if (askSave == JOptionPane.YES_OPTION) {
//opens save image method, then exits
saveImage();
System.exit(0);
}
else {
//exits without saving
System.exit(0);
}
}
});
//option to open a new image
ImageIcon newIcon = new ImageIcon("GUI-images/new-image.png");
JMenuItem newAction = new JMenuItem("Open Image", newIcon);
fileMenu.add(newAction);
//if new option is selected, do this:
newAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//prompts to save image before opening new image
ImageIcon saveIcon = new ImageIcon("GUI-images/save-icon.png");
int askSave = JOptionPane.showConfirmDialog(null,"Save current image?", "Save...",
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, saveIcon);
//if they do want to save first, do this:
if (askSave == JOptionPane.YES_OPTION) {
//opens save image method, then asks asks for new image file
saveImage();
//clears old image
imageLabel.setIcon(null);
//browses for new image
browse();
//displays new image
imageLabel.setIcon(new ImageIcon(image));
//resizes canvas to fit new image
frame.setSize(width(), height());
}
//if they don't want to save, do this:
else {
//erases old image
imageLabel.setIcon(null);
//browses for new image
browse();
//displays new image
imageLabel.setIcon(new ImageIcon(image));
//resizes canvas to fit new image
frame.setSize(width(), height());
}
}
});
//option to save current image
ImageIcon saveIcon = new ImageIcon("GUI-images/save-image.png");
JMenuItem saveAction = new JMenuItem("Save Image As...", saveIcon);
fileMenu.add(saveAction);
//if save option is selected, do this:
saveAction.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//opens save image method
saveImage();
}
});
//option to make current image grayscale
ImageIcon gsIcon = new ImageIcon("GUI-images/grayscale-image.png");
JMenuItem grayScale = new JMenuItem("Grayscale", gsIcon);
editMenu.add(grayScale);
//if grayscale option is selected, do this:
grayScale.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//grabs height and width of image,
//then calls grayscale method
grayscale(width(), height());
}
});
//option to scale current window to new dimensions
ImageIcon scaleIcon = new ImageIcon("GUI-images/scale-image.png");
JMenuItem scaleImg = new JMenuItem("Scale Image", scaleIcon);
editMenu.add(scaleImg);
//if scale option is selected, do this:
scaleImg.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//asks for height and width to create new image
ImageIcon widthIcon = new ImageIcon("GUI-images/LR-arrows.png");
String scaleWidth = (String)JOptionPane.showInputDialog(null,"What should the new width be?",
"Scale Image", JOptionPane.QUESTION_MESSAGE, widthIcon, null, null);
ImageIcon heightIcon = new ImageIcon("GUI-images/UD-arrows.png");
String scaleHeight = (String)JOptionPane.showInputDialog(null,"What should the new height be?",
"Scale Image", JOptionPane.QUESTION_MESSAGE, widthIcon, null, null);
//turns user input strings into doubles
double x = Double.parseDouble(scaleWidth);
double y = Double.parseDouble(scaleHeight);
//casts doubles as ints
int newWidth = (int)x;
int newHeight = (int)y;
//resizes frame to fit new image dimensions
frame.setSize(newWidth, newHeight);
//calls scale method to resize image using given dimensions
scale(newWidth, newHeight);
}
});
//option to merge two images together
ImageIcon mergeIcon = new ImageIcon("GUI-images/merge-image.png");
JMenuItem mergeImg = new JMenuItem("Merge Image", mergeIcon);
editMenu.add(mergeImg);
//if merge option is selected, do this:
mergeImg.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//asks for image file as input
fileChooser.setDialogTitle("Choose an image file to merge current image with.");
fileChooser.showOpenDialog(frame);
File mergeFile = fileChooser.getSelectedFile();
//if user has selected image file, continue
if (fileChooser.getSelectedFile() != null) {
try {
//reads selectedFile as image
mergeImage = ImageIO.read(mergeFile);
}
catch (IOException f) {
System.out.println("Invalid image file: " + mergeFile);
System.exit(0);
}
}
//else print error message
else {
System.out.println("Error! No File Selected.");
}
//if two images are same size, merge them
if (width() == mergeImage.getWidth() && height() == mergeImage.getHeight()) {
mergeImg(width(), height(), mergeImage);
}
//else, resize the second image to size of original, then merge
else {
scale(width(), height());
mergeImg(width(), height(), mergeImage);
}
}
});
//option to rotate image by x degrees
ImageIcon rotateIcon = new ImageIcon("GUI-images/rotate-image.png");
JMenuItem rotateImage = new JMenuItem("Rotate Image", rotateIcon);
editMenu.add(rotateImage);
//if rotate option is selected, do this:
rotateImage.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String rotateAngle = (String)JOptionPane.showInputDialog(null,"By what angle would you like to rotate?",
"Input Degrees", JOptionPane.QUESTION_MESSAGE, null/*icon goes here*/, null, null);
//turns user input strings into doubles
double angleDegs = Double.parseDouble(rotateAngle);
//converts degrees to rads
double angle = Math.toRadians(angleDegs);
//applies sine and cosine functions
int sin = (int)Math.sin(angle);
int cos = (int)Math.cos(angle);
//gets new width of rotated image
int newWidth = width()*sin + height()*cos;
int newHeight = height()*sin + width()*cos;
//sets frame to new image size
frame.setSize(newWidth, newHeight);
//calls rotate method to rotate image
rotate(newWidth, newHeight, angle);
}
});
//paint the frame
frame.pack();
frame.repaint();
frame.setVisible(true);
}
//method converts image to grayscale; 6 lines of code
public void grayscale(int width, int height) {
// create a grayscale image with original dimensions
image2 = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
// convert colored image to grayscale
ColorConvertOp grayScale = new ColorConvertOp(image.getColorModel().getColorSpace(),
image2.getColorModel().getColorSpace(),null);
grayScale.filter(image,image2);
imageLabel.setIcon(new ImageIcon(image2));
//sets new image as "original"
setImage();
}
//method scales image to user-input dimensions; 5 lines of code
public void scale(int width, int height){
//uses user-input dimensions to create new image
image2 = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics g = image2.createGraphics();
//gets new dimensions and resizes image
g.drawImage(image, 0, 0, image2.getWidth(), image2.getHeight(), 0, 0, width(), height(), null);
imageLabel.setIcon(new ImageIcon(image2));
//sets new image as "original"
setImage();
}
//method merges two images together; 14 lines of code
public void mergeImg(int width, int height, BufferedImage mergeImage) {
//creates new image from two images of same size
BufferedImage image2 = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
//get color from original image
Color c = new Color(image.getRGB(i, j));
//get colors from merge image
Color c2 = new Color(mergeImage.getRGB(i, j));
//average the colors
int r = (c.getRed()+c2.getRed())/2;
int g = (c.getGreen()+c2.getGreen())/2;
int b = (c.getBlue()+c2.getBlue())/2;
Color avgColor = new Color(r, g, b);
//set colors of new image to average of the two images
image2.setRGB(i, j, avgColor.getRGB());
imageLabel.setIcon(new ImageIcon(image2));
}
}
mergeImage = null;
//sets new image as "original"
setImage();
}
//method rotates image by user-input angle; 18 lines of code
public void rotate(int width, int height, double angle) {
//rotates image around center point
BufferedImage image2 = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//defines sin and cos functions
double sin = Math.sin(angle);
double cos = Math.cos(angle);
//gets coordinates of image center
double Xc = width/2;
double Yc = height/2;
//rotate
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
//new i,j at center of image
double iPrime = i - Xc;
double jPrime = j - Yc;
//i,j at new points after rotation
int xPrime = (int) (iPrime * cos - jPrime * sin + Xc);
int yPrime = (int) (iPrime * sin + jPrime * cos + Yc);
// plot pixel (i, j) the same color as (xPrime, yPrime) if it's in bounds
if (xPrime >= 0 && xPrime < width && yPrime >= 0 && yPrime < height) {
image2.setRGB(xPrime, yPrime, image.getRGB(i, j));
imageLabel.setIcon(new ImageIcon(image2));
}
}
}
//sets new image as "original"
setImage();
}
//main method; starts program
public static void main(String[] args) {
//creates new picture from image file
Picture p = new Picture();
//shows picture on JFrame
p.show();
}
}
Any ideas what could be up? Appreciate the help!
Judging from the stack trace and the code, it seems like this method
//method returns width of image
public int width() {
int width = image.getWidth();
return width;
}
throws a NullPointerException. The only thing that can cause this is if image is null.
I suggest you step through your problematic methods and check where and why null is assigned to the image variable.
One possible problem is that you redeclare image2 in method rotate and mergeImg.
BufferedImage image2 = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
This effectively "hides" this.image2. When you later call setImage and do
this.image = image2;
image2 doesn't refer to the local variable which you have prepared.
From the stacktrace, you instance variable image seems to be null.
public int width() {
int width = image.getWidth();
return width;
}
try to add :
public int width() {
int width = 0;
if (null != image) {
width = image.getWidth();
}
return width;
}
EDIT : as someone already commented, you should not use so many instance varibale. having a setImage() with no param should ring a bell ;-). i would add a image parameter to this method so you will be sure to update your image instance variable with something you just worked with!
like
public void setImage(BufferedImage workingImg)
Relying on the state of different instance variables modified by many class method is the best way to have unpredictable results.
Good luck