【问题标题】:How can I convert BufferedImage to byte[]?如何将 BufferedImage 转换为 byte[]?
【发布时间】:2015-05-23 07:13:45
【问题描述】:
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。如果你们知道怎么做,请告诉我。

【问题讨论】:

  • 使用ByteArrayOutputStream 将其写入ImageIO.write,用于example
  • 旁注:catch(IOException e) {} 怎么知道是否出现问题?
  • 另外,您是否有理由不想将文件中的字节复制到数据库中?

标签: java mysql byte bytearray bufferedimage


【解决方案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;
}

【讨论】:

    【解决方案2】:

    您可以使用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)
    }
    

    【讨论】:

    • 应该是stream.toByteArray();
    【解决方案3】:

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

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

    类似:

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

    【讨论】:

      【解决方案4】:

      使用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 并将其传递给 PreparedStatementsetBlob 方法

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-05-01
        • 2020-02-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-14
        相关资源
        最近更新 更多