5

I'm working on a database application in which I'm inserting images into a database. I'm storing the InputStreams in the database as a BLOB, and I am having issues retrieving them and setting them to an ImageIcon.

try{
    // Return a resultset That contains 
    // the photos from the hashtags the user is following.

    preparedStatement = conn.prepareStatement("SELECT * FROM PHOTOS WHERE CARID=?");
    preparedStatement.setInt(1, 1);
    resultSet = preparedStatement.executeQuery();
    while(resultSet.next()){
        newPhoto = new Photo(resultSet.getInt(1), resultSet.getInt(2), 
                             resultSet.getLong(3), resultSet.getBinaryStream(4));
        System.out.println(resultSet.getBinaryStream(4));
        photos.add(newPhoto);
        System.out.println("Retrieving a photo");
    }
}

photos is an ArrayList using my Photo class, which I am returning. Every time I try to display the images, I am getting the following error...

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at business.appdev.Home.paintEditFrame(Home.java:577)

which is coming from the following code..

editImageLabel[i].setIcon(
        new ImageIcon(img.getScaledInstance(imageSize, imageSize, imageSize)));

I have some basic println commands that are showing me what's returning from the MySQL database, which is

java.io.ByteArrayInputStream@2c0213a5
Retrieving a photo
java.io.ByteArrayInputStream@252ab7be
Retrieving a photo

where img is a BufferedImage. Any help would be greatly appreciated, Thanks!

Code for handling of the InputStream returned from the resultSet

for(int i = 0; i < photos.size(); i++){         
img = ImageIO.read(photos.get(i).getInputStream());
editImageLabel[i] = new JLabel("");
editImageLabel[i].setIcon(new ImageIcon(img.getScaledInstance(imageSize, imageSize, imageSize)));

updated Photo class with byte[] data Based on some other posts I've read, I'm storing the byte[] into a varbinary in MySQL. After that, I grab the photo data from my database using

InputStream in = resultSet.getBinaryStream(4);
byte[] photoData = new byte[(int) resultSet.getLong(3)];
ByteArrayOutputStream os = new ByteArrayOutputStream();
for (int len; (len = in.read(photoData)) != -1;)
    os.write(photoData, 0, len);
    os.flush();

I then create my photo object and return an ArrayList of photos. This has eliminated the NullPointerException, but I now cannot get the ImageIcon JLabels to show up. I use the following code to add them to a JPanel,

InputStream in = new ByteArrayInputStream(photos.get(i).getData());
BufferedImage newImage = ImageIO.read(in);
editImageLabel[i] = new JLabel("");
editImageLabel[i].setIcon(new ImageIcon(newImage.getScaledInstance(imageSize, imageSize, Image.SCALE_DEFAULT)));

and then I place the Label onto the JPanel.

  • can you check if `resultSet.getBinaryStream(index)` is retrieving you any data? – Alex S. Diaz Aug 10 '15 at 23:25
  • 1
    Could you share the stream-handling code in your `Photo` class? – Mick Mnemonic Aug 10 '15 at 23:26
  • @AlexandroSifuentesDíaz the last code section is what's returning from the resultSet.getBinaryStream(index). I had it in the println command just for testing purposes. – Chris Davis Aug 11 '15 at 00:23
  • @MickMnemonic public void setInputStream(InputStream inputStream) { this.inputStream = inputStream; } public InputStream getInputStream() { return inputStream; } Sorry for the horrible formatting, still getting the hang of this. – Chris Davis Aug 11 '15 at 00:24
  • Those methods don't really handle the stream -- they are just a getter and a setter. Where do you read the stream? Please include the code in the question (click the edit link). – Mick Mnemonic Aug 11 '15 at 00:31
  • @MickMnemonic code has been added. When uploading a file, the images will display, the NullPointer is coming just when I retrieve them from a database and try to display them. – Chris Davis Aug 11 '15 at 00:49
  • I'm quite sure that the streams you're storing within `Photo` can not be used that way afterwards, because they will get closed when the prepared statement closes. Could you refactor the code so that you would read the stream into a `byte[]` within `while(resultSet.next()) {...` and only store the byte array in the `Photo` class? – Mick Mnemonic Aug 11 '15 at 07:52
  • Often you see questions asked about storing files as blobs in various databases. That's not the optimal way to do it whatever your programming language is and whatever your database is. The optimal way is to save the file on the file system or on cloud storage and just put in the filename/link into your database. – e4c5 Aug 13 '15 at 08:57
  • @e4c5 I've considered that, but I've had trouble finding helpful articles on how to connect to my directory hosted through godaddy and upload and image file straight to there from a java application. Any suggestions? – Chris Davis Aug 13 '15 at 12:57

1 Answers1

0

Avoid the trouble of encoding and decoding images by storing the image in the filesystem and just the path to the image in your database. This can help to keep your database size down which, in turn, can help your transactional efficiency. You can write up some quick code to make a numeric filename for the file on your server.

fiddlestacks
  • 109
  • 1
  • 10