【问题标题】:How do I retrieve images within Postgres into Matlab using Java?如何使用 Java 将 Postgres 中的图像检索到 Matlab 中?
【发布时间】:2009-08-07 16:52:14
【问题描述】:

我接到了一个奇怪的任务,大约有 1500-2000 张 jpeg 图像,大小都在 1-50kb 左右。它们目前存储在我用 Postgres 创建的一个简单数据库中。很久没有大量使用 Matlab 和 Postgres 了,非常感谢任何帮助或建议!

我需要将存储在数据库中的图像从数据库中取出到 Java 中。最后一步是将图像从 Java 检索到 Matlab 中,以便图像以与 imread 函数在 Matlab 中工作的方式相同的方式存储。 imread 函数读取图像并创建一个 n × m × 3 的 uint8 值矩阵数组,表示 RGB 的像素强度。

Atm 我已经用 Java 将图像进出数据库,当前将图像存储在 bytea 列数据类型中。是最好的数据类型吗?

我怎样才能从数据库中取回数据,以便它是我放入的构造的 jpeg 图像或者是请求的矩阵数组格式?

目前我不了解检索到的数据。它位于一个包含大约 70,000 个元素的字节数组中,其中包含 -128 到 128 之间的值。求助!?!

注意:我无法使用数据库工具包

另一个更新:我已经解决了与 post 有关“UTF-8”编码错误的问题。

如果有人偶然发现此页面,我会尽快尝试发布任何答案!我真的很感激你的想法和回答。再次感谢。

【问题讨论】:

    标签: java sql database matlab image


    【解决方案1】:

    当您说您将图像放在 bytea 列中时,它究竟是如何存储的?它是存储 JPEG 文件内容的字节,还是 RGB 像素值数组,还是其他东西? “Bytea”只是一个二进制字符串,可以存储几乎任何格式的数据。

    我假设它是 JPEG 内容。在这种情况下,您可以做的是通过 Java 检索 jpeg 内容,将它们保存到临时文件,然后在临时文件上调用 imread()。

    那些 [-128,127] 值是有符号字节 Java 的值。即使没有 Database Toolbox,您也可以调用常规 JDBC 或其他使用它的 Java 代码。您用来获取这些值的 Java 方法 - 从 Matlab 调用它(在类路径上使用您的 JAR),它应该将该数组作为 int8 数组返回,或者您可以转换为一个数组。

    鉴于在名为“bytes”的 Matlab 变量中,您可以使用类似这样的方式将其写入临时文件。

    file = [tempname() '.jpg'];
    fid = fopen(file, 'wb');
    fwrite(fid, bytes, 'int8');
    fclose(fid);
    

    通过指定“int8”精度,我认为您可以跳过将它们转换为无符号字节的步骤,这是一种更常见的约定。将 int8s 写为 'int8' 或 uint8s 写为 'uint8' 将生成相同的文件。如果确实需要将它们转换为无符号,请使用 Matlab 的 typecast() 函数。

    unsigned_bytes = typecast(bytes, 'uint8');
    

    此时您可以在临时文件上调用 imread 然后将其删除。

    img = imread(file);
    delete(file);
    

    【讨论】:

    • 我创建一个图像的文件对象并发送图像的字节。所以澄清一下,bytea 存储 JPEG 文件的内容。
    • 我已经尝试了您通过 Java 应用程序提出的建议,创建了一个字节数组并从存储图片的 bytea 数组中填充它。然后我创建了一个 FileOutputStream 和文件,但结果似乎不是 jpeg 格式,因为 Matlab 和其他程序将文件视为损坏或未知格式。
    【解决方案2】:

    问题解决了:-)

    我已设法将存储在数据库中 bytea 列中的字节转换为字节数组。然后通过创建一个临时文件(使用 ByteArrayInputStream 和 Reader 对象形成我写入文件的 BufferedImage 对象)将其发送回数组中的 Matlab。

    然后处理我在 Matlab 中从临时文件中检索和读取的数据。一旦数据在 Matlab 中,所有的临时文件都会被删除。

    处理 ResultSet 以从从数据库 bytea 列接收的字节数组创建临时图像的代码如下所示:

    private static void processImageResultSet(ResultSet rs) throws SQLException, FileNotFoundException, IOException{
    
            int i = 0;                  //used as a count and to name various temp files
            while(rs.next()){           //loop through result sets
    
            byte[] b = rs.getBytes(1);                                 //the bytea column result
            String location = getFileName(rs.getString(2));            //the name of the jpg file
            ByteArrayInputStream bis = new ByteArrayInputStream(b);    //creates stream storing byts
    
            //To make individual names of temporary files unique the current time and date is stored
            SimpleDateFormat df = new SimpleDateFormat("'Date 'yyyy-MM-dd HH'H'-mm'M'-ss'secs'-SS'ms'"); //formats date string
            Calendar cal = Calendar.getInstance();                                //gets instance of calendar time
            String fileDate = df.format(cal.getTime());                           //gets the time and date as a String
    
            Iterator<?> readers = ImageIO.getImageReadersByFormatName("jpg");     //creates a reader object, that will read jpg codec compression format
            Object source = bis;                                                  //object to store stream of bytes from database
            ImageReader reader = (ImageReader) readers.next();                      
            ImageInputStream iis = ImageIO.createImageInputStream(source);        //creates image input stream from object source which stores byte stream
    
            reader.setInput(iis, true);             //sets the reader object to read image input stream
    
            ImageReadParam param = reader.getDefaultReadParam(); 
            Image image = reader.read(0, param);
    
            BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB);   //creates buffered image
    
            Graphics2D g2 = bufferedImage.createGraphics();
            g2.drawImage(image, null, null);
            File imageFile = new File(location + " " + fileDate + " " + i + ".jpg"); //creates image file 
            ImageIO.write(bufferedImage, "jpg", imageFile);                          //writes buffered image object to created file
    
            i++;        //counts number of results from query within the ResultSet 
            }
    
        }
    

    【讨论】:

      【解决方案3】:

      您可以在 MATLAB 中访问 Database Toolbox 吗?如果是这样,您应该能够使用DATABASE 函数直接连接到PostgreSQL 数据库,然后使用FETCH 函数或QUERYBUILDER GUI 导入和导出数据。这可能比第一次使用 Java 更容易。

      【讨论】:

      • 不,我无法使用数据库工具箱,很遗憾我也无法将图像存储在文件系统上。让事情变得有点棘手!
      猜你喜欢
      • 2018-04-10
      • 2017-09-21
      • 2021-03-28
      • 2023-03-29
      • 1970-01-01
      • 1970-01-01
      • 2013-12-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多