How do you load 52 images into one image

e.g a deck of cards into one image file

Page 1 of 1

8 Replies - 1604 Views - Last Post: 09 November 2009 - 10:49 AM Rate Topic: -----

#1 zanyrogue  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 91
  • Joined: 16-January 09

How do you load 52 images into one image

Post icon  Posted 07 November 2009 - 11:43 AM

Hi

How would you go about putting 52 card images into one file? and then when you call it in a loop the cards are shuffled at random and appear random when your image loads?

I have completed my card game but want to put in images of all the cards into my program so that when the random shuffle takes place the cards are displayed re-shuffled at the end.

I can already display one image but what I don't want to do is 52 JLabels!


Any suggestions? :)

Is This A Good Question/Topic? 0
  • +

Replies To: How do you load 52 images into one image

#2 Fuzzyness  Icon User is offline

  • Comp Sci Student
  • member icon

Reputation: 669
  • View blog
  • Posts: 2,438
  • Joined: 06-March 09

Re: How do you load 52 images into one image

Posted 07 November 2009 - 11:52 AM

Create an array of images and have one jLabel, when you need to display a card just set that jLabel to one of the images in the element, then when need to set back to the "back" just do so.
Image back = new Image ...
JLabel dispCard = new JLabel(back);
//have a method that gets a random card.
dispCard = images[getNewCard()]; // have it return an index
//when they are done with that card set it back to unknown card, or the back of a card
dispCard = back;


Something like that.

Hope this helps!
Was This Post Helpful? 0
  • +
  • -

#3 zanyrogue  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 91
  • Joined: 16-January 09

Re: How do you load 52 images into one image

Posted 07 November 2009 - 12:17 PM

View PostFuzzyness, on 7 Nov, 2009 - 10:52 AM, said:

Create an array of images and have one jLabel, when you need to display a card just set that jLabel to one of the images in the element, then when need to set back to the "back" just do so.
Image back = new Image ...
JLabel dispCard = new JLabel(back);
//have a method that gets a random card.
dispCard = images[getNewCard()]; // have it return an index
//when they are done with that card set it back to unknown card, or the back of a card
dispCard = back;


Something like that.

Hope this helps!


Thanks it does help but how do I get all 52 cards into one file image so that it has one name? Also could I display all 52 so that they never turn back to the back of the card they just re-shuffle face up?
Was This Post Helpful? 0
  • +
  • -

#4 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8329
  • View blog
  • Posts: 31,857
  • Joined: 06-March 08

Re: How do you load 52 images into one image

Posted 07 November 2009 - 01:56 PM

View Postzanyrogue, on 7 Nov, 2009 - 11:17 AM, said:

Thanks it does help but how do I get all 52 cards into one file image so that it has one name? Also could I display all 52 so that they never turn back to the back of the card they just re-shuffle face up?

It is surely not a good approach
When you will have your big image with all the 52 cards into it how will you suffle the cards ?
Every image with the card turn on/off would be another image that will require someting like 52! * 52! different images. I hope yur computer has a lot of memory
You can have 1 image for the back of your card and 52 images fro the front. I would use JLabel but if you do not want to use them just draw the 52 images where you need them drawing the front or your single back.
Was This Post Helpful? 0
  • +
  • -

#5 Fuzzyness  Icon User is offline

  • Comp Sci Student
  • member icon

Reputation: 669
  • View blog
  • Posts: 2,438
  • Joined: 06-March 09

Re: How do you load 52 images into one image

Posted 07 November 2009 - 02:07 PM

Well if you dont want it to turn back to the card then dont and you can just create a txt file with the file path to each image and read it in and add the image to an arraylist or whatever you use. Put them in the array and then have the "back" image as a default hard coded into the code and not through an file. and if you do not wish for the back to show then just set the JLabel to images[0] to get the first card. and to after done shuffling, just have it set to the images[0] like before. Basically it only shows the "back" if it is a new game pretty much.
Was This Post Helpful? 0
  • +
  • -

#6 baavgai  Icon User is online

  • Dreaming Coder
  • member icon

Reputation: 5805
  • View blog
  • Posts: 12,644
  • Joined: 16-October 07

Re: How do you load 52 images into one image

Posted 08 November 2009 - 05:05 PM

View Postzanyrogue, on 7 Nov, 2009 - 12:43 PM, said:

How would you go about putting 52 card images into one file?


This is a very good question. Answers, not so good. :P

The practice of having one big image for numerous like sized smaller images is extremely common. You see it in card games, board games, all kinds of animations with "sprite" like objects. If offers an advantage of size, organization, IO, various kinds resource management. For simple designing, seeing all the elements at once is also very helpful.

Strangely enough, chopping images up in Java isn't as trivial as it should be. Image manipulation in Java is often asynchronous and this can result in your program being ready for the result before the result is read for you. This makes sense for downloading, but it extends to file operations and even transformations.

The magic code for chopping up an image looks like this:
ImageFilter filter = new CropImageFilter(x, y, width, height);
ImageProducer producer = new FilteredImageSource(component.imgFull.getSource(), filter);
Image resultImage = createImage(producer);



However, this sometimes doesn't work as expected without a "MediaTracker".

A quick search gave me this site ( http://www.jfitz.com/cards/ ) with your choice of card collections.

I wrote a complete example of how to grab one of these images and use cards in your program. It's probably larger than needed for an example, but I'll doubtless use this code again for card game fun. For demo purposes, this points at a URL for the image. For playing with, copy that image local.

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
import java.util.*;
import java.io.*;
import java.net.URL;

class SlicedImage {
	protected int rows, cols;
	protected Dimension sliceSize;
	protected Image imgSlice[][];
	protected String errMsg = null;

	private class DummyComponent extends Component {
		public Image imgFull;
		public MediaTracker mediaTracker;
		
		public DummyComponent(Image imgFull) throws InterruptedException {
			this.mediaTracker = new MediaTracker(this);
			mediaTracker.addImage(imgFull, 1);
			mediaTracker.waitForID(1);
			this.imgFull = imgFull;
		}
	}
	
	public SlicedImage(String url, int rows, int cols, boolean isUrl) {
		try {
			DummyComponent dc = null;
			if (isUrl) {
				dc = new DummyComponent(Toolkit.getDefaultToolkit().getImage(new URL(url)));
			} else {
				dc = new DummyComponent(Toolkit.getDefaultToolkit().getImage(url));
			}
			init(dc, rows, cols);
		} catch (Exception e)  {
			errMsg = e.getMessage();
			e.printStackTrace();
		}
	}
	
	protected void init(DummyComponent component, int rows, int cols) throws InterruptedException {
		this.cols = cols;
		this.rows = rows;
		this.imgSlice = new Image[rows][cols];
		
		Dimension imageSize = new Dimension(component.imgFull.getWidth(null), component.imgFull.getHeight(null) );
		sliceSize = new Dimension((imageSize.width/cols), (imageSize.height/rows));
		for (int row=0; row<rows; row++) {
			int y = row*sliceSize.height;
			for (int col=0; col<cols; col++) {
				int x = col*sliceSize.width;
				ImageFilter filter = new CropImageFilter(x, y, sliceSize.width, sliceSize.height);
				ImageProducer producer = new FilteredImageSource(component.imgFull.getSource(), filter);
				Image resultImage = component.createImage(producer);
				component.mediaTracker.addImage(resultImage, 2);
				imgSlice[row][col] = resultImage;
			}
		}
		component.mediaTracker.waitForID(2);
	}

	public String getErrorMessage() { return errMsg; }
	public boolean isValid() { return errMsg==null; }
	public int getRows() { return rows; }
	public int getCols() { return cols; }
	public Dimension getSliceSize() { return sliceSize; }
	public Image getImgSlice(int row, int col) { return imgSlice[row][col]; }
}

class CardImages extends SlicedImage {
	public CardImages() {
		//super("classic-playing-cards.png", Card.SuitSize, Card.FaceSize, false);
		super("http://www.jfitz.com/cards/classic-playing-cards.png", Card.SuitSize, Card.FaceSize, true);
	}
	
	public Icon getCardIcon(Card card) {
		if (!isValid()) { return null; }
		return new ImageIcon(getImgSlice(card.getSuitNum(), card.getFaceNum()));
	}
	
}


// a basic card class
class Card {
	public static final int FaceSize = 13;
	public static final int SuitSize = 4;
	protected final int value;
	
	public Card(int value) { this.value = value; }
	public int getValue() { return this.value; }
	
	public int getSuitNum() { return this.value / FaceSize; }
	public int getFaceNum() { return this.value % FaceSize; }
}


class CardButton extends JButton {
	private static CardImages images = new CardImages();
	private Card card = null;
	
	public CardButton() {
		super();
		if (images.isValid()) { setSize(images.getSliceSize()); }
		setCard(0);
	}
	
	public void setCard(Card card) { 
		this.card = card;
		this.setIcon(images.getCardIcon(card));
	}

 	public void setCard(int cardNum) { setCard(new Card(cardNum)); }
	
	public Card getCard() { return this.card; }
	
}


class CardPanel extends JPanel {
	public static final int CardCount = 5;
	private CardButton[] cards;
	private java.util.Random rnd = new java.util.Random();
	
	public CardPanel() {
		setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
		cards = new CardButton[CardCount];
		
		for(int i=0; i<CardCount; i++) {
			cards[i] = new CardButton();
			add(cards[i]);
		}
		RandDisplay();
	}
	
	public void RandDisplay() {
		for(int i=0; i<CardCount; i++) {
			cards[i].setCard(rnd.nextInt(52));
		}
	}
	
}


public class CardImageTest extends JFrame {
	CardPanel cardPanel;
	
	public CardImageTest() {
		cardPanel = new CardPanel();
		setLayout( new BorderLayout() );
		add(cardPanel, BorderLayout.CENTER);
		
		JButton b = new JButton("Random Cards"); 
		b.addActionListener(new ActionListener() { 
			public void actionPerformed(ActionEvent e) { 
				cardPanel.RandDisplay();
			} 
		}); 
		add(b, BorderLayout.SOUTH);
		setSize(550,250);
		
		setDefaultCloseOperation(EXIT_ON_CLOSE);          
	}

	public static void main(String[] args) {
		CardImageTest frame = new CardImageTest();
		frame.setVisible(true);
	}
	
}


Was This Post Helpful? 0
  • +
  • -

#7 g00se  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2700
  • View blog
  • Posts: 11,368
  • Joined: 20-September 08

Re: How do you load 52 images into one image

Posted 08 November 2009 - 05:44 PM

You'll find it a lot easier to load your images with javax.imageio.ImageIO.read. No asynchronous problems - one call to load an Image
Was This Post Helpful? 0
  • +
  • -

#8 baavgai  Icon User is online

  • Dreaming Coder
  • member icon

Reputation: 5805
  • View blog
  • Posts: 12,644
  • Joined: 16-October 07

Re: How do you load 52 images into one image

Posted 08 November 2009 - 08:04 PM

View Postg00se, on 8 Nov, 2009 - 06:44 PM, said:

You'll find it a lot easier to load your images with javax.imageio.ImageIO.read.


Excellent! Thank you.

Updated the following class to use same.
class SlicedImage {
	protected int rows, cols;
	protected Dimension sliceSize;
	protected Image imgSlice[][];
	protected String errMsg = null;
	
	public SlicedImage(String url, int rows, int cols, boolean isUrl) {
		this.cols = cols;
		this.rows = rows;
		this.imgSlice = new Image[rows][cols];
		
		try {
			BufferedImage imgFull = null;
			if (isUrl) {
				imgFull = ImageIO.read(new URL(url));
			} else {
				imgFull = ImageIO.read(new File(url));
			}
			sliceSize = new Dimension((imgFull.getWidth(null)/cols), (imgFull.getHeight(null)/rows));
			for (int row=0; row<rows; row++) {
				int y = row*sliceSize.height;
				for (int col=0; col<cols; col++) {
					imgSlice[row][col] = imgFull.getSubimage(col*sliceSize.width, y, sliceSize.width, sliceSize.height);
				}
			}
			
		} catch (Exception e)  {
			errMsg = e.getMessage();
			e.printStackTrace();
		}
	}
	
	public String getErrorMessage() { return errMsg; }
	public boolean isValid() { return errMsg==null; }
	public int getRows() { return rows; }
	public int getCols() { return cols; }
	public Dimension getSliceSize() { return sliceSize; }
	public Image getImgSlice(int row, int col) { return imgSlice[row][col]; }
}


Was This Post Helpful? 1
  • +
  • -

#9 zanyrogue  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 91
  • Joined: 16-January 09

Re: How do you load 52 images into one image

Posted 09 November 2009 - 10:49 AM

View Postbaavgai, on 8 Nov, 2009 - 07:04 PM, said:

View Postg00se, on 8 Nov, 2009 - 06:44 PM, said:

You'll find it a lot easier to load your images with javax.imageio.ImageIO.read.


Excellent! Thank you.

Updated the following class to use same.
class SlicedImage {
	protected int rows, cols;
	protected Dimension sliceSize;
	protected Image imgSlice[][];
	protected String errMsg = null;
	
	public SlicedImage(String url, int rows, int cols, boolean isUrl) {
		this.cols = cols;
		this.rows = rows;
		this.imgSlice = new Image[rows][cols];
		
		try {
			BufferedImage imgFull = null;
			if (isUrl) {
				imgFull = ImageIO.read(new URL(url));
			} else {
				imgFull = ImageIO.read(new File(url));
			}
			sliceSize = new Dimension((imgFull.getWidth(null)/cols), (imgFull.getHeight(null)/rows));
			for (int row=0; row<rows; row++) {
				int y = row*sliceSize.height;
				for (int col=0; col<cols; col++) {
					imgSlice[row][col] = imgFull.getSubimage(col*sliceSize.width, y, sliceSize.width, sliceSize.height);
				}
			}
			
		} catch (Exception e)  {
			errMsg = e.getMessage();
			e.printStackTrace();
		}
	}
	
	public String getErrorMessage() { return errMsg; }
	public boolean isValid() { return errMsg==null; }
	public int getRows() { return rows; }
	public int getCols() { return cols; }
	public Dimension getSliceSize() { return sliceSize; }
	public Image getImgSlice(int row, int col) { return imgSlice[row][col]; }
}



Thank you very much this has been a great help! Some parts of your code I don't understand but at least now I can look them up and find out what they do. :D
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1