如何将BufferedImage转换为byte []?

时间:2015-03-19 23:48:31

标签: java mysql byte bytearray bufferedimage

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();
    }

以上是我选择图片并将图片显示到JLabel的代码。我的问题是,我不知道如何将其转换为byte[],因此我可以将其保存到我的数据库中。顺便说一句,我使用MySQL作为我的数据库。如果你们知道怎么做,请告诉我。

4 个答案:

答案 0 :(得分:1)

使用ImageIO.write通过ByteArrayOutputStream编写图像,例如

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());

然后,您可以使用生成的byte[]数组或ByteArrayInputStream并将其传递给setBlob

PreparedStatement方法

答案 1 :(得分:1)

您可以使用ByteArrayOutputStreamImageIO将图像写入字节数组,如下所示:

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)
}

答案 2 :(得分:1)

您可以使用此方法 -

/**
 * @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();
}

像 -

一样使用它
//file from filechooser
BufferedImage originalImage = ImageIO.read(file);
byte image[] = getByteData(originalImage);

请注意,如果图像类型是int的类型,例如然后是BufferedImage.TYPE_INT_RGB 你会得到施放异常。以下方法可用于转换为合适的类型 -

/**
 * 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;
}

答案 3 :(得分:0)

虽然@ MadProgrammer和@immibis的答案在技术上都是正确的并且回答了你的问题,但你真的不想通过解码它来复制图像文件,并重新编码它。这是因为它较慢,但更重要的是,对于某些图像格式(最明显是JPEG),会丢失质量,并且与图像关联的任何元数据都将丢失(最后一部分当然可以是故意的,但有更好的方法可以做到这一点而不会破坏图像质量)。

所以,相反,就像@immibis似乎在他的评论中提示一样,只需打开一个FileInputStream并直接从文件中读取字节,然后进入数据库。您也应该能够在数据库中打开OutputStream blob,这样就可以通过不将整个文件内容读入字节数组来节省一些内存(如果文件很大,这是一件好事),在写作之前。

类似的东西:

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可以实现为:

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();
}