Rotating a BufferedImage

I have been rotating a BufferedImage using the following code where m_Image is the BufferedImage:
AffineTransform trans = new AffineTransform();
AffineTransformOp op = null;
int imgWidth = m_Image.getWidth();
int imgHeight = m_Image.getHeight();
trans.rotate( Math.toRadians(degrees), imgWidth / 2, imgHeight / 2 );
AffineTransformOp op = new AffineTransformOp(trans, new RenderingHints(
RenderingHints.KEY_COLOR_RENDERING,
RenderingHints.VALUE_COLOR_RENDER_QUALITY));
m_Image = op.filter(m_Image, null);
The degrees variable is only ever 90, 180 or 270.
The problem occurs when degrees is 90 or 270 and the image is rectangular. After rotation the final image is square in shape and has black edging on one side.
Am I doing something wrong or am I missing something? Any suggestions welcomed.

When you pass in a null for the filter call, it creates a destination BufferedImage for you. I assume that the BufferedImage it createsw has the same size as the source image (there's no way for it to know what size you want it if e.g. you rotate by 30 degrees).
When you rotate by 90 or 270, the resulting image has the height and width swapped. You should construct a destination image with the height and width swapped from the source image and use that in the filter call.
I used the following code:
int w = image.getWidth();
int h = image.getHeight();
if( numQuadrants % 2 != 0 ) {
int temp = w;
w = h;
h = temp;
BufferedImage retval = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
op.filter(image, retval);
return retval;

Similar Messages

  • Help really needed in rotating a bufferedImage

    Its so silly, but i've been trying to get this for more than a week now and i cant get it to work.
    I have a gravity simulator and i want to rotate an image of a small ship. Just to mention it.. i have one thread that does the physics. I want to do two things: move and rotate (i always get the move method working, but not the rotate one)
    I have a class Nave (ship in spanish) and Graficador (the jpanel that paints everything). I want to say that ive tried really ALOT of things (yes, ive read google, the forums... i just like to ask for help when i really need it).
    So: here's what i've tried:
    -Ive tried to have a general affineTransform in Nave, then, when i call for example rotate, i just modify the AffineTransform and then use it to paint in the Jpanel. Something like this:
    In Nave
    public void rotarDer(){
            this.at.rotate(Math.PI/2,this.info.getPosX()+5,this.info.getPosY()+5);
        }And in the Jpanel:
    if(this.nave.at!=null){
                g2.drawImage(this.nave.imagen,this.nave.at,null);
            }Ive also tried to use drawRenderedImage with the AffineTransform, but the result are the same: the coordinate system changes (i think because of the AffineTransform) so the gravity takes the ship to the right instead of making it fall down. Ive tried to "store" the affineTransform before any change, and then reapply it after drawing the image, but doesnt seem to work either.
    Also, with this approach, ive tried to create a "buffer" in Nave, then paint the image in the buffer with the affineTransform, and finally paint this buffer in the jpanel, but it gets messed up anyway.
    Ive tried many approaches, but i think i will just mention this one, and see if with your help i get this one to work... i just need to make the coordinates "right" after drawing the image in the jpanel so the gravity works well...

    It wasn't clear how you were trying to use AffineTransform other than rotation in a
    gravitational field. To avoid altering the coordinate system orientation try making a
    transform for each rendering of an image by moving the image to the location where you
    want to show it and then rotatng the image about the specific point in/on the image that
    will give the desired final location/orientation. This sounds vague because there are
    multiple ways to see/do this. Here's an example of one way:
    import java.awt.*;
    import java.awt.event.*;
    import java.awt.geom.AffineTransform;
    import java.awt.image.BufferedImage;
    import javax.swing.*;
    public class RotationExample extends JPanel {
        BufferedImage image;
        Point[] points;
        RotationExample() {
            makeImage();
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D)g;
            g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                                RenderingHints.VALUE_INTERPOLATION_BICUBIC);
            if(points == null) initPoints();
            markPointGrid(g2);
            // Center image over points[0] and rotate 45 degrees.
            int cx = image.getWidth()/2;
            int cy = image.getHeight()/2;
            double theta = Math.PI/4;
            double x = points[0].x - cx;
            double y = points[0].y - cy;
            AffineTransform at = AffineTransform.getTranslateInstance(x, y);
            at.rotate(theta, cx, cy);
            g2.drawRenderedImage(image, at);
            // Center image over points[1] and rotate 135 degrees.
            x = points[1].x - cx;
            y = points[1].y - cy;
            theta = Math.PI*3/4;
            at.setToTranslation(x, y);
            at.rotate(theta, cx, cy);
            g2.drawRenderedImage(image, at);
            // Move tail over points[2] and rotate 180 degrees.
            x = points[2].x;
            y = points[2].y - cy;
            theta = Math.PI;
            at.setToTranslation(x, y);
            at.rotate(theta, 0, cy);
            g2.drawRenderedImage(image, at);
            // Mark points.
            g2.setPaint(Color.cyan);
            for(int j = 0; j < points.length; j++)
                g2.fillOval(points[j].x-2, points[j].y-2, 4, 4);
        private void markPointGrid(Graphics2D g2) {
            int w = getWidth(), h = getHeight();
            g2.setPaint(new Color(220, 230, 240));
            for(int j = 0; j < points.length; j++) {
                g2.drawLine(points[j].x, 0, points[j].x, h);
                g2.drawLine(0, points[j].y, w, points[j].y);
        private void makeImage() {
            int w = 75, h = 45, type = BufferedImage.TYPE_INT_RGB;
            image = new BufferedImage(w, h, type);
            Graphics2D g2 = image.createGraphics();
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                                RenderingHints.VALUE_ANTIALIAS_ON);
            g2.setStroke(new BasicStroke(4f));
            g2.setBackground(getBackground());
            g2.clearRect(0,0,w,h);
            g2.setPaint(Color.red);
            g2.drawLine(w, h/2, w-30, 0);
            g2.drawLine(w, h/2, w-30, h);
            g2.setPaint(Color.blue);
            g2.drawLine(0, h/2, w, h/2);
            g2.dispose();
        private void initPoints() {
            int w = getWidth();
            int h = getHeight();
            points = new Point[3];
            for(int j = 0; j < points.length; j++) {
                points[j] = new Point((j+1)*w/4, (j+1)*h/4);
        public static void main(String[] args) {
            JFrame f = new JFrame();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.getContentPane().add(new RotationExample());
            f.setSize(400,400);
            f.setLocation(200,200);
            f.setVisible(true);
    }

  • AffineTransform to rotate a bufferedimage?

    Hi,
    I have a bufferedImage that updates on a thread, but I want to rotate the entire image 90 degrees. I have (in my paint component method)
    Graphics2D g2 = (Graphics2D)g;
    bi_ = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
    g2 = bi_.createGraphics();
    //some drawing...
    AffineTransform atx = new AffineTransform();
    atx.rotate(Math.toRadians(90));
    g2.setTransform(atx);
    g2.dispose();
    g.drawImage(bi_, 0, 0, null);but it doesn't rotate the image. Am I using AffineTransform wrong?
    Thanks
    Edited by: ryanj318 on Jun 23, 2009 5:47 PM

    import java.awt.*;
    import java.awt.geom.AffineTransform;
    import java.awt.image.BufferedImage;
    import javax.swing.*;
    public class SpinImage extends JPanel {
        BufferedImage image;
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D)g;
            if(image == null) image = getImage();
            double cx = image.getWidth()/2.0;
            double cy = image.getHeight()/2.0;
            AffineTransform at =
                AffineTransform.getRotateInstance(Math.PI/2, cx, cy);
            g2.drawRenderedImage(image, at);
        private BufferedImage getImage() {
            int w = getWidth();
            int h = getHeight();
            int type = BufferedImage.TYPE_INT_RGB;
            BufferedImage image = new BufferedImage(w, h, type);
            Graphics2D g2 = image.createGraphics();
            g2.setBackground(Color.pink);
            g2.clearRect(0,0,w,h);
            g2.setFont(g2.getFont().deriveFont(24f));
            g2.setPaint(Color.blue);
            g2.drawString("SpinImage", 100, 130);
            g2.dispose();
            return image;
        public Dimension getPreferredSize() {
            return new Dimension(300, 240);
        public static void main(String[] args) {
            JFrame f = new JFrame();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.add(new SpinImage());
            f.pack();
            f.setLocation(200,200);
            f.setVisible(true);
    }

  • Resizing a rotated BufferedImage

    Hi everybody,
    I am currently developing a graphical figure editor. Users can drop several 'objects' on a JPanel.
    These objects are represented on screen by BufferedImages. The objects are resizable, rotatable
    and movable.
    Rotating is implemented using AffineTransform. This works fine.
    However, imagine one of the objects that has been rotated 90 degrees. Its north face will be facing east in
    the viewport. When a user resizes the object by grabbing the east-side (i.e. the north handle before rotation)
    resize-handle and dragging it to the east it is essentially resizing the object in a northwise direction.
    This means that the height of the object is increased and that its origin (top left point) is decreased. However,
    this will be drawn on screen exactly as stated: the height is increased and the origin is decreased and afterwards
    the image is rotated. All this results in an object with the correct size, but drawn at the wrong location (I draw the
    BufferedImage at the origin-point which was just decreased).
    Might be a long and akward story, so here I will post a small example application which illustrates the behaviour
    of my program. The program shows a BufferedImage. On this image a rectangle is drawn, along with an ellipse that
    indicates the north face of the rectangle. Pressing 'R' results in a rotation of 90 degrees, whereas pressing any
    of the four arrow-keys results in a 5-pixel increase in size. Just pressing R once and then an arrow key will
    illustrate my problem.
    My question is simple: how should I go about resizing (not rescaling, I really want to increase the
    number of paintable pixels for my BufferedImage!) a BufferedImage that's been rotated using AffineTransform.
    Any suggestions are greatly appreciated!
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Point;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import java.awt.image.BufferedImage;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    * Creates a BufferedImage that displays a simple image.
    * This Image will can be rotated 1/2 PI degrees by pressing 'R'.
    * By pressing any of the arrow-keys, the image is resized as if stretching
    * the top of the image. (i.e. in the original, non-rotated, image it
    * simply moves the origin of the image and increases the height).
    public class ImageTest extends JPanel implements KeyListener
       double theta = 0.0; // rotation angle
       Point origin = new Point(50,50); // origin of the image
       Dimension size = new Dimension(100,100); // size of the image
       public static void main(String[] args)
          JFrame mainFrame = new JFrame("Image Tester");
          ImageTest imageTest = new ImageTest();
          mainFrame.getContentPane().add(imageTest);
          mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          mainFrame.setSize(400,400);
          mainFrame.show();
          mainFrame.addKeyListener(imageTest);
       // draw the image on the JPanel
       public void paintComponent(Graphics g)
          super.paintComponent(g);
          // create a BufferedImage and draw something on it (a rectangle)
          BufferedImage image =
             new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_ARGB);
          Graphics g2 = image.createGraphics();
          g2.drawRect(0, 0, size.width - 1, size.height - 1);
          g2.fillOval(size.width / 2, 0, 3, 3); // draw a little 'north' indicator
          g2.dispose();
          // now rotate g
          Graphics2D g2d = (Graphics2D)g;
          g2d.rotate(theta,
                     origin.x + size.width / 2.0,
                     origin.y + size.height / 2.0);
          // and draw the image on the specified origin
          g2d.drawImage(image, origin.x, origin.y, null);
        * @see java.awt.event.KeyListener#keyPressed(java.awt.event.KeyEvent)
       public void keyPressed(KeyEvent arg0)
          switch(arg0.getKeyCode())
             case (KeyEvent.VK_R):
                // rotate! add 1 / 2 PI degrees of rotation
                theta += Math.PI / 2;
                repaint();
                break;
             case (KeyEvent.VK_LEFT):
             case (KeyEvent.VK_RIGHT):
             case (KeyEvent.VK_DOWN):
             case (KeyEvent.VK_UP):
                // make the image 5 pixels larger
                origin.y = origin.y - 5;
                size.height += 5;
                repaint();
                break;
        * @see java.awt.event.KeyListener#keyReleased(java.awt.event.KeyEvent)
       public void keyReleased(KeyEvent arg0)
        * @see java.awt.event.KeyListener#keyTyped(java.awt.event.KeyEvent)
       public void keyTyped(KeyEvent arg0)
    }

    Thanks Olek for your suggestion.
    I took your advice (kind-of) and tried something.
    Now I create a BufferedImage on which I draw a rectangle. The resulting Image is transformed to a rotated version of
    this image. To do so, a new BufferedImage is created based on an AffineTransformOp.
    This resulting (rotated) image is then shown on screen.
    However, it still does not work correctly.
    I have to state that this is a very simplified version of my problem. The original program features 8 resize handles, along with one rotation handle above
    the object. When no rotation has been applied everything works fine (i.e. the object can be resized using the handles). However, if someone uses
    the rotation handle to rotate the object 90 degrees (for example), resizing does no longer work correctly.
    This sample program that I provided intends to mimic the case in which a user is stretching a rectangle to the north (without rotation) and to the
    east (with 90 degrees of rotation). As you can see, if you press the UP-arrow if the object is not rotated, it does exactly what it needs to do:
    stretch to the north (i.e. update the origin and increase the height). If you press R once and then try the UP-arrow again, you see that it still does what it needs to do. However, since I update the origin, the BufferedImage is moving up.
    This all is very logical and the program does exactly what I ask it to do. However, it is not what I want it to do and I do not know how to implement what I really want.
    Maybe someone can sketch some solution to this problem:
    1 - Display a buffered image of size 30 x 30 (with some north-indicator)
    2 - Stretch this image to the north a few pixels
    3 - Rotate the buffered image 90 degrees clockwise around its center (north indicator is pointing east)
    4 - Stretch this image to the east a few pixels (which, I think, corresponds to the operation in 2, but it clearly does not!)
    This might be the little kick I need to set me off in the right direction again. I think I might have been thinking about this too long to see the solution
    myself.
    Listed here is my own updated version of the sample I provided in my first post. Clockwise rotation is still key R, counter clockwise rotation is E,
    stretching the image to the north is UP-arrow and decreasing the image from the north is down (i.e. up and down mimic the case in which a user uses
    the northern resize-handle to resize the image; in case of rotation this northern resize-handle is obviously displayed east or whatever).
    Any help is appreciated as always!
    package test;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Point;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import java.awt.geom.AffineTransform;
    import java.awt.image.AffineTransformOp;
    import java.awt.image.BufferedImage;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    * Creates a BufferedImage that displays a simple image.
    * This Image will can be rotated 1/2 PI degrees by pressing 'R'.
    * By pressing any of the arrow-keys, the image is resized as if stretching
    * the top of the image. (i.e. in the original, non-rotated, image it
    * simply moves the origin of the image and increases the height).
    public class ImageTest extends JPanel implements KeyListener
       double theta = 0.0; // rotation angle
       Point origin = new Point(50,50); // origin of the image drawing
       Dimension size = new Dimension(100,100); // size of the image
       public static void main(String[] args)
          JFrame mainFrame = new JFrame("Image Tester");
          ImageTest imageTest = new ImageTest();
          mainFrame.getContentPane().add(imageTest);
          mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          mainFrame.setSize(400,400);
          mainFrame.show();
          mainFrame.addKeyListener(imageTest);
       public void paintComponent(Graphics g)
          super.paintComponent(g);
          // get the BufferedImage in its rotated version;
          BufferedImage image = getImage();
          // display the image
          g.drawImage(image, origin.x, origin.y, null);
       private BufferedImage getImage()
          BufferedImage result =
             new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_ARGB);
          // draw a nice rectangle
          Graphics g = result.createGraphics();
          g.fillRect(0, 0, size.width, size.height);
          // and a north indicator
          g.setColor(Color.BLACK);
          g.fillOval(size.width / 2 - 3, 0, 6, 6);
          return applyRotation(result);
       private BufferedImage applyRotation(BufferedImage source)
          // create the rotation
          AffineTransform transform =
             AffineTransform.getRotateInstance(
                      theta,
                      source.getWidth() / 2,
                      source.getHeight() / 2);
          // make an Operation to create the new buffered image
          AffineTransformOp transformOp =
             new AffineTransformOp(transform, AffineTransformOp.TYPE_BILINEAR);
          // create dest image
          BufferedImage dest =
             transformOp.createCompatibleDestImage(source, source.getColorModel());
          // apply the filter
          transformOp.filter(source, dest);
          return dest;     
        * @see java.awt.event.KeyListener#keyPressed(java.awt.event.KeyEvent)
       public void keyPressed(KeyEvent arg0)
          int key = arg0.getKeyCode();
          switch(key)
             case KeyEvent.VK_R:
                // rotate clockwise
                theta += Math.PI / 2;
                break;
             case KeyEvent.VK_E:
                // rotate counter-clockwise
                theta -= Math.PI / 2;
                break;
             case KeyEvent.VK_UP:
                // scale up
                origin.y -= 5;
                size.height += 5;
                break;
             case KeyEvent.VK_DOWN:
                // scale down
                origin.y += 5;
                size.height -= 5;
                break;
          repaint();
        * @see java.awt.event.KeyListener#keyReleased(java.awt.event.KeyEvent)
       public void keyReleased(KeyEvent arg0)
        * @see java.awt.event.KeyListener#keyTyped(java.awt.event.KeyEvent)
       public void keyTyped(KeyEvent arg0)
    }

  • How can i rotate a PNG photo and keep the transparent background?

    current i use this method to rotate a photo, but the transparent background is lost.
    what can I do ?
    public CreateRotationPhoto(String photofile,String filetype,int rotation_value,String desfile){
                 File fileIn = new File(photofile);
               if (!fileIn.exists()) {
                   System.out.println(" file not exists!");
                   return;
               try {
                       InputStream input = new FileInputStream(fileIn);
                       JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(input);
                       BufferedImage imageSrc = decoder.decodeAsBufferedImage();
                       int width = imageSrc.getWidth();
                       int height = imageSrc.getHeight();
                       BufferedImage src = ImageIO.read(input);
                       int width = src.getWidth(); //????? 
                            int height = src.getHeight(); //????? 
                       Image img = src.getScaledInstance(width, height,
                               Image.SCALE_FAST);
                       BufferedImage bi;
                       int fill_width=0;
                       int fill_height=0;
                       if (rotation_value==1||rotation_value==3){
                            bi = new BufferedImage(height, width,BufferedImage.TYPE_INT_RGB);
                            fill_width=height;
                            fill_height=width;
                       else{
                            bi = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
                            fill_height=height;
                            fill_width=width;
                            //BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
                       input.close();
                       System.out.println(photofile);
                       File fileOut = new File(desfile);
                       //File fileOut = new File("c:/Host1.PNG");
                       OutputStream output = new FileOutputStream(fileOut);
                       JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(output);
                       JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bi);
                       param.setQuality(0.90f, false);
                       encoder.setJPEGEncodeParam(param);
                       Graphics2D biContext =bi.createGraphics();
                      biContext.setColor(Color.white);
                       biContext.fillRect(0,0,fill_width,fill_height);
                       int frame_width,frame_height;
                     if (rotation_value==1||rotation_value==3){
                            frame_width=height;
                            frame_height=width;
                       }else{
                            frame_width=width;
                            frame_height=height;
                       int x=0,y=0;
                       if (rotation_value==2){
                            x=frame_width;
                            y=frame_height;
                       if (rotation_value==0){
                             x=frame_width;
                             y=frame_height;
                       if (rotation_value==1){
                                x=frame_height;
                                 y=frame_height;
                       if (rotation_value==3){
                                    x=frame_width;
                                 y=frame_width;
                       double rotate=0;
                       if (rotation_value==0){
                             rotate=Math.PI *2;
                       if (rotation_value==1){
                            rotate=Math.PI / 2;
                       if (rotation_value==2){
                            rotate=Math.PI;
                       if (rotation_value==3){
                            rotate=Math.PI*1.5;
                       int x=0,y=0;
                       if (rotation_value==2){
                            x=width;
                            y=height;
                       if (rotation_value==1){
                                x=height;
                                 y=height;
                       if (rotation_value==3){
                                    x=width;
                                 y=width;
                       double rotate=0;
                       if (rotation_value==1){
                            rotate=Math.PI / 2;
                       if (rotation_value==2){
                            rotate=Math.PI;
                       if (rotation_value==3){
                            rotate=Math.PI*1.5;
                       System.out.println(Integer.toString(x)+"|x|"+Integer.toString(y)+"|y|"+Double.toString(rotate));
                       biContext.rotate(rotate, x / 2, y / 2);
                       biContext.drawImage(src, 0, 0, null);
                       biContext.dispose();
                       System.out.println("123123123123");
                       try{
                               ImageIO.write(bi, filetype, output);
                               //ImageIO.write(bi, filetype, "c:/Host.PNG");
                               output.close();
                          }catch (IOException e) {
                              System.err.println(e);
                      // encoder.encode(bi);
                       //output.close();
                } catch (Exception e) {
                         e.printStackTrace();
          }

    Using this BufferedImage.TYPE_INT_RGB for the type will eliminate any transparency in
    your image. Try BufferedImage.TYPE_INT_ARGB.
    Image file: Bird.gif
    import java.awt.*;
    import java.awt.event.*;
    import java.awt.geom.AffineTransform;
    import java.awt.image.BufferedImage;
    import java.io.*;
    import javax.imageio.ImageIO;
    import javax.swing.*;
    import javax.swing.event.*;
    public class Rotate implements ChangeListener
        BufferedImage image;
        JLabel label;
        JSlider slider;
        public Rotate(BufferedImage orig)
            // make transparent background
            Color toErase = new Color(248, 248, 248, 255);
            image = eraseColor(convertImage(orig), toErase);
        public void stateChanged(ChangeEvent e)
            int value = slider.getValue();
            double theta = Math.toRadians(value);
            BufferedImage rotated = getImage(theta);
            label.setIcon(new ImageIcon(rotated));
        private BufferedImage getImage(double theta)
            double cos = Math.cos(theta);
            double sin = Math.sin(theta);
            int w = image.getWidth();
            int h = image.getHeight();
            int width  = (int)(Math.abs(w * cos) + Math.abs(h * sin));
            int height = (int)(Math.abs(w * sin) + Math.abs(h * cos));
            BufferedImage bi = new BufferedImage(width, height, image.getType());
            Graphics2D g2 = bi.createGraphics();
            g2.setPaint(new Color(0,0,0,0));
            g2.fillRect(0,0,width,height);
            AffineTransform at = AffineTransform.getRotateInstance(theta, width/2, height/2);
            double x = (width - w)/2;
            double y = (height - h)/2;
            at.translate(x, y);
            g2.drawRenderedImage(image, at);
            g2.dispose();
            return bi;
        private BufferedImage convertImage(BufferedImage in)
            GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
            GraphicsDevice gd = ge.getDefaultScreenDevice();
            GraphicsConfiguration gc = gd.getDefaultConfiguration();
            BufferedImage out = gc.createCompatibleImage(in.getWidth(), in.getHeight(),
                                                         Transparency.TRANSLUCENT);
            Graphics2D g2 = out.createGraphics();
            g2.drawImage(in, 0, 0, null);
            g2.dispose();
            return out;
        private BufferedImage eraseColor(BufferedImage source, Color color)
            int w = source.getWidth();
            int h = source.getHeight();
            int type = BufferedImage.TYPE_INT_ARGB;
            BufferedImage out = new BufferedImage(w, h, type);
            Graphics2D g2 = out.createGraphics();
            g2.setPaint(new Color(0,0,0,0));
            g2.fillRect(0,0,w,h);
            int target = color.getRGB();
            for(int j = 0; j < w*h; j++)
                int x = j % w;
                int y = j / w;
                if(source.getRGB(x, y) == target)
                    source.setRGB(x, y, 0);
            g2.drawImage(source, 0, 0, null);
            g2.dispose();
            return out;
        private JLabel getLabel()
            label = new JLabel(new ImageIcon(image));
            return label;
        private JSlider getSlider()
            slider = new JSlider(JSlider.HORIZONTAL, 0, 360, 0);
            slider.addChangeListener(this);
            return slider;
        public static void main(String[] args) throws IOException
            String path = "images/Bird.gif";
            ClassLoader cl = Rotate.class.getClassLoader();
            InputStream is = cl.getResourceAsStream(path);
            Rotate rotate = new Rotate(ImageIO.read(is));
            JFrame f = new JFrame();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.getContentPane().setBackground(Color.pink);
            f.getContentPane().add(rotate.getLabel());
            f.getContentPane().add(rotate.getSlider(), "South");
            f.setSize(400,400);
            f.setLocation(200,200);
            f.setVisible(true);
    }

  • Problem rotating a non-square image

    I am getting very strange results trying to use an AffineTransform to rotate a rectangular but non-square image. If I pre-define a destination Image, then after using the AffineTransform to filter the source, most of the destination image is black (because the resultant image isn't positioned correctly). This is especially true when I try to rotate an image 90 degrees counter-clockwise, in which case I don't know what happens to the rotated image.
    If I try to just let the filter method produce a new image to return to me, it returns a completely square image, which cuts off some of the image if it isn't square. I'm really lost as to what to try next. Here is my code...
    at = new AffineTransform();
    at.setToTranslation( roiImage.getWidth()/2, roiImage.getHeight()/2);
    at.rotate( Math.toRadians( angle ) );
    at.translate( -roiImage.getWidth()/2, -roiImage.getHeight()/2);
    AffineTransformOp atOp = new AffineTransformOp( at, renderingHints );
    /* construct the new destination image with the correct post-rotation bounds */
    BufferedImage rotatedImage = new BufferedImage( roiImage.getHeight(), roiImage.getWidth(), roiImage.getType() );
    atOp.filter( roiImage, rotatedImage );
    roiImage.flush();
    roiImage = rotatedImage;
    Any ideas on why this might be acting so strange? Can I even use an AffineTransform to rotate a non-square image?

    could you provide me a code sample? I've tried doing it that way as well, but I'm still having troubles. I think I'm just missing something small and simple :-(
    thanks for the quick response.

  • Problem with very slow scale, rotate and translate

    Hi -
    Here is the basic problem. I want to take a bufferedImage (read from a jpeg earlier on) and then rotate it according to an angle value (radians) and then resize it to fit within a specifically sized box. My code works fine, but... I have to do this in a loop up to 200 times. The process is often taking several minutes to complete. If this is simply a consequence of what I am trying to do, then I'll accept that, but surely I am just doing something wrong? Please help!
    Thanks - here is the (working but very slow) code
        public Graphics2D get_shape_image(Graphics2D g, BufferedImage b, double shaperotation, double space_width, double space_height,
                float x_scale_factor, float y_scale_factor, float shapeTransparency){
            // Work out the boundimg box size of the rotated image
            double imageWidth = (double) b.getWidth();
            double imageHeight = (double) b.getHeight();
            double cos = Math.abs( Math.cos(shaperotation));
            double sin = Math.abs( Math.sin(shaperotation));
            int new_width = (int) Math.floor(imageWidth * cos  +  imageHeight * sin);
            int new_height = (int) Math.floor(imageHeight * cos  +  imageWidth * sin);
            // Create the new bufferedImage of the right size
            BufferedImage transformed = new BufferedImage((int) new_width, (int) new_height, BufferedImage.TYPE_INT_RGB);
            // Create the transform and associated AffineTransformOperation
            AffineTransform at = new AffineTransform();
            AffineTransformOp affine_op;
            // Make sure our image to be rotated is in the middle of the new image
            double x_movement = ((double) (new_width / 2.0d)) - ((double) imageWidth / 2.0d);
            double y_movement = ((double) (new_height / 2.0d)) - ((double) imageHeight / 2.0d);
            at.setToTranslation(x_movement, y_movement);
            affine_op = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
            transformed = affine_op.filter(b, null);
            // Now we need to rotate the image according to the input rotation angle
            BufferedImage rotated = new BufferedImage((int) new_width, (int) new_height, BufferedImage.TYPE_INT_RGB);
            at.setToRotation(shaperotation, (double) new_width / 2.0d, new_height / 2.0d);
            affine_op = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
            rotated = affine_op.filter(transformed, null);
            // Do the scaling so that we fit into the grid sizes
            BufferedImage sizedImage = new BufferedImage((int) (space_width * x_scale_factor), (int) (space_height * y_scale_factor), BufferedImage.TYPE_INT_RGB);
            double xScale = (double) (space_width * x_scale_factor) / (double) new_width;
            double yScale = (double) (space_height * y_scale_factor) / (double) new_height;
            at.setToScale(xScale, yScale);
            affine_op = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
            sizedImage = affine_op.filter(rotated, null);
            // Finally translate the image to the correct position after scaling
            double x_adjust = (space_width / 2.0d) - ((space_width * x_scale_factor) / 2.0d);
            double y_adjust = (space_height / 2.0d) - ((space_height * y_scale_factor) / 2.0d);
            // Set the transparency
            AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, shapeTransparency);
            g.setComposite(ac);
            // Draw the image as long as it's above 0 size
            if (sizedImage.getWidth() > 0 && sizedImage.getHeight() > 0)
                g.drawImage(sizedImage, null, (int) x_adjust, (int) y_adjust);
            return g;
        }

    Your code worked okay in my system: busy at 200fps using 1.0f for alpha and
    the x/y scale_factor values.
    Here's another approach that isn't quite as busy.
    import java.awt.*;
    import java.awt.geom.*;
    import java.awt.image.BufferedImage;
    import java.io.*;
    import javax.imageio.ImageIO;
    import javax.swing.*;
    public class XTest extends JPanel
        BufferedImage image;
        int gridWidth  = 100;
        int gridHeight = 100;
        double theta   = 0;
        double thetaInc;
        public XTest(BufferedImage image)
            this.image = image;
            thetaInc = Math.toRadians(1);
        protected void paintComponent(Graphics g)
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D)g;
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                                RenderingHints.VALUE_ANTIALIAS_ON);
            g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                                RenderingHints.VALUE_INTERPOLATION_BICUBIC);
            int w = getWidth();
            int h = getHeight();
            int imageW = image.getWidth();
            int imageH = image.getHeight();
            // rather than making a new BufferedImage for each step of
            // the rotation and scaling let's try to rotate, scale and
            // fit the source image directly into the grid by using
            // transforms...
            // rotation
            AffineTransform rotateXform = new AffineTransform();
            double x = (w - imageW)/2;
            double y = (h - imageH)/2;
            rotateXform.setToTranslation(x,y);
            rotateXform.rotate(theta, imageW/2.0, imageH/2.0);
            // get rotated size for source
            double cos = Math.abs( Math.cos(theta));
            double sin = Math.abs( Math.sin(theta));
            double rw = Math.rint(imageW * cos  +  imageH * sin);
            double rh = Math.rint(imageH * cos  +  imageW * sin);
            // scale factors to fit image into grid
            double xScale = gridWidth /  rw;
            double yScale = gridHeight / rh;
            // scale from center
            x = (1.0 - xScale)*w/2;
            y = (1.0 - yScale)*h/2;
            AffineTransform scaleXform = AffineTransform.getTranslateInstance(x,y);
            scaleXform.scale(xScale, yScale);
            scaleXform.concatenate(rotateXform);
            g2.drawRenderedImage(image, scaleXform);
            // markers
            // grid
            g2.setPaint(Color.red);
            int gx = (w - gridWidth)/2;
            int gy = (h - gridHeight)/2;
            g2.drawRect(gx, gy, gridWidth, gridHeight);
            // bounds of unscaled, rotated source image
            g2.setPaint(Color.blue);
            double rx = (w - rw)/2;
            double ry = (h - rh)/2;
            g2.draw(new Rectangle2D.Double(rx, ry, rw, rh));
        public void rotate()
            theta += thetaInc;
            repaint();
        public static void main(String[] args) throws IOException
            BufferedImage bi = ImageIO.read(new File("images/bclynx.jpg"));
            XTest test = new XTest(bi);
            Activator activator = new Activator(test);
            JFrame f = new JFrame();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.setContentPane(test);
            f.setSize(400,400);
            f.setLocation(200,200);
            f.setVisible(true);
            activator.start();
    class Activator implements Runnable
        XTest xTest;
        Thread thread;
        boolean animate;
        public Activator(XTest xt)
            xTest = xt;
            animate = false;
        public void run()
            while(animate)
                try
                    Thread.sleep(50);
                catch(InterruptedException ie)
                    animate = false;
                    System.out.println("interrupt");
                xTest.rotate();
        public void start()
            if(!animate)
                animate = true;
                thread = new Thread(this);
                thread.setPriority(Thread.NORM_PRIORITY);
                thread.start();
        public void stop()
            animate = false;
            thread = null;
    }

  • Dealing with AffineTransform mouse driven rotation

    Hi there,
    I'm implementing the mouse control to navigate through an image representing a map. Pan and zoom where trivial operations, but I'm getting in trouble when trying to rotate the BufferedImage.
    I actually can perform the rotation, but because the map coordinate system gets rotated too. I have applied a trigonometric correction when performing a pan after a rotation. This was the hard part... my problem is that I have inverted the axis when panning, so dragging the mouse to the bottom of the canvas becomes a horizontal translation if we had a rotation by PI rads.
    Because original Java code is pretty big, I have coded a simple example that pans, zooms or rotates a square.
    The magic happens here:
    def performPan(self,diff):
            xa = diff.x*lang.Math.cos(self.theta)+diff.y*lang.Math.sin(self.theta)
            ya = -diff.x*lang.Math.sin(self.theta)+diff.y*lang.Math.cos(self.theta)
            diff.x -= (diff.x - xa)
            diff.y -= (diff.y - ya)
            center = self.canvas.squareCenter()
            # if self.theta != 0: self.transform.rotate(-self.theta, center.x, center.y)       
            self.transform.translate(diff.x, diff.y)
            #if self.theta != 0: self.transform.rotate(self.theta, center.x, center.y)
        def performZoom(self,diff):     
              zoomLevel = 1.0+0.01*diff.y;
              if zoomLevel <= 0:
                  zoomLevel = 0
              center = self.canvas.windowCenter()          
              self.transform.scale(zoomLevel, zoomLevel)
        def performRotation(self,diff):
             angleStep = diff.y * 0.1
             self.theta += diff.y
             self.theta %= 2*lang.Math.PI
             center = self.canvas.squareCenter()
             self.transform.rotate(angleStep, center.x, center.y)
        def toWindowCoordinates(self,diff):
            try:
                self.transform.inverseTransform(diff,diff)
            except:
                print "error en window coordinates"I have already tried changing diff.x and diff.x sign, and commenting that trigonometric correction and uncommeting the lines concatenating two rotations surrounding the translation without sucess.
    Please, I'd appreciate some feedback. Brainstorms are welcome. :-)
    Thanks, Vicente.
    The full code:
    from javax import swing
    from java import awt, lang;
    class Listener(swing.event.MouseInputAdapter):
        def __init__(self,subject):
            self.offset = awt.geom.Point2D.Double()
            self.anchor = awt.geom.Point2D.Double()
            self.canvas = subject
            self.transform = subject.transform
            self.rectangle = subject.rectangle
            self.theta = 0.0
        def mousePressed(self,e):
            self.anchor.x = e.getX()
            self.anchor.y = e.getY()
            self.offset.x = e.getX()
            self.offset.y = e.getY()
        def mouseDragged(self,e):
            self.offset.x = e.getX()
            self.offset.y = e.getY()
            diff = awt.geom.Point2D.Double()   
            tx = self.offset.x - self.anchor.x
            ty = self.offset.y - self.anchor.y
            diff.x = tx
            diff.y = ty      
            self.anchor.x = self.offset.x
            self.anchor.y = self.offset.y
            class Painter(lang.Runnable):
                def __init__(self,canvas, listener):
                    self.canvas = canvas
                    self.listener = listener
                def run(self):
                    if e.isControlDown():
                        self.listener.performRotation(diff)
                    elif swing.SwingUtilities.isLeftMouseButton(e):       
                        self.listener.performPan(diff)       
                    if swing.SwingUtilities.isRightMouseButton(e):
                        self.listener.performZoom(diff)
                    self.canvas.repaint()
            work = Painter(self.canvas, self)
            swing.SwingUtilities.invokeLater(work)
        def mouseReleased(self,e):
            self.color = awt.Color.red
            self.canvas.repaint()
        def performPan(self,diff):
            xa = diff.x*lang.Math.cos(self.theta)+diff.y*lang.Math.sin(self.theta)
            ya = -diff.x*lang.Math.sin(self.theta)+diff.y*lang.Math.cos(self.theta)
            diff.x -= (diff.x - xa)
            diff.y -= (diff.y - ya)
            center = self.canvas.squareCenter()
            if self.theta != 0: self.transform.rotate(-self.theta, center.x, center.y)       
            self.transform.translate(diff.x, diff.y)
            if self.theta != 0: self.transform.rotate(self.theta, center.x, center.y)
        def performZoom(self,diff):     
              zoomLevel = 1.0+0.01*diff.y;
              if zoomLevel <= 0:
                  zoomLevel = 0
              center = self.canvas.windowCenter()          
              self.transform.scale(zoomLevel, zoomLevel)
        def performRotation(self,diff):
             angleStep = diff.y * 0.1
             self.theta += diff.y
             self.theta %= 2*lang.Math.PI
             center = self.canvas.squareCenter()
             self.transform.rotate(angleStep, center.x, center.y)
        def toWindowCoordinates(self,diff):
            try:
                self.transform.inverseTransform(diff,diff)
            except:
                print "error en window coordinates"
    class Canvas(swing.JPanel):
        def __init__(self):
            self.rectangle = awt.geom.Rectangle2D.Double(0,0,50,50)
            self.transform = awt.geom.AffineTransform()   
            self.wcenter = awt.geom.Point2D.Double()
            self.rcenter = awt.geom.Point2D.Double()
            listener = Listener(self)
            swing.JPanel.addMouseMotionListener(self,listener)
            swing.JPanel.addMouseListener(self,listener)
        def paintComponent(self,g2d):
            self.super__paintComponent(g2d)
            g2d.setTransform(self.transform)
            g2d.fill(self.rectangle)
        def windowCenter(self):
            if self.wcenter.x == 0 or self.wcenter.y == 0:
                self.wcenter.x = self.getHeight()/2.0
                self.wcenter.y = self.getWidth()/2.0     
            return self.wcenter
        def squareCenter(self):
            if self.rcenter.x == 0 or self.rcenter.y == 0:
                self.rcenter.x = self.rectangle.getBounds2D().height/2.0
                self.rcenter.y = self.rectangle.getBounds2D().width/2.0       
            return self.rcenter
    frame = swing.JFrame(   title="test",
                            visible=1,
                            defaultCloseOperation = swing.JFrame.EXIT_ON_CLOSE,
                           preferredSize = awt.Dimension(400,400),
                            maximumSize = awt.Dimension(800,600),
                            minimumSize = awt.Dimension(200,200),
                            size = awt.Dimension(500,500)
    frame.add(Canvas(), awt.BorderLayout.CENTER)
    frame.pack()

    I forgot to mention that the example is written in
    Jython, because the Java was pretty big, but it is
    legible bu a Java programmer. :-)It's legible, but most of us w/out a jython compiler would have to re-write the code if we wanted to try it out. That may hurt your chances of getting a useful response (as opposed to my useless responses). ... Or it might not.
    Good luck!
    /Pete

  • Load a redrawn image into a JLabel and save it into a BufferedImage?

    Hello, I'm doing a small application to rotate an image, it works, but I'd like to show it into a JLabel that I added, and also store the converted image into a BufferedImage to save it into a database, this is what I have so far:
    public void getImage() {
    try{
    db_connection connect = new db_connection();
    Connection conn = connect.getConnection();
    Statement stmt = conn.createStatement();
    sql = "SELECT image " +
    "FROM image_upload " +
    "WHERE image_id = 1";
    rset = stmt.executeQuery(sql);
    if(rset.next()){
    img1 = rset.getBinaryStream(1);
    buffImage = ImageIO.read(img1);
    rset.close();
    } catch(Exception e){
    System.out.println(e);
    public void paint(Graphics g){
    super.paint(g);
    Graphics2D g2 = (Graphics2D) g;
    ImageIcon imgIcon = new ImageIcon(buffImage);
    AffineTransform tx = AffineTransform.getRotateInstance(rotacion, imgIcon.getIconWidth()/2, imgIcon.getIconHeight()/2);
    g2.drawImage(imgIcon.getImage(), tx, this);
    jLabel1.setIcon(imgIcon);
    private void jButton1MouseClicked(java.awt.event.MouseEvent evt) {
    // TODO add your handling code here:
    setRotacion(getRotacion() + 1.5707963249999999);
    repaint();
    I get the image from a db, then using the paint() method I rotate the image, it works, but the new image is outside of the JLabel and I don't know how to assign the new one into the JLabel (like overwritting the original) and also how to store the new image into a BufferedImage to upload it into the database converted, thanks in advanced, any help would be appreciated, thanks!!
    Edited by: saman0suke on 25-dic-2011 14:07
    Edited by: saman0suke on 25-dic-2011 15:08

    I was able already to fill the JLabel with the modified content, just by creating a new BufferedImage, then create this one into a Graphics2D object and the drawing the image into it, last part, inserting the modified image into the database, so far, so good, thanks!
    EDIT: Ok, basic functionality is ok, I can rotate the image using AffineTransform class, and I can save it to the database and being displayed into a JLabel, now, there's a problem, the image for this example is 200 width and 184 height, but when I rotate it the width can be 184 and the height 200 depending on the position, but the BufferedImage that I create always read from original saved image:
    bimage = new BufferedImage(buffImage.getWidth(), buffImage.getHeight(), BufferedImage.TYPE_INT_ARGB);
    Is there a way that I can tell BufferedImage new width and height after rotate it? :( as far as I understand this cannot be done because before the image bein rotated the bufferedImage is already created and, even being able to do it how can I get width and height from rotated image? thanks!
    Edited by: saman0suke on 25-dic-2011 19:40

  • Creating a Buffered Image to Rotate a JPanel

    I am trying to rotate a JPanel and all of its contents 90 degrees. In searching through the forums for ways to do this, I found this thread:
    http://forum.java.sun.com/thread.jspa?forumID=256&threadID=139832
    a solution in the thread said to create a BufferedImage of the panel, rotate the BufferedImage, and then display it. I understand how to do everything about that but create the BufferedImage. Help would be appreciated. Thanks.

    Using "bufferedimage jpanel" as the keywords I found a few threads.

  • Rotate Image Created with createImage() ?

    I've been looking around online for a way to do this, but so far the only things I have found are 50+ lines of code. Surely there is a simple way to rotate an image created with the createImage() function?
    Here's some example code with all the tedious stuff already written. Can someone show me a simple way to rotate my image?
    import java.net.*;
    import java.awt.*;
    import java.awt.geom.*;
    import java.awt.event.*;
    import javax.swing.*;
    public class RotImg extends JApplet implements MouseListener {
              URL base;
              MediaTracker mt;
              Image myimg;
         public void init() {
              try{ mt = new MediaTracker(this);
                   base = getCodeBase(); }
              catch(Exception ex){}
              myimg = getImage(base, "myimg.gif");
              mt.addImage(myimg, 1);
              try{ mt.waitForAll(); }
              catch(Exception ex){}
              this.addMouseListener(this);
         public void paint(Graphics g){
              super.paint(g);
              Graphics2D g2 = (Graphics2D) g;
              g2.drawImage(myimg, 20, 20, this);
         public void mouseClicked(MouseEvent e){
              //***** SOME CODE HERE *****//
              // Rotate myimg by 5 degrees
              //******** END CODE ********//
              repaint();
         public void mouseEntered(MouseEvent e){}
         public void mouseExited(MouseEvent e){}
         public void mousePressed(MouseEvent e){}
         public void mouseReleased(MouseEvent e){}
    }Thanks very much for your help!
    null

    //  <applet code="RotationApplet" width="400" height="400"></applet>
    //  use: >appletviewer RotationApplet.java
    import java.awt.*;
    import java.awt.event.*;
    import java.awt.geom.AffineTransform;
    import java.awt.image.BufferedImage;
    import javax.swing.*;
    public class RotationApplet extends JApplet {
        RotationAppletPanel rotationPanel;
        public void init() {
            Image image = loadImage();
            rotationPanel = new RotationAppletPanel(image);
            setLayout(new BorderLayout());
            getContentPane().add(rotationPanel);
        private Image loadImage() {
            String path = "images/cougar.jpg";
            Image image = getImage(getCodeBase(), path);
            MediaTracker mt = new MediaTracker(this);
            mt.addImage(image, 0);
            try {
                mt.waitForID(0);
            } catch(InterruptedException e) {
                System.out.println("loading interrupted");
            return image;
    class RotationAppletPanel extends JPanel {
        BufferedImage image;
        double theta = 0;
        final double thetaInc = Math.toRadians(5.0);
        public RotationAppletPanel(Image img) {
            image = convert(img);
            addMouseListener(ml);
        public void rotate() {
            theta += thetaInc;
            repaint();
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D)g;
            g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                                RenderingHints.VALUE_INTERPOLATION_BICUBIC);
            double x = (getWidth() - image.getWidth())/2;
            double y = (getHeight() - image.getHeight())/2;
            AffineTransform at = AffineTransform.getTranslateInstance(x,y);
            at.rotate(theta, image.getWidth()/2, image.getHeight()/2);
            g2.drawRenderedImage(image, at);
        private BufferedImage convert(Image src) {
            int w = src.getWidth(this);
            int h = src.getHeight(this);
            int type = BufferedImage.TYPE_INT_RGB; // options
            BufferedImage dest = new BufferedImage(w,h,type);
            Graphics2D g2 = dest.createGraphics();
            g2.drawImage(src,0,0,this);
            g2.dispose();
            return dest;
        private MouseListener ml = new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                rotate();
    }

  • Java Grahpics2d, Buffered Image, really bad fps when rotating a image10Dpts

    Hey, i'm making a spaceship game, and i use buffered .gif that are loaded before they are used.
    (The images are only loaded once before anyone says that :D )
    However, when i have a reasonably sized image rotating in real time, such as a 533 by 182, at normal scale my fps drops really low, like into the mid teens, and i'm not sure why.
    This only seems to happen when the iamge rotates, the fps stays fine when the image is translating.
    I use Affine Transforms to do my rotating.
    And i'm already using the createCompatibleImage GraphicsConfiguration to help increase performance, but i still get this problem.
    I've also noticed if i zoom in realy close (using scaling ffrom affine transform) the same thing happens if i rotate, and my fps drops really low as well.
    and the problem with the fps dropping when rotating is alot reduced if i zoom out alot as well.
    Anyone got any idea how i can imrpove performance.
    I'm buffering images as so:
         public BufferedImage createCompatible(int width, int height, int transparency) {
              GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration() ;
              BufferedImage compatible = gc.createCompatibleImage(width,height,transparency);
              return compatible;
         }and the following code block is the one i use to render the spaceships (Actors)
         public void paint(Graphics2D g){
                   AffineTransform at = new AffineTransform();
              at.scale(Sector42Main.UNIVSCALE, Sector42Main.UNIVSCALE);
              at.translate(x
                        -(((Actor)Sector42Main.playeractors.get(FOCUS_ID)).x)
                        +((Stage.WIDTH/2)/Sector42Main.UNIVSCALE)
                        - (((Actor)Sector42Main.playeractors.get(FOCUS_ID)).getWidth()/2) ,
                        y
                        -(((Actor)Sector42Main.playeractors.get(FOCUS_ID)).y)
                        + ((Stage.HEIGHT/2)/Sector42Main.UNIVSCALE)
                        - (((Actor)Sector42Main.playeractors.get(FOCUS_ID)).getHeight()/2));
              at.rotate(r,getWidth()/2,getHeight()/2);
         at.scale(xscale, yscale);
              g.drawImage( spriteCache.getSprite(spriteNames[currentFrame]),at, stage);
         }any help would be really welcome.
    thanks.
    Message was edited by:
    MatthewH

    I've found that a lot of game development seems to involve working out exactly what you can get away with in terms of display rather than conforming to a strict model. Sure, this is changing these days, but in terms of a bitmapped sprite just how much difference will each incremement make when projected onto pixels?
    I tend to find a little experimentation with these things goes a long way - you might find that rounding your model's angle to a display angle with a much lower resolution (say, every 2 or 5 or 10 degrees) doesn't acutally make any real difference to the game (apart from letting you render frames moire quickly) once a number of sprites are flying about the place.
    Still, just one suggestion. Let us all know if you find a another way around it.
    Cheers,
    John

  • Add alpha channel to a BufferedImage

    Hi, I am making a small jigsaw puzzle type game. I read an image from a file into a BufferedImage using ImageIO.read(). From this image I cut out rectangular pieces using getSubimage(). Then I would like to mask out the small figure cuts that should be along the edges of each piece. I'm thinking that I would like to do this by alpha transparency - making the background show through the irregular edges. So, my problem is that the images returned by ImageIO.read() does not necesarily have an alpha channel.
    Is there a simple way to add an alpha channel to an existing BufferedImage?
    Or does anyone have a better solution?
    P.S. Currently I intend to use a single circle at each edge, either inside the piece as a hole or filled outside the edge. These circles can easily be drawn, but I plan to eventually expand this to be able to make arbitrarily shaped pieces.

    Is there a simple way to add an alpha channel to an
    existing BufferedImage?Not for the general case. For example, I used ImageIO.read to load in a jpeg image. It's 50x60 pixels, and as an image it has 3 channels: red, green and blue -- no alpha. The pixel data is stored in a DataBufferByte, which has a single array of 9,000 bytes (3 channels x W x H). Given the packed structure of that data, there is no efficient way to slide in alpha values -- there's no room.
    One thing you can always do is copy the data from this BufferedImage into another BufferedImage that has an alpha channel. Here's some quick and dirty code to do it:
    static BufferedImage addAlpha(BufferedImage bi) {
         int w = bi.getWidth();
         int h = bi.getHeight();
         int type = BufferedImage.TYPE_INT_ARGB;
         BufferedImage bia = new BufferedImage(w,h,type);
         Graphics2D g = bia.createGraphics();
         ImageObserver imo = null;
         g.drawImage(bi, 0, 0, imo);
         g.dispose();
         return bia;
    Or does anyone have a better solution?
    P.S. Currently I intend to use a single circle at each
    edge, either inside the piece as a hole or filled
    outside the edge. These circles can easily be drawn,
    but I plan to eventually expand this to be able to
    make arbitrarily shaped pieces.1. The code given above is sufficient to take the original image and create the same image, but with an alpha channel. Don't worry about the fact that you're copying pixel data. Are you generating 100 jigsaw puzzles per second?
    2. Another possible solution is to start with the entire image, perhaps with no alpha channel, and draw individual jigsaw pieces by adjusting the Clip property before drawing each piece. Now, this may be a little slow, because calculating a fancy clipping shape with half-circles etc... may complicate the rendering
    3. My Conclusion. Because a jigsaw application would involve lots of repainting, rotating pieces and dragging them, I'd do the following:
    a. Create buffered images (with alpha) for each piece. I'm not using subimages because I'm trading more space for faster redrawing time. To be rigorous, one should do it both ways and compare the results.
    b. Just once, for each of these piece images, using a clipping shape, draw from the original image (with or without alpha) onto the piece image to generate the image of one piece. If your jigsaw game allows pieces to be rotated 90/180/270 degrees you may want to pre-generate those rotated piece images to speed up drawing the pieces in rotated orientations. Again, one should do it both ways and compare the results.
    --Nax

  • Effecient Rotating of Images

    In my experience, rotating images has always been a pain. I've come across a variety of methods for rotating, but I am not sure which one to use.
    In my last game, I used the following:
    public void rotate(){
    if(alpha){
        myImage = new BufferedImage(width,height,BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = myImage.createGraphics();
        if(!alpha){
        g2d.setColor(Color.black);
        g2d.fillRect(0,0,width,height);
        g2d.rotate(-rotation,width/2,height/2);
        g2d.drawImage(original,0,0,width,height,null);
    }With this method, if alpha was true, the image was rotated and background transparency was preserved, but a new bufferedimage had to be created. If alpha is false, it is much faster but when two units move near/ontop of each other, you can see the squares around them b/c of the lack of transparency.
    The Java Developer's Almanac says to use AffineTransform and AffineTransformOp to do the job. http://www.exampledepot.com/egs/java.awt.image/CreateTxImage.html
    Recently while experimenting, I tried just rotating the original graphics:
    g.rotate(-rotation,x+width/2,y+height/2);
        g.drawImage(i,getX(),getY(),null);
         g.rotate(rotation,x+width/2,y+height/2);So what is the best way (it may not even be one of the ones above). By best I mean fastest, where hundreds of partially transparent units are rotating on the screen at the same time.
    One thing that annoyed me is that I have to use the negative of my rotation amount in order for it to work. I thought that theta is measured in a counter-clock-wise direction??
    Thanks for helping

    [url http://java.sun.com/docs/books/tutorial/2d/advanced/transforming.html]Transforming Shapes, Text and Images.

  • Jagged edges after rotation

    Hi Everyone,
    I am try to rotate an image and put it on a background image. Image is being rotated successfuly but jagging appears if i use an small angle to rotate. I am also setting the Antialiasing using Rendering hints...
    Please respond.
    Thanks,
    Masood
    Following is the Code:
    RenderingHints renderHints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_DEFAULT);
    renderHints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    int value = 5;
    int angle = (float)(value * (Math.PI/180.0F));
    out = new BufferedImage(bsrc1.getWidth(), bsrc1.getHeight(), BufferedImage.TYPE_INT_RGB);
    Graphics2D g2 = out.createGraphics();
    g2.setRenderingHints(renderHints);
    //draw bg image
    g2.drawRenderedImage(bsrc1, null);
    at = AffineTransform.getTranslateInstance(width1+86-34,height1-30);
    at.rotate(angle,612/2,486/2);
    g2.drawRenderedImage(bsrc2,at);     
    g2.dispose();

    It's not an antialiasing process, it's interpolation. Try setting the interpolation key to bilinear or bicubinc - though the results still won't be ideal.
    If that's not good enough then what you could do to get a fully smooth edge, if you're prepared to lose a pixel or two round the edge, is this:
    - rotate the image
    - create a quarilateral Shape which forms a rectangle around the new four corners
    - turn on antialiasing
    - using a stroke the same colour as your background, with a width of say 2 pixels, render the shape
    This should give you a smooth edge but, as I say, you will lose a pixel or so round each edge, which may or may not be acceptable.

Maybe you are looking for

  • Error while adding Delivery

    Hi Experts, I have saved few deliveries as draft and when I try to add it I get an error "There is a difference between the Document total and it components".Can u pls help in solving this error. Thanks in advance....

  • Activating Direct Posting to G/L Accounts and Material Accounts

    Hi, Can anyone plz tell me with some examples ,what is the relevance of this ,'Activating Direct Posting to G/L Accounts and Material Accounts'. Link for this is as below : spro/Materials Management/ Logistics Invoice Verification / Incoming Invoices

  • Cannot connect to YouTube or safari

    My son iTouch for some reason refused to connect to YouTube and safari . Error was "cannot connect tou you tube" and on safari just spins but never connect. Odd the apppear tobe copnnect to my wireless Hub ok. Follow most of the solution but none wor

  • Ejb access

    Hi, I'm currently trying to get to know Java EE and thus playing around a little. But off course this means some trouble can happen along the road... I created an EJB called TitleCheckerBean with a local interface TitleCheckerLocal which I can use wi

  • Crearting Stacked Bar Chart

    Dear All I have a requirement of making a stacked chart using Visual Composer 7.0. There will be two stacks against each month and each stack consists of different data series. Actual production and plan data are two different stacks and differnet pr