Delphi 2010 - декодирование изображения в кодировке Base64 из документа XML - PullRequest
3 голосов
/ 15 апреля 2010

Я пытаюсь декодировать изображение EMF в кодировке base64 из XML-документа в моем приложении и отображать его на экране, однако, кажется, оно никогда не появляется.

Если я копирую / вставляю данные из XML-документа в Notepad ++, использую опцию Base64 Decode и сохраняю файл как .emf, он прекрасно открывается в mspaint. Поэтому я думаю, что проблема в том, как я расшифровываю это.

Я пробовал следующие методы декодирования, описанные в этих статьях:

Как кодировать / декодировать строку Base 64
http://www.swissdelphicenter.ch/torry/showcode.php?id=1223

Я также попробовал класс TIdDecoderMIME безрезультатно.

Кто-нибудь знает самый надежный способ декодирования строки, закодированной в base64, из XML?

Пример * * тысяча двадцать-один

procedure TXmlSerializer.SaveImageFromString(const AValue: string);
var
  StrStream: TStringStream;
  Decoder: TIdDecoderMIME;
begin
  // AValue is base64 encoded string from XML doc
  Decoder := TIdDecoderMIME.Create(nil);
  try
    StrStream := TStringStream.Create(Decoder.DecodeString(AValue));
    try
      StrStream.SaveToFile('MyPath\Image.emf');
    finally
      StrStream.Free;
    end;
  finally
    Decoder.Free;
  end;
end;

Почему вышеприведенное не работает, но копирует необработанные данные в Notepad ++ и декодирует и сохраняет как .emf работает?

Ответы [ 3 ]

7 голосов
/ 15 апреля 2010

Вы используете строку для хранения двоичных данных; Unicode-ness в Delphi 2010 может быть «виноват» здесь.

Попробуйте использовать декодер base64, который поддерживает декодирование в поток, и декодируйте непосредственно в TFileStream; Я использую JclMime (часть JCL Jedi), но я был бы удивлен, если бы не был метод Indy MIME, который работает с потоками вместо строк.

Поскольку JclMime поддерживает только потоковое декодирование, я использую следующую оболочку при декодировании данных base64 из полезных нагрузок XML:

procedure MimeDecode(const inputString: string; const outputStream: Tstream);
var
  ss: TStringStream;
begin
  ss := TStringStream.Create(inputString);
  try
    JclMime.MimeDecodeStream(ss, outputStream);
  finally
    ss.free;
  end;
end;
2 голосов
/ 15 апреля 2010

TIdDecoderMIME работает просто отлично. Пробовал и проверял. Просто посмотрите на примеры кода, предоставленные Indy.

Также OmniXML имеет модуль OmniXMLUtils.pas с различными служебными функциями для XML. Внутри вы можете найти автономную функцию кодирования / декодирования Base64. Вы можете скопировать их вставить или использовать их как есть.

В противном случае отправьте код, используя TIdDecoderMIME. Это должно быть ошибка в вашем коде.

EDIT:

Вы должны следить за тем, чтобы вы записали строку в поток в виде однобайтового порядка. Base64 работает с байтами (символы ASCII) и не будет работать правильно, если вы укажете 2-байтовую строку Unicode. Если вы возьмете в качестве строки последовательность в кодировке Base64 и запишете ее в поток, как есть, у вас будет ошибка, потому что длина такого потока будет вдвое больше, чем оригинал.

Вы можете использовать TStringStream или использовать AnsiStrings для этой задачи. Пока вы придерживаетесь этого, кодирование / декодирование будет работать правильно.

Вы также можете использовать мой SimpleStorage , который сделает всю работу за вас. Чтение изображения из XML сводится к такой простой задаче, как:

  Jpeg := TJPEGImage.Create;
  try
    Jpeg.LoadFromStream(SrcStorage.Get('Image').Filter('gzip').AsBinary.Stream);
  finally
    Jpeg.Free;
  end;

Легко, не правда ли (и это также распаковывается в процессе). :)

0 голосов
/ 15 апреля 2010

Убедитесь, что вы декодируете только значение атрибута, а не весь XML.

В вашем коде обязательно установите позицию потока в 0, прежде чем читать из него.

StrStream.Seek(0, soFromBeginning);

Я не знаком с методом SaveToFile () объекта TStringStream. Вы уверены в этом?

Кроме того, поскольку Delphi 2010 поддерживает строки Unicode, вы можете использовать AnsiStrings при обработке двоичных данных. Будьте осторожны при смешивании многобайтовых типов символов с однобайтовыми данными.

...