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);
}
}
Firstly, you should separate this into two parts:
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 theWritableRaster
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.
read the image file using
FileInputStream
rather thanWritableRaster
and then store Image file in database using
setBinaryStream()
method ofPreparedStatement
..it will store the file in bytes.
also while getting file back from database use
getBytes()
method ofResultSet
and store it usingFileOutputStream
it will solve your problem..
Below is what I'm doing to write to DB -