我以为我会相对容易地找到解决这个问题的方法,但在这里,我呼吁你们众神的帮助让我摆脱这个难题。
所以,我有一个图像,我想用Java将它存储在XML文档中。我以前通过将图像保存到流中,将流转换为数组,然后VB的xml类能够将数组编码为base64字符串,在VisualBasic中实现了这一点。但是,经过几个小时的网络搜索以获得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文件中的图像进行编码/解码,请向前迈进,即使它只是指向其他线程的链接也没问题。
提前干杯,
喧闹。
答案 0 :(得分:20)
我做过类似的事情(Base64中的编码和解码),它就像一个魅力。以下是我认为您应该使用Apache Commons项目中的类Base64
:
// 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));
希望它有所帮助。
答案 1 :(得分:8)
Apache Commons有一个Base64类应该对您有所帮助:
从那里,你可以写出字节(它们已经是可读格式)
答案 2 :(得分: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>
答案 3 :(得分:2)
使用Java 6,您可以使用DatatypeConverter将字节数组转换为Base64字符串:
byte[] imageData = ...
String base64String = DatatypeConverter.printBase64Binary(imageData);
并将其转换回来:
String base64String = ...
byte[] imageData = DatatypeConverter.parseBase64Binary(base64String);
答案 4 :(得分:1)
您的arrayToString()
方法相当奇怪(该分隔符的重点是什么?)。为什么不简单地说
String s = new String(array, "US-ASCII");
反向操作是
byte[] array = s.getBytes("US-ASCII");
使用ASCII编码,在处理Base64编码数据时应该足够。另外,我更喜欢来自像Apache Commons这样信誉良好的来源的Base64编码器。
答案 5 :(得分:1)
您不需要为此创建自己的XML数据类型。 XML模式定义标准二进制数据类型,例如base64Binary,这正是您尝试做的。
一旦使用标准类型,它就可以被一些解析器(如XMLBeans)自动转换为二进制文件。如果你的解析器没有处理它,你可以在很多地方找到base64Binary的类,因为数据类型在SOAP,XMLSec等中被广泛使用。
答案 6 :(得分:1)
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太大时要小心。
答案 7 :(得分:0)
基本问题是您不能在XML文档中拥有任意字节流,因此您需要以某种方式对其进行编码。一个频繁的编码方案是BASE64,但只要收件人知道它就会做任何事情。
答案 8 :(得分:0)
我知道问题是如何通过XML编码图像,但也可以通过HTTP GET请求流式传输字节,而不是使用XML和编码图像。请注意,输入为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();
答案 9 :(得分:0)
node.setTextContent( base64.encodeAsString( fileBytes ) )
使用org.apache.commons.codec.binary.Base64