我正在尝试从我的应用程序中的XML文档解码base64编码的EMF图像并在屏幕上呈现它,但是,它似乎永远不会出现。
如果我将XML文档中的数据复制/粘贴到Notepad ++中并使用Base64 Decode
选项并将文件另存为.emf
,则可以在mspaint中打开。所以我认为问题是我如何解码它。
我尝试了以下这些文章中描述的解码方法:
How to encode / decode Base 64 string
http://www.swissdelphicenter.ch/torry/showcode.php?id=1223
我也试过TIdDecoderMIME
课无济于事。
有没有人知道从XML解码base64编码字符串的最可靠方法?
实施例
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
有效吗?
答案 0 :(得分:7)
您正在使用字符串存储二进制数据; Delphi 2010的unicode-ness可能会在这里“责怪”。
尝试使用支持解码到流的base64解码器,并直接解码为TFileStream
;我使用JclMime
(Jedi的JCL的一部分),但是如果没有Indy MIME方法可以在流而不是字符串上工作,我会感到惊讶。
由于JclMime
仅支持流到流的解码,因此在从XML有效负载解码base64数据时使用以下包装器:
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;
答案 1 :(得分:2)
TIdDecoderMIME工作得很好。试过并测试过。只需查看Indy提供的代码示例。
此外,OmniXML具有OmniXMLUtils.pas单元,其中包含各种用于XML的实用程序功能。 在里面你可以找到独立的Base64编码/解码功能。您可以复制粘贴它们或按原样使用它们。
否则使用TIdDecoderMIME发布代码。你的代码一定是个错误。
编辑:
您必须注意您将字符串写为单字节顺序流。 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;
容易不是它(并且它在此过程中也被解压缩)。 :)
答案 2 :(得分:0)
确保您只解码属性值而不是整个XML。
在您的代码中,请确保在读取之前将流的位置设置为0.
StrStream.Seek(0, soFromBeginning);
我不熟悉TStringStream的SaveToFile()方法。你确定吗?
此外,由于Delphi 2010支持unicode字符串,因此在处理二进制数据时可能需要使用AnsiStrings。将多字节字符类型与单字节数据混合时要小心。