1

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);
        } 
    }
Bharat Nanwani
  • 653
  • 4
  • 11
  • 27
  • As an aside, I'd strongly advise you to read up on (and then follow) Java naming conventions for methods. – Jon Skeet May 18 '15 at 11:01
  • I don't think that `((DataBufferBye) ImageIO.read(...).getRaster().getDataBuffer()).getData()` contains the same bytes as the original file on the harddisk. – Seelenvirtuose May 18 '15 at 11:02

3 Answers3

1

Firstly, you should separate this into two parts:

  • Storing binary data in a database and retrieving it
  • Loading an image file and saving it again

There's no need to use a database to test the second part - you should diagnose the issues by loading the image and saving straight to a file, skipping the database.

No, I believe the problem is that you're copying the data from the WritableRaster's databuffer, and then saving that to a .jpg file. It's not a jpeg at that point - it's whatever the internal format of the WritableRaster uses.

If you want a jpeg file, you don't need to use ImageIO at all - because you've started off with a jpeg file. If you want to start and end with the same image, just copy the file (or save the file to the database, in your case). That's just treating the file as bytes.

If you need to do something like saving in a different format, or at a different size, etc, then you should ask the ImageIO libraries to save the image as a JPEG again, re-encoding it... and then store the result as a file or in the database etc.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
0

read the image file using FileInputStream rather than WritableRaster

and then store Image file in database using setBinaryStream() method of PreparedStatement..

it will store the file in bytes.

also while getting file back from database use getBytes() method of ResultSet and store it using 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);
    }
}

it will solve your problem..

ELITE
  • 5,815
  • 3
  • 19
  • 29
  • 1
    It isn't necessary to read the entire file into memory. It may not fit. It adds latency, – user207421 May 18 '15 at 11:34
  • ohh sorry for that....i changed the answer and thanks to let me know about this..it'll be helpful to me.. – ELITE May 18 '15 at 11:46
  • Hi Nirranjan - As suggested, I am writing to DB as below. I'm facing difficulties in writing back to disk from DB. can you please help with that? – Bharat Nanwani May 18 '15 at 11:48
  • what are the issues, getting back the image to disk?? – ELITE May 18 '15 at 11:50
  • you are writing blank `byte[]` to database..you just initialized it using `byte[] bytearray = new byte[(int)ImgPath.length()];` and didnt write anything in that array...so use the above answer i edited... – ELITE May 18 '15 at 11:51
  • Awesome! This is was so simple. I just made it so complicated. Thank you! :D – Bharat Nanwani May 18 '15 at 12:01
  • I this helped the OP, I wonder why this has a -1 score, strange. – KeitelDOG Sep 27 '21 at 23:51
0

Below is what I'm doing to write to 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();
}
Bharat Nanwani
  • 653
  • 4
  • 11
  • 27