Java - Кодировка изображения в XML - PullRequest
10 голосов
/ 21 августа 2009

Я думал, что сравнительно легко найду решение этой проблемы, но здесь я призываю вас, боги, вытащить меня из этой головоломки.

Итак, у меня есть изображение, и я хочу сохранить его в документе XML с использованием Java. Ранее я достиг этого в 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, пожалуйста, сделайте шаг вперед, даже если это просто ссылка на другой поток, что было бы хорошо.

Приветствия заранее,

шумиха.

Ответы [ 10 ]

20 голосов
/ 21 августа 2009

Я сделал что-то подобное (кодирование и декодирование в 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));

Надеюсь, это поможет.

8 голосов
/ 21 августа 2009

Apache Commons имеет класс Base64 , который должен быть вам полезен:

Оттуда вы можете просто записать байты (они уже находятся в читаемом формате)

2 голосов
/ 31 мая 2010

В Java 6 вы можете использовать DatatypeConverter для преобразования байтового массива в строку Base64:

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

И преобразовать его обратно:

String base64String = ...
byte[] imageData = DatatypeConverter.parseBase64Binary(base64String);
2 голосов
/ 21 августа 2009

После того, как вы получите свой байтовый массив

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>
1 голос
/ 02 мая 2012

Самая простая реализация, которую я смог сделать, как показано ниже, это передача с сервера на сервер XML, содержащая двоичные данные Base64 из библиотеки кодеков Apache: - Чтение двоичных данных из БД и создание 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 с двоичными данными был слишком большим.

  • Вишеш Саху
1 голос
/ 22 августа 2009

Вам не нужно придумывать свой собственный тип данных XML для этого. Схема XML определяет стандартные двоичные типы данных, такие как base64Binary , и это именно то, что вы пытаетесь сделать.

Как только вы используете стандартные типы, некоторые синтаксические анализаторы (например, XMLBeans) могут автоматически преобразовывать их в двоичные. Если ваш анализатор не справляется с этим, вы можете найти классы для base64Binary во многих местах, поскольку тип данных широко используется в SOAP, XMLSec и т. Д.

1 голос
/ 21 августа 2009

Ваш arrayToString() метод довольно странный (какой смысл в этом разделителе?). Почему бы просто не сказать

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

Обратная операция

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

Используйте кодировку ASCII, которой должно быть достаточно при работе с данными, закодированными в Base64. Также я бы предпочел кодировщик Base64 из авторитетного источника, такого как Apache Commons.

0 голосов
/ 22 сентября 2014
node.setTextContent( base64.encodeAsString( fileBytes ) )

с использованием org.apache.commons.codec.binary.Base64

0 голосов
/ 03 августа 2013

Я знаю, что вопрос был в том, как кодировать изображение через 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();
0 голосов
/ 21 августа 2009

Основная проблема заключается в том, что в XML-документе не может быть произвольного байтового потока, поэтому необходимо как-то его кодировать. Схема частого кодирования - BASE64, но любая из них подойдет, если получатель знает об этом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...