【问题标题】:Image to ByteArray to BLOB and BLOB to ByteArray to Image Conversion Issues in JavaJava 中图像到 ByteArray 到 BLOB 和 BLOB 到 ByteArray 到图像的转换问题
【发布时间】:2015-07-29 20:21:02
【问题描述】:

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

【问题讨论】:

  • 顺便说一句,我强烈建议您阅读(然后遵循)Java 方法的命名约定。
  • 我不认为((DataBufferBye) ImageIO.read(...).getRaster().getDataBuffer()).getData() 包含与硬盘上的原始文件相同的字节。

标签: java image bytearray blob ucanaccess


【解决方案1】:

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

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

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

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

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

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

【讨论】:

    【解决方案2】:

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

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

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

    在从数据库取回文件时,使用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);
        }
    }
    

    它会解决你的问题..

    【讨论】:

    • 不需要将整个文件读入内存。它可能不适合。它增加了延迟,
    • 哦,对不起……我改变了答案,感谢让我知道这件事……这对我有帮助……
    • 嗨,Nirranjan - 正如建议的那样,我正在写信给 DB,如下所示。我在从数据库写回磁盘时遇到了困难。你能帮忙吗?
    • 有什么问题,将图像恢复到磁盘??
    • 您正在将空白byte[] 写入数据库..您只是使用byte[] bytearray = new byte[(int)ImgPath.length()]; 对其进行了初始化并且没有在该数组中写入任何内容...所以使用我编辑的上述答案...
    【解决方案3】:

    以下是我正在做的写入 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();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-15
      • 1970-01-01
      • 1970-01-01
      • 2013-11-28
      • 1970-01-01
      • 2013-04-24
      • 2018-10-29
      • 2018-11-16
      相关资源
      最近更新 更多