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

  • Thread starter Thread starter Yoyo_Guru
  • Start date Start date
  • Tags Tags
    Images Java
AI Thread Summary
The discussion revolves around a Java program that allows users to select image icons in one JPanel and place them in another JPanel, with the goal of saving the final arrangement as a .gif image. The user has successfully saved the icon positions as an array of integers but struggles to save the visual representation of these icons as a .gif file. Suggestions from participants include accessing the screen buffer of the UI object to convert it into a suitable format for GIF conversion. Another recommendation is to utilize the JScrollPane's print method to capture the entire content, even if it is not fully visible on the screen, and save it as an image file. Additionally, there are mentions of creating a new 2D array to combine the images based on the index array and using a library for image conversion. Overall, the focus is on finding efficient methods to capture and save the visual output of the JPanel as a .gif without incurring performance issues from repainting.
Yoyo_Guru
Messages
32
Reaction score
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
Do you want to create the tiled image in code, or can you use a stand-alone program?
 
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.
 
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.
 
Its a JScrollPane though. Can't get all of it on screen at once.
 
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.
 
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:

Similar threads

Back
Top