[Java] How do I save a bunch of images as one?

  • Java
  • Thread starter Yoyo_Guru
  • Start date
  • Tags
    Images Java
In summary: Location.x + 10) / 20, (mouseLocation.y - 20) * 20,... (mouseLocation.y + 20)); } else { // if it's not focused or contains the mouse location, draw the tiles. }}In summary, the programmer wants to save the icons in a JPanel as a .gif file. They have tried googling the issue but haven't been able to find a clear answer. They have created a class that extends JPanel and implements MouseListener and MouseMotionListener. They also created an array of BufferedImages to store the icons and a Selection to save the icons. They have a method called paintComponent that updates the tiles. If the icon
  • #1
Yoyo_Guru
33
0
I have a program where the user selects image icons in one JPanel and can place them in another JPanel. The program saves the position of the icons as an array of integers where each integer represents the different icons. I need to also save the final result as a .gif image because otherwise it will repaint the icons everytime paint method is called and creates a lot of lag. Basically I want to take the image icons in the JPanel and save them as one .gif file. I've tried googling it but have not been able to determine how. Does anyone have any advice or could show me how to do it? I've gotten it to save the text file but not the image of all the icons together. Here is the code:
Here is the JPanel and JFrame where the tiles can be placed

Code:
public class Map extends JFrame
{
  final int AREA_SIZE_X = 100;
  final int AREA_SIZE_Y = 100;
  JFrame sWindow;
  mapPanel mPanel;
 JScrollPane scrollPane;
  Map() throws IOException
  {
    sWindow = new Selection(this);
    sWindow.setDefaultCloseOperation(EXIT_ON_CLOSE);
    sWindow.setSize(270,700);
    sWindow.setVisible(true);
    mPanel = new mapPanel(sWindow);
    this.getContentPane().setLayout(new BorderLayout());
    scrollPane = new JScrollPane(mPanel);
    this.getContentPane().add(scrollPane, BorderLayout.WEST);
    mPanel.requestFocus();      // Give the panel focus.
    this.setTitle("Map maker");
    this.setLocation(400, 0);
    this.setResizable(false);
    
    this.pack();
  }
}
class mapPanel extends JPanel implements MouseListener, MouseMotionListener
{
  //int[][][] back1;
 // int[][][] back2;
  boolean topLayer=false;
  final int AREA_SIZE_X = 100;
  final int AREA_SIZE_Y = 100;
  Point mouseLocation;
  Point myMouse;
  int[][][] tiles = new int[AREA_SIZE_X][AREA_SIZE_Y][4];
  ArrayList<BufferedImage> bFS;
  //ArrayList<ImageIcon> icons=new <ImageIcon>ArrayList();
  BufferedImage tempImage;
  Selection sWindow;

  public mapPanel(JFrame selWindow)
  {
    this.addMouseMotionListener(this);
    sWindow = (Selection) selWindow;
    bFS = sWindow.getBuffered();
    for (int i = 0; i < AREA_SIZE_X; i++)
    {
      for (int j = 0; j < AREA_SIZE_Y; j++)
      {
        for (int k = 0; k < 4; k++)
        {
          tiles[i][j][k] = -1;
        }
      }
    }
  //  back1= tiles.clone();
   // back2=tiles.clone();
    this.setBackground(Color.white);
    this.setPreferredSize(new Dimension(10*AREA_SIZE_X, 10*AREA_SIZE_Y));
    this.addMouseListener(this);
   // this.addKeyListener(this);  // This class has its own key listeners.
    this.setFocusable(true);    // Allow panel to get focus
    sWindow.updateTiles(tiles);
  }
  public void fillBackground()
  {
     for (int i = 0; i < AREA_SIZE_X; i++)
    {
      for (int j = 0; j < AREA_SIZE_Y; j++)
      {
        tiles[i][j][0]= sWindow.getSelected();
        for (int k = 1; k < 4; k++)
        {
          tiles[i][j][k] = -1;
        }
      }
    }
  }
  public void paintComponent(Graphics g)
  {

    super.paintComponent(g);
    g.setColor(Color.white);
    g.fillRect(0, 0, AREA_SIZE_X * 20, AREA_SIZE_Y * 20);
    mouseLocation = this.getMousePosition();

    for (int i = 0; i < AREA_SIZE_X; i++)
    {
      for (int j = 0; j < AREA_SIZE_Y; j++)
      {
        for (int k = 0; k < 4; k++)
        {
          if (tiles[i][j][k] != -1)
          {
            g.drawImage(bFS.get(tiles[i][j][k]), i * 20, j * 20, this);
          }
        }
      }
    }
//System.out.println(this.hasFocus());
    if (this.hasFocus()&&this.contains(mouseLocation))
    {
      g.drawImage(bFS.get(sWindow.getSelected()), mouseLocation.x - 20, mouseLocation.y - 20, this);
      // g.drawImage(bFS.get(sWindow.getSelected()), mouseLocation.x - 20, mouseLocation.y - 20, this);
      g.setColor(Color.red);
      g.drawRect(((mouseLocation.x - 10) / 20) * 20, ((mouseLocation.y - 10) / 20) * 20, 20, 20);
    }
  }

  @Override
  public void mouseClicked(MouseEvent e)
  {
    // updateHistogram(tiles);
    topLayer=sWindow.isLayered();
    // System.out.println(this.hasFocus());
    myMouse = this.getMousePosition();
    // System.out.println((myMouse.x - 10) / 20+"  "+(myMouse.y) / 20);
   if(topLayer)
   {
    for(int k=0;k<4;k++)
    {
      if(tiles[(myMouse.x - 10) / 20][(myMouse.y - 10) / 20][k]==-1)
      {
        tiles[(myMouse.x - 10) / 20][(myMouse.y - 10) / 20][k] = sWindow.getSelected();
        break;
      }
    }
    //System.out.println(tiles[(myMouse.x - 10) / 20][(myMouse.y - 10) / 20][0]);
   // System.out.println(tiles[(myMouse.x - 10) / 20][(myMouse.y - 10) / 20][1]);
   }
   else
   {
     tiles[(myMouse.x - 10) / 20][(myMouse.y - 10) / 20][0] = sWindow.getSelected();
     tiles[(myMouse.x - 10) / 20][(myMouse.y - 10) / 20][1] = -1;
     tiles[(myMouse.x - 10) / 20][(myMouse.y - 10) / 20][2] = -1;
     tiles[(myMouse.x - 10) / 20][(myMouse.y - 10) / 20][3] = -1;
   }
    //tiles[1][1] = sWindow.getSelected();
    //System.out.println(sWindow.getSelected());
    this.repaint();
  }

  @Override
  public void mousePressed(MouseEvent e)
  {
  }

  @Override
  public void mouseReleased(MouseEvent e)
  {
  }

  @Override
  public void mouseEntered(MouseEvent e)
  {
    this.requestFocus();
  }

  @Override
  public void mouseExited(MouseEvent e)
  {
    //sWindow.requestFocusInWindow()
    sWindow.updateTiles(tiles);
    sWindow.requestFocus();
  }

  @Override
  public void mouseDragged(MouseEvent e)
  {
  //  updateHistogram(tiles);
    myMouse = this.getMousePosition();
    topLayer=sWindow.isLayered();
    
    if(topLayer)
   {
    for(int k=0;k<4;k++)
    {
      if(tiles[(myMouse.x - 10) / 20][(myMouse.y - 10) / 20][k]==-1)
      {
        tiles[(myMouse.x - 10) / 20][(myMouse.y - 10) / 20][k] = sWindow.getSelected();
        break;
      }
    }
   }
   else
   {
     tiles[(myMouse.x - 10) / 20][(myMouse.y - 10) / 20][0] = sWindow.getSelected();
     tiles[(myMouse.x - 10) / 20][(myMouse.y - 10) / 20][1] = -1;
     tiles[(myMouse.x - 10) / 20][(myMouse.y - 10) / 20][2] = -1;
     tiles[(myMouse.x - 10) / 20][(myMouse.y - 10) / 20][3] = -1;
   }
    this.repaint();
  }

  @Override
  public void mouseMoved(MouseEvent e)
  {
    // System.out.println("moved");
    this.repaint();
  }

Here is the code for the selector
Code:
public class Selection extends JFrame
{

  selectionPanel panel;
  JScrollPane scrollPane;

  public Selection(Map mapFrame) throws IOException
  {
    panel = new selectionPanel(this, mapFrame);
    //  panel.setLayout(new BorderLayout());
    this.getContentPane().setLayout(new BorderLayout());
    //   JLabel instructions = new JLabel("<html><ul><li>Type text.</li>"
    //           + "<li>Use arrow keys to move text.</li>"
    //           + "<li>Press shift arrows to move faster.</li></html>");
    //   this.getContentPane().add(instructions, BorderLayout.NORTH);
    this.setResizable(false);
    scrollPane = new JScrollPane(panel);
    //setViewport(panel);
    scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
    this.getContentPane().add(scrollPane, BorderLayout.WEST);
    panel.requestFocus();      // Give the panel focus.
    this.setTitle("Texture Selecter");
    this.pack();
  }

  public int getSelected()
  {
    //System.out.println(panel.selected);
    return panel.selected;
  }

  public ArrayList<BufferedImage> getBuffered()
  {
    return panel.bFS;
  }

  public boolean isLayered()
  {
    return panel.layerB.isSelected();
  }

  public void updateTiles(int[][][] updatedTiles)
  {
    panel.updatePanelTiles(updatedTiles);
  }
}

class selectionPanel extends JPanel implements MouseListener
{

  Map map;
  boolean layered = false;
  ArrayList<ImageIcon> icons = new ArrayList<ImageIcon>();
  protected ArrayList<JButton> buttons = new ArrayList<JButton>();
  ArrayList<BufferedImage> bFS = new ArrayList<BufferedImage>();
  int selected = 1;
  File file;
  BufferedImage tempImage;
  JRadioButton layerB;
  JButton bSave;
  JButton bBackground;
  JButton bOpen;
  int tiles[][][];
  Selection select;

  selectionPanel(Selection sel, Map mapFrame) throws IOException
  {
    map = mapFrame;
    select = sel;
    this.setBackground(Color.white);
    this.addMouseListener(this);
    this.setFocusable(true);    // Allow panel to get focus

    layerB = new JRadioButton("Layer");
    this.add(layerB);
    layerB.addMouseListener(this);
    bSave = new JButton("SAVE");
    bSave.addMouseListener(this);
    this.add(bSave);
    bOpen = new JButton("OPEN");
    bOpen.addMouseListener(this);
    this.add(bOpen);
    bBackground=new JButton("BACKGROUND");
    bBackground.addMouseListener(this);
    this.add(bBackground);
    

    icons.add(createImageIcon("textures/0.gif"));
    JButton tempButton = new JButton("DELETE", icons.get(0));
    buttons.add(tempButton);
    buttons.get(0).addMouseListener(this);

    buttons.get(0).setVerticalTextPosition(AbstractButton.BOTTOM);
    buttons.get(0).setHorizontalTextPosition(AbstractButton.CENTER);
    file = new File("textures/0.gif");
    tempImage = ImageIO.read(file);
    bFS.add(tempImage);
    this.add(buttons.get(0));

    int counter = 1;

    while (!(createImageIcon("textures/" + (counter) + ".gif") == null))
    {
      icons.add(createImageIcon("textures/" + (counter) + ".gif"));

      tempButton = new JButton("" + counter, icons.get(counter));
      buttons.add(tempButton);
      buttons.get(counter).addMouseListener(this);

      buttons.get(counter).setVerticalTextPosition(AbstractButton.BOTTOM);
      buttons.get(counter).setHorizontalTextPosition(AbstractButton.CENTER);
      //file=new File(RouteBuilderv2.class.getResource("textures/" + (counter) + ".gif").getFile());
      file = new File("textures/" + (counter) + ".gif");
    // System.out.println("textures/" + (counter) + ".gif");
    //System.out.println(file.canRead());
    //  System.out.println(file.getAbsoluteFile());
      tempImage = ImageIO.read(file);
      bFS.add(tempImage);
      this.add(buttons.get(counter));
      counter++;
      //adds each icon to array without hardcoding number of icons in
    }
    this.setPreferredSize(new Dimension(250, 15 * buttons.size()));
  }

  protected static ImageIcon createImageIcon(String path) throws MalformedURLException
  {
    //java.net.URL imgURL = RouteBuilderv2.class.getResource(path);
    //java.net.URL imgURL=new URL(path);
    File someFile=new File(path);
    if (someFile.exists())
    {
     //System.out.println(path);
      return new ImageIcon(path);
    }
    else
    {
      return null;
    }
  }

  public void updatePanelTiles(int[][][] updatedTiles)
  {
    tiles = updatedTiles;
  }

  @Override
  public void mouseClicked(MouseEvent e)
  {

    for (int i = 0; i < buttons.size(); i++)
    {
      if (buttons.get(i).equals(e.getComponent()))
      {
        selected = i;
        //System.out.println(selected);
      }
    }
    if(e.getComponent().equals(bBackground))
    {
      map.mPanel.fillBackground();
    }
    if (e.getComponent().equals(bSave))
    {
      Saver saver = new Saver(tiles);
      saver.setVisible(true);
      saver.requestFocus();
    }
    if (e.getComponent().equals(bOpen))
    {
      Opener opener = new Opener(select);
      opener.setVisible(true);
      opener.requestFocus();

    }
  }

  public void updateFileTiles(int[][][] fileTiles)
  {
    tiles = fileTiles;
    map.mPanel.tiles = tiles;
    map.mPanel.repaint();
  }

  @Override
  public void mousePressed(MouseEvent e)
  {
  }

  @Override
  public void mouseReleased(MouseEvent e)
  {
  }

  @Override
  public void mouseEntered(MouseEvent e)
  {
  }

  @Override
  public void mouseExited(MouseEvent e)
  {
  }
}

and here is the code where it is saved
Code:
public class Saver extends JFrame
{

  SaverPanel filePanel;

  public Saver(int[][][] tiles)
  {
    filePanel = new SaverPanel(tiles,this);
    this.getContentPane().setLayout(new BorderLayout());
    //   JLabel instructions = new JLabel("<html><ul><li>Type text.</li>"
    //           + "<li>Use arrow keys to move text.</li>"
    //           + "<li>Press shift arrows to move faster.</li></html>");
    //   this.getContentPane().add(instructions, BorderLayout.NORTH);
    this.getContentPane().add(filePanel, BorderLayout.WEST);
    filePanel.requestFocus();      // Give the panel focus.
    this.setTitle("Save");
    this.setAlwaysOnTop(rootPaneCheckingEnabled);
    this.pack();
  }
}

class SaverPanel extends JPanel implements MouseListener, ActionListener
{
  final int AREA_SIZE_X = 100;
  final int AREA_SIZE_Y = 100;
  final JTextField x = new JTextField(20);
  final JTextField y = new JTextField(20);
  JButton done;
  int[][][] saveTiles;
  Saver closeReference;
  public SaverPanel(int[][][] tiles,Saver closeR)
  {
    closeReference=closeR;
    done=new JButton("SAVE");
   done.addMouseListener(this);
   JLabel xLabel=new JLabel();
   xLabel.setText("x: ");
   xLabel.setBounds(0, 50, 50, 30);
   this.add(xLabel);
    saveTiles = tiles;
    x.setBounds(50, 50, 50, 20);
    x.addActionListener(this);
    this.add(x);

   JLabel yLabel=new JLabel();
   yLabel.setText("y: ");
   yLabel.setBounds(0, 100, 50, 30);
   this.add(yLabel);
    y.setBounds(50, 100, 50, 20);
    y.addActionListener(this);
    this.add(y);
    this.add(done);

    this.addMouseListener(this);
    this.setBackground(Color.white);
    this.setPreferredSize(new Dimension(250, 250));
    this.setFocusable(true);    // Allow panel to get focus 
  }

  public void save(int[][][] tiles) throws IOException
  {
    String fName = x.getText() + " x " + y.getText();
   // Writer writer = null;
    File fileNew = new File(fName);
    //make variable for name to be saved
    FileWriter fWriter=new FileWriter(fileNew);
    BufferedWriter writer = new BufferedWriter(fWriter);
    for (int i = 0; i < AREA_SIZE_X; i++)
    {
      for (int j = 0; j < AREA_SIZE_Y; j++)
      {
        String toBeSaved=""+tiles[i][j][0];
        writer.write(toBeSaved + ' ');
        for (int k = 1; k < 4; k++)
        {
            toBeSaved=""+tiles[i][j][k];
            writer.write(toBeSaved + ' ');
        }
        writer.flush();
        //fWriter.flush();
    //    System.out.println(i+"   "+j);
      }
    }
    writer.close();
    //fWriter.close();
//    writer.close();
  }

  @Override
  public void mouseClicked(MouseEvent e)
  {
    if (e.getComponent().equals(done))
    {
      if (x.getText() != null && y.getText() != null)
      {
        try
        {
          this.save(saveTiles);
          closeReference.dispose();
        }
        catch (IOException ex)
        {
          Logger.getLogger(SaverPanel.class.getName()).log(Level.SEVERE, null, ex);
        }
      }
      else
      {
        //display message to fill ouy x and y
      }

    }
  }

  @Override
  public void mousePressed(MouseEvent e)
  {
  }

  @Override
  public void mouseReleased(MouseEvent e)
  {
  }

  @Override
  public void mouseEntered(MouseEvent e)
  {
  }

  @Override
  public void mouseExited(MouseEvent e)
  {
  }

  @Override
  public void actionPerformed(ActionEvent e)
  {
   // throw new UnsupportedOperationException("Not supported yet.");
  }
}
 
Technology news on Phys.org
  • #2
Do you want to create the tiled image in code, or can you use a stand-alone program?
 
  • #3
I'd prefer to do it in the program. Make it all in one. And how would i do it with another program? all the program saves is a bunch of numbers that correspond to images. no actual images.
 
  • #4
If you go the route of a standalone program, you basically make a system call and run the screenshot program of your choice that you should be to pass the coordinates of the shot as (command line) arguments as well as the name of the output file...or take a shot of the entire monitor and then open the image from within your Java program and crop the image to the coordinates of interest...you should know where your program's canvas is in screen coordinates.
 
  • #5
Its a JScrollPane though. Can't get all of it on screen at once.
 
  • #6
Doesn't JScrollPane have a 'print' method? maybe you can print the entire content even though it does not show up entirely in the screen...but print to a file, instead of to the printer or some trick like that.
 
  • #7
Hey Yoyo_Guru and welcome to the forums.

I haven't used Java in roughly 10 years but I would recommend that you find if you can access to the screen buffer for your UI object. It might be in Graphics structures or something like that.

Once you get access to the screen-buffer, convert this to the format you need for GIF/JPEG/Whatever conversion and then pass it to a library (or your own code) to convert the whole thing.

Also if you have the images and the index array, just create a new 2D array and use a routine to get the output uncompressed memory representation of the image and tile them together. Then take this raw form and pass this to your image library.

The last method is going to definitely be implemented and will take a lot less time as well.
 
Last edited:

FAQ: [Java] How do I save a bunch of images as one?

How do I save multiple images as one using Java?

Saving multiple images as one in Java can be achieved by creating a new BufferedImage object with the desired dimensions, then using a Graphics object to draw each individual image onto the new BufferedImage. Finally, you can use ImageIO.write() to save the new BufferedImage as a single image file.

Can I use a loop to save multiple images as one in Java?

Yes, you can use a loop to save multiple images as one in Java. As mentioned before, you can use a Graphics object to draw each image onto a new BufferedImage. By using a loop, you can easily iterate through a list of images and draw them onto the new BufferedImage one by one.

Is there a limit to the number of images I can save as one in Java?

There is no specific limit to the number of images you can save as one in Java. However, it is important to consider the memory and processing power of your system. If you try to save a very large number of images, it may cause performance issues or even crash your program.

Can I save images of different sizes as one in Java?

Yes, you can save images of different sizes as one in Java. When creating the new BufferedImage, you can specify the desired dimensions, which can be different from the original image sizes. However, it is important to consider the aspect ratio of the images to avoid distortion or cropping.

How can I ensure the quality of the saved image when merging multiple images in Java?

To ensure the quality of the saved image, it is important to use a high-quality rendering hints object when creating the Graphics object. You can also consider using image compression techniques, such as JPEG or PNG, to reduce the file size without compromising the image quality.

Similar threads

Replies
1
Views
2K
Replies
5
Views
2K
Replies
4
Views
4K
Replies
2
Views
2K
Replies
19
Views
2K
Replies
1
Views
2K
Back
Top