Java 中图像到 ByteArray 到 BLOB 和 BLOB 到 ByteArray 到图像的转换问题

Image to ByteArray to BLOB and BLOB to ByteArray to Image Conversion Issues in Java

在对 ByteArrays 和 BLOBS 进行大量学习之后,我设法编写了以下 Java 代码来将图像写入 Access DB(使用 ucanaccess)并将其写回磁盘。

当我将图像写回磁盘时,图像格式不正确或出现问题导致您无法打开该图像。

我知道将图像存储在数据库中不是一个好的做法,但是,这仅供我学习。

public static void Update_to_DB() throws SQLException, IOException {
    String URL = "jdbc:ucanaccess://C:\Users\bharat.nanwani\Desktop\Images.accdb";
    Connection conn = DriverManager.getConnection(URL);
    //Statement stmt = conn.createStatement();
    PreparedStatement p;

    File ImgPath = new File("C:\Users\bharat.nanwani\Desktop\Desert.jpg");
    BufferedImage bufferedimage = ImageIO.read(ImgPath);

    WritableRaster raster = bufferedimage.getRaster();
    DataBufferByte data = (DataBufferByte) raster.getDataBuffer();

    byte[] bytearray = date.getdata();


    String query = "INSERT INTO Images(data) VALUES(?);";
    p = conn.prepareStatement(query);
    p.setBinaryStream(1, new ByteArrayInputStream(bytearray),bytearray.length);
    p.execute();
}

public static void update_to_DISK() throws SQLException, IOException {
        String URL = "jdbc:ucanaccess://C:\Users\bharat.nanwani\Desktop\Images.accdb";
        Connection conn = DriverManager.getConnection(URL);
        PreparedStatement p;
        ResultSet rs;
        String query = "SELECT Data FROM Images";
                p=conn.prepareStatement(query);
        rs = p.executeQuery();
        if (rs.next()) {
        Blob blob = rs.getBlob("Data");

        byte[] bytearray = blob.getBytes(1L, (int)blob.length());

        FileOutputStream fos = new FileOutputStream("C:\Users\bharat.nanwani\Desktop\New Folder\test.jpg");
        fos.write(bytearray);
        fos.close();

        System.out.println(bytearray);
        } 
    }

首先,你应该把它分成两部分:

  • 在数据库中存储二进制数据并检索它
  • 正在加载图像文件并再次保存

无需使用数据库来测试第二部分 - 您应该通过加载图像并直接保存到文件来诊断问题,跳过数据库。

不,我认为问题在于您正在从 WritableRaster 的数据缓冲区复制数据,然后将其保存到 .jpg 文件中。那时它不是 jpeg - 它是 WritableRaster 使用的任何内部格式。

如果您想要 jpeg 文件,则根本不需要使用 ImageIO - 因为您已经开始 使用 jpeg 文件。如果您想以相同的图像开始和结束,只需复制文件(或将文件保存到数据库中,在您的情况下)。那只是将文件视为字节。

如果你需要做一些事情,比如以不同的格式保存,或者以不同的大小保存,那么你应该要求 ImageIO 库将图像保存为 JPEG再次,重新编码...然后将结果存储为文件或数据库等

使用FileInputStream而不是WritableRaster读取图像文件

然后使用PreparedStatementsetBinaryStream()方法将图像文件存储在数据库中..

它将以字节为单位存储文件。

同时从数据库取回文件时使用 ResultSetgetBytes() 方法并使用 FileOutputStream

存储它
public static void Update_to_DB() throws SQLException, IOException {
    String URL = "jdbc:ucanaccess://C:\Users\bharat.nanwani\Desktop\Images.accdb";
    Connection conn = DriverManager.getConnection(URL);
    //Statement stmt = conn.createStatement();
    PreparedStatement p;

    File ImgPath = new File("C:\Users\bharat.nanwani\Desktop\Desert.jpg");
    FileInputStream fin = new FileInputStream(ImgPath);
    String query = "INSERT INTO Images(Data) VALUES(?);";
    p = conn.prepareStatement(query);
    p.setBinaryStream(1, fin);
    p.execute();
}

public static void update_to_DISK() throws SQLException, IOException {
    String URL = "jdbc:ucanaccess://C:\Users\bharat.nanwani\Desktop\Images.accdb";
    Connection conn = DriverManager.getConnection(URL);
    PreparedStatement p;
    ResultSet rs;
    String query = "SELECT Data FROM Images";
    p = conn.prepareStatement(query);
    rs = p.executeQuery();
    if (rs.next()) {
        byte[] bytearray = rs.getBytes("Data");
        FileOutputStream fos = new FileOutputStream("C:\Users\bharat.nanwani\Desktop\New Folder\test.jpg");
        fos.write(bytearray);
        fos.close();
        System.out.println(bytearray);
    }
}

它会解决你的问题..

下面是我正在做的写入数据库的操作 -

public static void main(String[] Args) throws SQLException, IOException {
    String URL = "jdbc:ucanaccess://C:\Users\bharat.nanwani\Desktop\Images.accdb";
    Connection conn = DriverManager.getConnection(URL);
    PreparedStatement p;

    File ImgPath = new File("C:\Users\bharat.nanwani\Desktop\Desert.jpg");
    FileInputStream fileinput = new FileInputStream(ImgPath); 

    byte[] bytearray = new byte[(int)ImgPath.length()];


    String query = "INSERT INTO Images(data) VALUES(?);";
    p = conn.prepareStatement(query);
    //p.setBinaryStream(1, new ByteArrayInputStream(bytearray),bytearray.length);
    p.setBytes(1, bytearray);
    p.execute();
}