我被赋予了一些奇怪的任务,大约有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'编码错误的问题。
如果有人偶然发现此页面,我会尽快尝试发布任何答案!我真的很感激你的想法和答案。再次感谢。
答案 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更容易。