2009-08-21 67 views
10

我認爲我會相對容易地找到解決這個問題的方法,但在這裏我呼籲來自上帝的幫助讓我擺脫這個難題。Java - 用XML編碼的圖像編碼

所以,我有一張圖片,我想用Java將它存儲在一個XML文檔中。我以前在VisualBasic中通過將圖像保存爲流,將流轉換爲數組,然後VB的xml類能夠將數組編碼爲base64字符串來實現此目的。但是,經過幾個小時的網上搜索Java的等效解決方案之後,我已經空手而回。我有唯一的成功是由:

import it.sauronsoftware.base64.*; 
import java.awt.image.BufferedImage; 
import org.w3c.dom.*; 

... 

     BufferedImage img; 
     Element node; 

     ... 

     java.io.ByteArrayOutputStream os = new java.io.ByteArrayOutputStream(); 

     ImageIO.write(img, "png", os); 

     byte[] array = Base64.encode(os.toByteArray()); 

     String ss = arrayToString(array, ","); 

     node.setTextContent(ss); 

     ... 

    private static String arrayToString(byte[] a, String separator) { 
    StringBuffer result = new StringBuffer(); 
    if (a.length > 0) { 
     result.append(a[0]); 
     for (int i=1; i<a.length; i++) { 
      result.append(separator); 
      result.append(a[i]); 
     } 
    } 
    return result.toString(); 
    } 

這是好的我猜想,但在倒車過程中把它找回來到圖像時,我加載XML文件已被證明是不可能的。如果任何人有更好的方式來編碼/解碼XML文件中的圖像,請繼續前進,即使它只是一個鏈接到另一個線程就沒問題。

提前歡呼,

Hoopla。

+0

我將成爲完全無益,但是:爲什麼?你爲什麼要用XML存儲圖像?有一個更好的方法嗎?如果我發現自己處在這種情況下,我會重新考慮我在做什麼以及爲什麼。 – 2009-08-22 02:20:21

+0

嗨邁克,這是一個有效的點 - 有可能是一種更好的方式,我接受建議。 XML文檔的主要目的是存儲有關大學的信息。它保留了一系列校園,反過來保持房間的陣列。我存儲的圖像是校園地圖。我認爲XML可能是存儲父子數據的最佳方式。但請讓我知道你是否有更好的建議! – Hoopla 2009-08-22 12:43:25

回答

20

我已經做了類似的東西(Base64中的編碼和解碼),它像一個魅力。這是我認爲你應該做的,使用類Base64從Apache Commons項目:

// ENCODING 
BufferedImage img = ImageIO.read(new File("image.png"));  
ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
ImageIO.write(img, "png", baos);  
baos.flush(); 
String encodedImage = Base64.encodeToString(baos.toByteArray()); 
baos.close(); // should be inside a finally block 
node.setTextContent(encodedImage); // store it inside node 

// DECODING 
String encodedImage = node.getTextContent(); 
byte[] bytes = Base64.decode(encodedImage); 
BufferedImage image = ImageIO.read(new ByteArrayInputStream(bytes)); 

希望它能幫助。

+0

幫助(Y) – 2010-09-09 21:24:42

+0

obrigado Joao! @JoaoSilva – 2013-08-03 17:57:50

8

阿帕奇百科全書有Base64類,應該對你有所幫助:

從那裏,你可以只寫出來的字節(他們已經以可讀格式)

+0

乾杯隊友,這是一個更整潔的包! – Hoopla 2009-08-22 13:22:48

+0

那麼爲什麼不把它作爲答案呢? – 2009-08-22 15:59:37

1

arrayToString()方法是相當奇特(那個分隔符有什麼意義?)。爲什麼不能簡單地說

String s = new String(array, "US-ASCII"); 

反向操作

byte[] array = s.getBytes("US-ASCII"); 

使用ASCII編碼,以Base64編碼的數據處理時應該足夠了。另外,我更喜歡來自信譽良好的來源,如Apache Commons的Base64編碼器。

+0

謝謝邁克爾,我承認我正在抓着秸稈,並抄襲了一些人如何轉換數組而沒有真正想到它的例子。現在使用Apaches Commons。歡迎來電諮詢 – Hoopla 2009-08-22 13:25:40

2

你得到你的字節數組後

byte[] array = Base64.encode(os.toByteArray()); 

使用的編碼字符串:

String encodedImg = new String(array, "utf-8"); 

然後,你可以做有趣的事情,在你的XML像

<binImg string-encoding="utf-8" bin-encoding="base64" img-type="png"><![CDATA[ encodedIImg here ]]></binImg> 
0

基本的問題是,你不能在XML文檔中有任意的字節流,所以你需要以某種方式對它進行編碼。一種頻繁的編碼方案是BASE64,但只要收件人知道它,任何方法都會執行。

1

您不需要爲此創建自己的XML數據類型。 XML模式定義了標準的二進制數據類型,例如base64Binary,這正是您要做的。

一旦使用標準類型,它可以被一些解析器(如XMLBeans)自動轉換爲二進制。如果你的解析器沒有處理它,你可以在許多地方找到base64Binary的類,因爲數據類型廣泛用於SOAP,XMLSec等。

2

在Java 6中,可以使用DatatypeConverter將字節數組轉換爲Base64字符串:

byte[] imageData = ... 
String base64String = DatatypeConverter.printBase64Binary(imageData); 

而且將其轉換回:

String base64String = ... 
byte[] imageData = DatatypeConverter.parseBase64Binary(base64String); 
1

最容易實現,我能夠做出的如下,這是從服務器到服務器的XML傳輸包含二進制數據的Base64是從Apache編解碼器庫: - 讀從DB二進制數據,並創建XML

Blob blobData = oRs.getBlob("ClassByteCode"); 
byte[] bData = blobData.getBytes(1, (int)blobData.length()); 
bData = Base64.encodeBase64(bData); 
String strClassByteCode = new String(bData,"US-ASCII"); 
  • 請求服務器上讀取標籤,並將其保存在數據庫
byte[] bData = strClassByteCode.getBytes("US-ASCII"); 
bData = Base64.decodeBase64(bData); 
oPrStmt.setBytes(++nParam, bData); 

容易,因爲它可以是.. 我仍在致力於實現XML的流式處理,因爲它是基因從創建XML的第一臺服務器開始進行評估,並將其流式傳輸到響應對象,這對於具有二進制數據的XML太大時要格外小心。

  • Vishesh薩胡
0

我知道這個問題是亞慶如何將圖像經由XML編碼,但它也可以只是流,而不是使用XML和編碼經由HTTP GET請求的字節一個圖像。請注意,輸入是FileInputStream。 服務器代碼:

 File f = new File(uri_string); 
    FileInputStream input = new FileInputStream(f); 
    OutputStream output = exchange.getResponseBody(); 

    int c = 0; 
    while ((c = input.read()) != -1) {       
     output.write(c); //writes each byte to the exchange.getResponseBody(); 

    } 

    result = new DownloadFileResult(int_list); 
    if (input != null) {input.close();} 
    if (output != null){ output.close();} 

客戶端代碼:

InputStream input = connection.getInputStream(); 
    List<Integer> l = new ArrayList<>(); 
    int b = 0; 
    while((b = input.read()) != -1){ 
     l.add(b);//you can do what you wish with this list of ints ie- write them to a file. see code below. 
    } 

這裏是你如何將整數列表寫入文件:

FileOutputStream out = new FileOutputStream("path/to/file.png"); 

    for(int i : result_bytes_list){ 
      out.write(i); 
    } 
    out.close(); 
0
node.setTextContent(base64.encodeAsString(fileBytes)) 

使用org.apache.commons .codec.binary.Base64