4

I haven't really explored this part of Java. Can I create a class, say Student which has all his/her details like name, id and all but in addition to that, can I store their photo as well, as a data member?

Basically, whenever I create a Student object, I pass in a picture as one of it's arguments?

So, the question is, what is the most standard and the best (in your opinion) way to handle such image objects?

I'm comfortable with Java Swing classes, so if it can be done using that, it will be awesome.

4 Answers4

2

For ease of use I recommend a BufferedImage.

There are two options, one provided by HRgiger where you never store the image, instead load it each time, the other is to store it directly in the Student instance.

Instead of storing it as a byte[] picture; as you might need some functionality in the future for the image. Which BufferedImage has, or you can easily add to it.

As you mentioned you were comfortable with Swing it is fairly easy to handle. Note, I would not let the student render the image itself. Just provide a getter for the image and render it from the relevant method.

A short example.

Student.java

public class Student {
    private String name;
    private BufferedImage image;

    public Student (String name) {
        this.name = name;
        this.image = ImageIO.read(new File(name + ".png"));
    }

    public getName () {
        return name;
    }

    public getImage () {
        return image;
    }
}

Some paint method somewhere where it makes sense to paint the Student.image

private final List<Student> students = new ArrayList<>();

...

@override
public void paintComponent(Graphics g) {
    super.paintComponent(g);

    for (Student s : students) {
        g.drawImage (s.getImage(), x, y, null);
    }
}

That paintComponent needs to have access in some way to the List<Student>. You can also of course just paint one student.

Emz
  • 1,280
  • 1
  • 14
  • 29
  • Can you please explain this with an example, because I like the idea very much and worked with BufferedImages once. – Brendon McCullum Dec 03 '15 at 17:26
  • @BrendonMcCullum, wrote a quick now one, do not hesitate to ask for further help with it. You can use [drawImage](https://docs.oracle.com/javase/tutorial/2d/images/drawimage.html) as reference for understanding custom `paintComponent` as well as how to draw images in Swing. – Emz Dec 03 '15 at 17:35
1

If you only want to store the image, without doing any operation on it, the best option is to use an array of byte.

E.g.

byte[] picture;

Here's how to convert a file into a byte[]: http://www.mkyong.com/java/how-to-convert-file-into-an-array-of-bytes/

And here's the opposite conversion: http://www.mkyong.com/java/how-to-convert-array-of-bytes-into-file/

Andres
  • 10,561
  • 4
  • 45
  • 63
1

Use filePath as String in your Student object. which will be one of the cheapest memory consumer for you. And when you need call an utility method something like that:

public static BufferedImage getStudentImage(Student student) throws IOException{
 return ImageIO.read(new File(student.getImagePath()));
}
HRgiger
  • 2,750
  • 26
  • 37
  • If you don't have to access the image that often I truly recommend this one. Here you can easily build out for filters and everything as was briefly mentioned in my answer, yet you do not need to store the `BufferedImage` directly in the `Student` class. However, if you are reading the image often I'd recommend my solution. – Emz Dec 03 '15 at 17:24
0

You could have an Image or byte[] or something representing the picture of the student, but that's a large data member that you probably don't need every time you reference the student. Better would probably be to have an id reference to the picture as stored in the database or filesystem, then load the image as needed only when you wish to display it.

digitaljoel
  • 26,265
  • 15
  • 89
  • 115
  • 1
    Why would it be a problem if the image exists every time you are referencing the student? It is not like you are actually sending around the student in the program. You are only sending around a pointer to the student object. – Emz Dec 03 '15 at 17:12
  • Assume you have an array of 100k students. Now you have generated a bunch of garbage for the garbage collector that you likely only need 5% of the time. – digitaljoel Dec 03 '15 at 17:20
  • I see. I like this proposal. Since I have a lot of images, storing them in the database will be the way to go. Can you please elaborate or link me to the process that explains it? – Brendon McCullum Dec 03 '15 at 17:21
  • Here's one example using hibernate: http://www.mkyong.com/hibernate/hibernate-save-image-into-database/ but it's pretty old. Other considerations for image storage for a webapp here: http://stackoverflow.com/questions/5293085/in-java-web-application-where-should-i-store-users-photos – digitaljoel Dec 03 '15 at 17:23
  • 100k students are quite a few, you will start to have some substantial problems working with an `array` now. Finding student `foo` will be rough. That aside, the gc will have absolutely nothing to do if they are all referenced in the array. That being said, it does take memory. A `BufferedImage` is not very cheap on memory. – Emz Dec 03 '15 at 17:27
  • hypothetical: I have to send email to each student that is late paying their tuition. I query the database, get a collection of 100k students back (big university!) I iterate through pages of students loading the info so I can get the email address. Now I'm loading the image too, which is useless in this case. Better to just load the image id. I queue the email and continue on my iteration. If I've loaded a bunch of byte[] or buffered images now eden space is filling up with useless images when I run this job keeping the gc busy. Easier to dispose of an id and process needs less total memory. – digitaljoel Dec 03 '15 at 17:34
  • You do not have to store the image in the database however. It all comes down to memory vs. speed in the end. – Emz Dec 03 '15 at 17:39
  • Yes. My point was that storing the actual byte content of the image within the student object may not be the best choice. Some sort of reference identifier (db id, file system path, s3 bucket and path, etc.) and a service to load the image when needed would be better. Whether the bytes are stored in the database, filesystem, s3, etc. is irrelevant as long as it is not required to be part of the student object always. – digitaljoel Dec 03 '15 at 20:24