2009-08-21 69 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