0

After a lot of learning on ByteArrays & BLOBS, I managed to write the below Java code to write an image into Access DB (Using ucanaccess) and writing it back to Disk.

When I write an image back to disk the image is in incorrect format or something is messed up that you cannot open that image.

I understand it is not a good practice to store Images on DB but, this is only for my learning.

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

3 回答 3

1

首先,您应该将其分为两部分:

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

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

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

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

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

于 2015-05-18T11:01:39.853 回答
0

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

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

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

同时从数据库使用getBytes()方法获取文件ResultSet并使用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);
    }
}

它会解决你的问题..

于 2015-05-18T11:26:01.807 回答
0

下面是我正在做的写 DB -

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();
}
于 2015-05-18T11:49:56.563 回答