2009-08-07 38 views
0

我被賦予了一些奇怪的任務,大約有1到50kb的大約1500-2000個jpeg圖像。他們目前存儲在一個我用Postgres製作的簡單數據庫中。自從我使用Matlab和Postgres以來,這已經很長時間了,所以任何幫助或建議都非常感謝!如何使用Java將Postgres中的圖像檢索到Matlab中?

我需要將存儲在數據庫中的圖像從數據庫中取出到Java中。最後一步是將圖像從Java檢索到Matlab中,以便圖像以imread函數在Matlab中工作的相同方式進行存儲。 imread函數讀入一幅圖像,並創建一個n乘m×3矩陣的uint8值,表示RGB的像素強度。

Atm我已經從Java數據庫中進出圖像,當前將圖像存儲在bytea列數據類型中。是最好的數據類型使用?

我怎樣才能從數據庫中取出數據,以便它可以是我所放入的構造的jpeg圖像還是以所需的矩陣數組格式存儲?

目前我不明白檢索到的數據。它是一個包含大約70,000個元素的字節數組,其中包含-128到128之間的值。

注意:數據庫工具包是不可用我

另一個更新:我已經解決了相關post regarding'UTF-8' 編碼錯誤的問題。

如果有人在此頁面上發現任何錯誤,我會盡快嘗試發佈任何答案!我真的很感激你的想法和答案。再次感謝。

回答

1

問題解決:-)

我已成功地獲得存儲在數據庫內的BYTEA塔內成字節數組的字節數。然後通過創建一個臨時文件(使用ByteArrayInputStream和Reader對象來形成一個我寫入文件的BufferedImage對象),將其傳回到Matlab中的一個數組中。

然後處理我從Matlab中的臨時文件中檢索和讀取的數據。一旦數據在Matlab內,所有的臨時文件都將被刪除。

處理結果集從數據庫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 
     } 

    } 
0

您是否有權訪問MATLAB中的Database Toolbox?如果是這樣,您應該能夠使用DATABASE函數直接連接到PostgreSQL數據庫,然後使用FETCH函數或QUERYBUILDER GUI導入和導出數據。這可能比首先通過Java更容易。

+0

沒有,數據庫工具箱不提供給我,我很遺憾,我們無法將圖像存儲在文件系統中。讓事情變得有點棘手! – binarycreations 2009-08-07 17:09:52

1

當你說你有一個bytea列中的圖像時,它究竟是如何存儲的?它是存儲JPEG文件內容的字節,還是存儲RGB像素值的數組或其他內容? 「Bytea」只是一個二進制字符串,它可以以任何格式存儲數據。

我假設它是JPEG內容。在這種情況下,您可以通過Java檢索jpeg內容,將它們保存到臨時文件,並在臨時文件上調用imread()。

這些[-128,127]值是簽名字節Java的值。即使沒有數據庫工具箱,也可以調用常規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); 
+0

我創建圖像的File對象併發送圖像的字節。因此澄清,bytea存儲JPEG文件的內容。 – binarycreations 2009-08-12 14:20:36

+0

我試圖通過Java應用程序建議您創建一個字節數組,並從存儲圖片的bytea數組中填充它。然後我創建了一個FileOutputStream和File,但它看起來並不像Matlab和其他程序那樣以jpeg格式顯示文件爲損壞或未知格式。 – binarycreations 2009-08-16 15:17:00

相關問題