0
public void actionPerformed(java.awt.event.ActionEvent evt) { 

    Connection cn = null;
    Object source = evt.getSource();

    JFileChooser filechooser= new JFileChooser();
    filechooser.setDialogTitle("Choose Your File");
    filechooser.setFileSelectionMode(JFileChooser.FILES_ONLY);

    int returnval=filechooser.showOpenDialog(this);
    if(returnval==JFileChooser.APPROVE_OPTION)
    {
        File file = filechooser.getSelectedFile();
        BufferedImage bi;
        try
        {
            bi=ImageIO.read(file);
            lbl_movieCover.setIcon(new ImageIcon(bi));
        }
        catch(IOException e)
        {
        }
        //this.pack();
    }

Above is my code for choosing the image and displaying the image to JLabel. My problem is that, I don't know how to convert it to byte[] so I could save it to my database. By the way, I'm using MySQL for my database. If you guys know how to do it, please let me know.

UrsinusTheStrong
  • 1,239
  • 1
  • 16
  • 33
Bee Azombrado
  • 13
  • 1
  • 4
  • 1
    Write it through `ImageIO.write` using a `ByteArrayOutputStream`, for [example](http://stackoverflow.com/questions/20961065/converting-image-in-memory-to-a-blob/20961506#20961506) – MadProgrammer Mar 19 '15 at 23:49
  • Side note: with `catch(IOException e) {}` how will you know if something goes wrong? – user253751 Mar 19 '15 at 23:51
  • 1
    Also, is there a reason you don't want to just copy the bytes from the file to the database? – user253751 Mar 19 '15 at 23:56

4 Answers4

2

Use ImageIO.write to write the image through a ByteArrayOutputStream, for example

ByteArrayOutputStream baos = null;
try {
    baos = new ByteArrayOutputStream();
    ImageIO.write(bi, "png", baos);
} finally {
    try {
        baos.close();
    } catch (Exception e) {
    }
}
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());

You can then use the resulting byte[] array or ByteArrayInputStream and pass this to the setBlob method of a PreparedStatement

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
2

You could use a ByteArrayOutputStream and ImageIO to write an image to a byte array, like this:

static byte[] imageToByteArray(BufferedImage image) {
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    try {
        ImageIO.write(image, "png", stream);
    } catch(IOException e) {
        // This *shouldn't* happen with a ByteArrayOutputStream, but if it
        // somehow does happen, then we don't want to just ignore it
        throw new RuntimeException(e);
    }
    return stream.toByteArray();
    // ByteArrayOutputStreams don't need to be closed (the documentation says so)
}
user253751
  • 57,427
  • 7
  • 48
  • 90
2

You can use this method-

/**
 * @param userSpaceImage
 * @return byte array of supplied image
 */
public byte[] getByteData(BufferedImage userSpaceImage) {
    WritableRaster raster = userSpaceImage.getRaster();
    DataBufferByte buffer = (DataBufferByte) raster.getDataBuffer();
    return buffer.getData();
}

Use it like-

//file from filechooser
BufferedImage originalImage = ImageIO.read(file);
byte image[] = getByteData(originalImage);

Note that if image type is that of int e.g. BufferedImage.TYPE_INT_RGB then you will get cast exception. Following method can be used to convert to suitable type-

/**
 * this method convert supplied image to suitable type
 * it is needed because we need bytes of array so TYPE_INT images must be
 * converted to BYTE_BGR or so
 * @param originalImage loaded from file-chooser
 * @return 
 */

public BufferedImage convertImage(BufferedImage originalImage) {
    int newImageType = originalImage.getType();

    /**
     * Converting int to byte since byte array is needed later to modify 
     * the image
     */
    if (newImageType == BufferedImage.TYPE_INT_RGB
            || newImageType == BufferedImage.TYPE_INT_BGR) {
        newImageType = BufferedImage.TYPE_3BYTE_BGR;
    } else if (newImageType == BufferedImage.TYPE_INT_ARGB) {
        newImageType = BufferedImage.TYPE_4BYTE_ABGR;
    } else if (newImageType == BufferedImage.TYPE_INT_ARGB_PRE) {
        newImageType = BufferedImage.TYPE_4BYTE_ABGR_PRE;
    }
    BufferedImage newImage = new BufferedImage(originalImage.getWidth(), 
            originalImage.getHeight(), newImageType);
    Graphics g = newImage.getGraphics();
    g.drawImage(originalImage, 0, 0, null);
    g.dispose();
    return newImage;
}
Varun Kumar
  • 2,543
  • 1
  • 23
  • 22
0

While both @MadProgrammer's and @immibis' answers are technically correct and answers your question, you don't really want to copy an image file by decoding it, and re-encoding it. This is because it's slower, but more importantly, you will lose quality for certain image formats (most notably JPEG) and any metadata associated with the image will be lost (this last part could of course be intentional, but there are better ways to do this without ruining the image quality).

So, instead, do as @immibis seems to hint at in his comment, just open a FileInputStream and read the bytes directly from the file, and into the database. You should be able to open an OutputStream to the blob in your database as well, so you can save some memory (a good thing, if your files are large) by not reading the entire file contents into a byte array, before writing.

Something like:

File file = filechooser.getSelectedFile();

// ... show image in label as before (but please, handle the IOException)

InputStream input = new FileInputStream(file);
try {
   Blob blob = ...; // Get from JDBC connection
   OutputStream output = blob.setBinaryStream(0);

   try {
      FileUtils.copy(input, output);
   }
   finally {
       output.close();
   }
}
finally {
    input.close();
}

FileUtils.copy can be implemented as:

public void copy(final InputStream in, final OutputStream out) {
    byte[] buffer = new byte[1024]; 
    int count;

    while ((count = in.read(buffer)) != -1) {
        out.write(buffer, 0, count);
    }

    // Flush out stream, to write any remaining buffered data
    out.flush();
}
Harald K
  • 26,314
  • 7
  • 65
  • 111