Skip to Main Content

Java SE (Java Platform, Standard Edition)

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Rotate and scale an ImageIcon. Please help

843806May 16 2008 — edited May 17 2008
Hi all! I'm trying to make an Image browser with rotate and zoom. I want to display my images using ImageIcon.

The problem is really simple but I can't figure out what to do to correct it. The problem lies in that I have to some how tell my ImageIcon that the BufferedImage has been rotated. I'm trying achieve this by creating a new BufferedImage with flipped width and height and then drawing my original bufferImage on it with drawRenderedImage().

Please have a look at my code and especially on the method create() in my ImageModel class where I create a bufferedImage to use in the ImageIcon.
It would be even better if you could run the demo program and see for yourself. Note that you in that case have to enter a path to an image in the ImageModelDemo class.

Any help greatly appriciated!
Mattias

HERE IS THE IMAGEMODEL CONTAINING THE DATA
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
import javax.swing.*;

/**
 * The ImageModel class is a JPanel that represent an image. It contains various operations that can be applied to the image.
 *
 * @author B�ck
 * @see JPanel
 * @version 4.0
 * @since JDK6.0
 */
public class ImageModel {
    
    /**Describes which way to rotate (left or right).*/
    public static enum rotateDirection {LEFT, RIGHT};
    /**<code>filePath</code> contains the system path of the image.*/
    private String filePath;
    private BufferedImage image;
    private BufferedImage resultImg;
    private AffineTransform zoomTransform = new AffineTransform();
    private AffineTransform rotateTransform = new AffineTransform();
    private int width;
    private int height;
    private final double rotateLeft = Math.toRadians(-90.00);
    private final double rotateRight = Math.toRadians(90.00);
    private double scale = 1.0;
    private double currentDegrees = 0.0;
    private boolean rotated;
    

    /**
     * Creates a new instance of ImageModel
     * @param path The system path of an image.
     */
    public ImageModel(String path) {

        filePath = path;

        try {
            image = ImageIO.read(new File(filePath));//Reads the image

        } catch (IOException e) {
        }

        width = image.getWidth();
        height = image.getHeight();
        resultImg = new BufferedImage(width, height, image.getType());
    }

    /**
     * Zooms the image to the wanted scale.
     * @param zoomScale The scale which should be applied to the image.
     * @throws zoomException This exception is thrown if the scale is out of bounds. Tolerated scaling values are between 0.1 and 5.
     */
    public void zoom(double zoomScale) throws zoomException {
        
        if (scale > 5 || scale < 0.1) {
            throw new zoomException();
        } else {
            scale = zoomScale;
            zoomTransform = AffineTransform.getScaleInstance(scale, scale);
        }
        create();
    }
    
    /**
     * Rotates the image 90 degrees left or right.
     * @param direction The direction in which the image is rotated.
     */
    public void rotate(rotateDirection direction) {
        
        if (direction == ImageModel.rotateDirection.LEFT) {
            currentDegrees += rotateLeft;
        } else {
            currentDegrees += rotateRight;
        }
        rotateTransform = AffineTransform.getRotateInstance(currentDegrees,width/2,height/2);

        if (currentDegrees == Math.toRadians(360)) {
            currentDegrees = 0;
        } else if (currentDegrees < 0) {
            currentDegrees += Math.toRadians(360);
        }
        if (currentDegrees == Math.toRadians(90) || currentDegrees == Math.toRadians(270)) {
            rotated = true;
        } else {
            rotated = false;
        }
        create();
    }
    /**
     * Resets the image to its original form.
     */
    public void reset() {////////IGNORE

        currentDegrees = 0;
        scale = 1;
    }

    /**
     * Returns a String containing the system path of the image.
     * @return <code>filePath</code> which contains the system path of the image.
     */
    public String getFilePath() {

        return filePath;
    }

    /**
     * Compares the system paths of two ImageModels.
     * @param o An Object which are to be compared with the object the method is called from.
     * @return True if the two objects have the same system path and false otherwise.
     */
    public boolean equals(Object o) {

        if (o instanceof ImageModel) {
            ImageModel im = (ImageModel) o;
            return filePath.equals(im.getFilePath());
        }
        return false;
    }

    /**
     * Returns a hash code value for the object.
     * @return A specific hash code value.
     */
    public int hashCode() {

        int hash = 9;
        hash = 59 * hash + (this.filePath != null ? this.filePath.hashCode() : 0);
        return hash;
    }
    public void create(){
        int h = (int) (height * scale);
        int w = (int) (width * scale);
        if (rotated) {
            resultImg = new BufferedImage(h, w, image.getType());
        } else {
            resultImg = new BufferedImage(w, h, image.getType());
        }
        AffineTransform at = new AffineTransform();
        at.concatenate(rotateTransform);
        at.concatenate(zoomTransform);
        Graphics2D g2 = resultImg.createGraphics();
        g2.drawRenderedImage(image, at);
        g2.dispose();
    }
    /**
     * Returns a BufferedImage with an applied affinetransform on it.
     * @return resultImg A BufferedImage with applied affinetransform
     */
    public BufferedImage getImage() {
        return resultImg;
    }
}
HERE IS THE IMAGEVIEW WHICH UPDATES THE IMAGE IN THE IMAGEICON.
import java.awt.*;
import javax.swing.*;

/**
 *
 * @author B&#65533;ck
 */
public class ImageView extends JPanel{
    
    ImageModel image;
    ImageIcon icon;
    JLabel label;
    /** Creates a new instance of ImageView*/
    public ImageView(ImageModel im) {
        image = im;
        
        this.setLayout(new BorderLayout());
        icon = new ImageIcon(image.getImage());
        JLabel label = new JLabel(icon);
        label.setBackground(Color.BLACK);
        this.add(label);
    }
    public void update(){
        icon.setImage(image.getImage());
        repaint();
        revalidate();
    }
    public ImageModel getModel(){
        return image;
    }
}
HERE IS A DEMO FOR TESTING
import java.awt.*;
import java.awt.event.*;
import java.awt.ScrollPane.*;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
/**
 *
 * @author B&#65533;ck
 * @version 3.0
 * @since JDK6.0
 */
public class ImageModelDemo extends JFrame implements ActionListener, ChangeListener{
    

    JPanel panel = new JPanel();
    ImageModel im = new ImageModel("alf.jpg");;
    ImageView view = new ImageView(im);
    JScrollPane scroll = new JScrollPane(view);
    
    JLabel label = new JLabel("TEST");
    JLabel label2 = new JLabel("TEST");
    JLabel label3 = new JLabel("TEST");
    JLabel label4 = new JLabel("TEST");
    
    JPanel buttons = new JPanel();
    
    JButton rotateLeft = new JButton("Rotate left");
    JButton rotateRight = new JButton("Rotate right");
    JButton zoomIn = new JButton("Zoom in");
    JButton zoomOut = new JButton("Zoom out");
    JButton reset = new JButton("Reset");
    JSlider zoomSlider = new JSlider(JSlider.HORIZONTAL, 10, 300, 100);;

    /** Creates a new instance of ImageModelDemo */
    public ImageModelDemo() {
        /*try{
            im2.zoom(2);
        }catch(zoomException e){}
        ImageIcon icon = im2.getImage();
        im3.rotate(ImageModel.rotateDirection.LEFT);
        ImageIcon icon2 = im3.getImage();*/
        
        
        
        label.setBackground(Color.CYAN);
        label2.setBackground(Color.CYAN);
        label3.setBackground(Color.CYAN);
        label4.setBackground(Color.CYAN);
        
        panel.setLayout(new BorderLayout());
        
        panel.add(label, BorderLayout.WEST);
        panel.add(label2, BorderLayout.EAST);
        panel.add(label3, BorderLayout.NORTH);
        buttons.add(rotateLeft);
        buttons.add(rotateRight);
        buttons.add(zoomIn);
        buttons.add(zoomOut);
        buttons.add(reset);
        buttons.add(zoomSlider);
        panel.add(buttons, BorderLayout.SOUTH);
        panel.add(scroll, BorderLayout.CENTER);
        //panel.add(new JLabel(icon), BorderLayout.CENTER);
        //panel.add(new JLabel(icon2), BorderLayout.CENTER);
        add(panel);
        
        rotateLeft.addActionListener(this);
        rotateRight.addActionListener(this);
        zoomIn.addActionListener(this);
        zoomOut.addActionListener(this);
        reset.addActionListener(this);
        zoomSlider.addChangeListener(this);
        
        setTitle("Demo :D");
        setSize(800,600);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
        
    }
    /** Listen to the slider. */
    public void stateChanged(ChangeEvent e) {
        
        JSlider source = (JSlider)e.getSource();
        
        if (!source.getValueIsAdjusting()) {
            double value = (double) source.getValue();
            double scale = (value / 100);
            try{
                view.getModel().zoom(scale);
            }catch(zoomException exception){}
            view.update();
            System.out.println("silder changed");
        }
    }
    
    public void actionPerformed(ActionEvent e){
        
        if(e.getSource() == rotateLeft){
            
            view.getModel().rotate(ImageModel.rotateDirection.LEFT);
            
        }else if(e.getSource() == rotateRight){
            
            view.getModel().rotate(ImageModel.rotateDirection.RIGHT);
            
        }else if(e.getSource() == zoomIn){
            
            try{
                view.getModel().zoom(2);
            }catch(zoomException exception){}
            
        }else if(e.getSource() == zoomOut){
            
            try{
                view.getModel().zoom(0.5);
            }catch(zoomException exception){}
            
        }else if(e.getSource() == reset){
            
            view.getModel().reset();
            
        }
        view.update();
        System.out.println("button pressed");
    }
    
    public static void main(String[] arg){
        ImageModelDemo demo = new ImageModelDemo();
    }
}
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Jun 14 2008
Added on May 16 2008
10 comments
1,532 views