views:

56

answers:

1

Hello Guys,

I am trying to rotate a tile in a BufferedImage(the bufferedimage is made up of tiles) but i got stuck and don't seem to find the answer. I have googled for hours but can't find any tutorials. So i decided to come here for help.

I want to rotate the crossing(tile) at the bottom right of the buffered image. I want to rotate it 90 degrees whiles the other tiles stay unaffected.

I am doing a robot visualization so whenever the robot reaches the rail crossing, the crossing will turn 90 degrees and it will move to the other rail. I have added the button "rotate" in order to be able to test the rotation alone. When the button is clicked, i want the crossing to be rotated 90 degrees.

Here is the code. You can copy it and run it.

Don't forget to copy the images into your image folder of your development environment(Eclipse, etc...). The images are 130 X 130.

The names of the images as they are in the "VisPanel" class below are: Save the images as "railHorizontal.JPG", "railVertical2.JPG" and "railCrossing2.JPG".

Here are the images.

alt text

alt text

alt text

The code:

 public class TilesImage extends JFrame{

        private static final long serialVersionUID = 1L;

        public TilesImage(){
              this.setSize(700,700); 
              this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              VisPanel vis = new VisPanel();
              JPanel pana = new JPanel();
              pana.setLayout(new FlowLayout());
              vis.setPreferredSize(new Dimension(500, 500));
              pana.add(vis);
              BufferedImage sub = vis.getImg().getSubimage(261, 260, 129, 129);
              JButton but = new JButton(new RotateCrossingAction(sub, vis));
              but.setPreferredSize(new Dimension(170, 40));
              pana.add(but);
              this.setContentPane(pana);
              this.setVisible(true);
          }


          public static void main( String[] args ) { 
                new TilesImage(); 
            } 

    }

    class RotateCrossingAction extends AbstractAction{
        private static final long serialVersionUID = 1L;

        private final Component component;
        private final BufferedImage image;
        private final BufferedImageOp op;

        public RotateCrossingAction(BufferedImage image, Component component) {
            super("Rotate");
            this.component = component;
            this.image = image;
            double x = 0.5 * image.getWidth();
            double y = 0.5 * image.getHeight();
            AffineTransform xfrm = new AffineTransform();
             xfrm = AffineTransform.getQuadrantRotateInstance(2, x, y);
            op = new AffineTransformOp(xfrm, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
        }

        public void actionPerformed(ActionEvent e) {
            BufferedImage tmpImage = op.filter(image, null);
            image.setData(tmpImage.getRaster());
            component.repaint();
        }

    }



public class VisPanel extends JPanel{
     private static final int IMAGE_TYPE = BufferedImage.TYPE_INT_ARGB; 
      private BufferedImage img;
      AffineTransform affineTransform = new AffineTransform();

     public VisPanel() { 

            // here you should create a compatible BufferedImage
            //img = new BufferedImage( 450, 350, IMAGE_TYPE );  
            img = new BufferedImage( 500, 500, IMAGE_TYPE ); 
            this.setSize(img.getWidth(), img.getHeight());     

            final int NB_TILES = 4; 
            BufferedImage[] tiles = new BufferedImage[NB_TILES]; 
            tiles[0] = createHorizontalRail( new Color( 255, 255, 255 ) ); 
            tiles[1] = createVerticalRail( new Color( 255, 255, 255 ) ); 
            tiles[2] = createCrossing( new Color( 255,   0, 255 ) ); 


            final int[][] map = new int[][] { 

                      {4, 4, 1},     
                      {4, 4, 1},
                      {0, 0, 2},
                      {4, 4, 4},  
            }; 

            for (int i = 0; i < map[0].length; i++) { 
                 BufferedImage tile = null;
                for (int j = 0; j < map.length; j++) { 
                    if(map[j][i] == 0){
                          tile = tiles[0]; 
                          for (int x = 0; x < tile.getWidth(); x++) { 
                            for (int y = 0; y < tile.getHeight(); y++) { 
                                img.setRGB( x + i * 130, y + j * 130, tile.getRGB(x,y) );
                                //img.setRGB( x + i * 45, y + j * 32, tile.getRGB(x,y) ); 
                            } 
                        } 
                    } if(map[j][i] == 1){
                          tile = tiles[1]; 
                          for (int x = 0; x < tile.getWidth(); x++) { 
                            for (int y = 0; y < tile.getHeight(); y++) { 
                                img.setRGB( x + i * 130, y + j * 130, tile.getRGB(x,y) ); 
                            } 
                        } 
                     }

                    if(map[j][i] == 2){
                          tile = tiles[2]; 
                          for (int x = 0; x < tile.getWidth(); x++) { 
                            for (int y = 0; y < tile.getHeight(); y++) { 
                                img.setRGB( x + i * 130, y + j * 130, tile.getRGB(x,y) ); 
                            } 
                        } 
                     }


                } 
            } 

            this.setVisible( true ); 
        }

     private BufferedImage createHorizontalRail( final Color c ) { 
            final Random r = new Random(); 
            BufferedImage img = null;
            try {
                img = ImageIO.read(new File("images/railHorizontal.JPG"));
            } catch (IOException e) {
            }
            return img; 
        }

        private BufferedImage createVerticalRail( final Color c ) { 
            final Random r = new Random(); 
            BufferedImage img = null;
            try {
                img = ImageIO.read(new File("images/railVertical2.JPG"));
            } catch (IOException e) {
            }
            return img; 
        }

        private BufferedImage createCrossing( final Color c ) { 
            final Random r = new Random(); 
            BufferedImage img = null;
            try {
                img = ImageIO.read(new File("images/railCrossing2.JPG"));
            } catch (IOException e) {
            }


            return img; 
        }


        public void paintComponent(Graphics g) { 
             Graphics2D g2d = (Graphics2D)g;
             g2d.drawImage(img, 0, 0, null); 

          }


        public BufferedImage getImg() {
            return img;
        }
        public void setImg(BufferedImage img) {
            this.img = img;
        } 

        public AffineTransform getAffineTransform() {
            return affineTransform;
        }
        public void setAffineTransform(AffineTransform affineTransform) {
            this.affineTransform = affineTransform;
        }
}

Thanks for your help.

A: 

In VisPanel, instead of having one large BufferedImage, create an array of BufferedImages that corresponds to your int[][] map array.

BufferedImage[][] img;

You can more easily rotate the individual images.

You construct the one large image in the getImg method.

Gilbert Le Blanc