如何使用Java将Postgres中的图像检索到Matlab中?

时间:2009-08-07 16:52:14

标签: java sql database matlab image

我被赋予了一些奇怪的任务,大约有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'编码错误的问题。

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

3 个答案:

答案 0 :(得分: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);

答案 1 :(得分:1)

问题解决了: - )

我设法将存储在数据库中的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 
        }

    }

答案 2 :(得分:0)

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