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

断了今生、忘了曾经 提交于 2019-12-13 04:55:07

问题


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

回答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.




回答2:


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



回答3:


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..



来源:https://stackoverflow.com/questions/30301344/image-to-bytearray-to-blob-and-blob-to-bytearray-to-image-conversion-issues-in-j

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!