Xml 如何在Delphi中显示XMPP(Jabber)vcard照片?
如何从XMPP vcard(我认为是JPEG格式的化身图片)读取照片并在Delphi TImage控件中显示 XMPP服务器发送以下XML:Xml 如何在Delphi中显示XMPP(Jabber)vcard照片?,xml,delphi,xmpp,vcf-vcard,Xml,Delphi,Xmpp,Vcf Vcard,如何从XMPP vcard(我认为是JPEG格式的化身图片)读取照片并在Delphi TImage控件中显示 XMPP服务器发送以下XML: <presence id="e3T50-75" to="cvg@esx10-2022/spark" from="semra@esx10-2022" type="unavailable"> <x xmlns="vcard-temp:x:update"> <photo>897ce4538a4568f2e3c4
<presence id="e3T50-75" to="cvg@esx10-2022/spark" from="semra@esx10-2022"
type="unavailable">
<x xmlns="vcard-temp:x:update">
<photo>897ce4538a4568f2e3c4838c69a0d60870c4fa49</photo>
</x>
<x xmlns="jabber:x:avatar">
<hash>897ce4538a4568f2e3c4838c69a0d60870c4fa49</hash>
</x>
</presence>
897ce4538a4568f2e3c4838c69a0d60870c4fa49
897ce4538a4568f2e3c4838c69a0d60870c4fa49
您发布的XML不包含图片。它包含图片内容的详细信息。最初,如果您已经获取了该图像一次,那么您只能获取哈希值,这样您就可以显示缓存的版本,而不是重新请求它
如果您没有包含该哈希的图像,请请求一张新的vcard。当它到达时,阅读照片
元素(如果可用)。它可能有两个子元素,BINVAL
和TYPE
BINVAL
将包含图像的Base-64编码版本,TYPE
将包含图像类型的MIME类型标识符,如image/jpeg或image/png
解码二进制数据并将其存储在流中,例如TFileStream
或TMemoryStream
。接下来,选择适合您拥有的图像类型的TGraphic
子体。它可能是TPngImage
,也可能是TBitmap
。实例化该类,并告诉它加载流的内容。事情会是这样的:
function CreateGraphicFromVCardPhoto(const BinVal, MimeType: string): TGraphic;
var
Stream: TStream;
GraphicClass: TGraphicClass;
begin
Stream := TMemoryStream.Create;
try
if not Base64Decode(BinVal, Stream) then
raise EBase64Decode.Create;
Stream.Position := 0;
GraphicClass := ChooseGraphicClass(MimeType);
Result := GraphicClass.Create;
try
Result.LoadFromStream(Stream);
except
Result.Free;
raise;
end;
finally
Stream.Free;
end;
end;
function ChooseGraphicClass(const MimeType: string): TGraphicClass;
begin
if MimeType = 'image/bmp' then
Result := TBitmap
else if MimeType = 'image/png' then
Result := TPngImage
else if MimeType = 'image/gif' then
Result := TGifImage
else if MimeType = 'image/jpeg' then
Result := TJpegImage
else
raise EUnknownGraphicFormat.Create(MimeType);
end;
上述代码使用的base64解码
功能来自,如对的回答中所述。获得TGraphic
值后,可以将其分配给TImage
或使用TGraphic
s执行任何其他操作
choosegraphicsclass
函数的工作原理如下:
function CreateGraphicFromVCardPhoto(const BinVal, MimeType: string): TGraphic;
var
Stream: TStream;
GraphicClass: TGraphicClass;
begin
Stream := TMemoryStream.Create;
try
if not Base64Decode(BinVal, Stream) then
raise EBase64Decode.Create;
Stream.Position := 0;
GraphicClass := ChooseGraphicClass(MimeType);
Result := GraphicClass.Create;
try
Result.LoadFromStream(Stream);
except
Result.Free;
raise;
end;
finally
Stream.Free;
end;
end;
function ChooseGraphicClass(const MimeType: string): TGraphicClass;
begin
if MimeType = 'image/bmp' then
Result := TBitmap
else if MimeType = 'image/png' then
Result := TPngImage
else if MimeType = 'image/gif' then
Result := TGifImage
else if MimeType = 'image/jpeg' then
Result := TJpegImage
else
raise EUnknownGraphicFormat.Create(MimeType);
end;
这是一个phyton示例,但我需要delphi,因为Python函数
recieve\u vcard()
显示这只是base64编码的数据。使用“Delphi”Base64搜索在StAdvExcel上找到很多链接和示例代码来编码和解码这种格式。@ MGHIE:为什么不把这个写为答案,以便它可以被接受?@拉尔斯:我不认为这是一个答案,只是一个有益的推敲向右的方向。希望有人(甚至OP)发布一些代码来回答这个问题。我只是快速浏览了一下链接的Python代码。谢谢Rob Kenndy,但我得到了一些错误Jpeg error#53实现使用OmniXlutils;{$R*.dfm}…函数选择GraphicClass(const MimeType:string):TGraphicClass。。。函数CreateGraphicFromVCardPhoto(const BinVal,MimeType:string):TGraphic;程序TForm1.按钮1单击(发送方:TObject);开始memo1.lines.loadfromfile('c:\cvg.bin');image1.Picture.Graphic:=CreateGraphicFromVCardPhoto(memo1.text,'image/jpeg');结束;{cvg.bin文件在这里}{}真棒的答案,罗伯!建议:添加一个示例vCard XML。没有办法。我从未见过这样的事。我假设需要此代码的人已经知道如何获得vcard。如果他们没有,他们可以在这里自由地问一个新问题。谢谢Rob Kenndy,但我有一些错误Jpeg error#53实现使用OmniXlutils;{$R*.dfm}…函数选择GraphicClass(const MimeType:string):TGraphicClass。。。函数CreateGraphicFromVCardPhoto(const BinVal,MimeType:string):TGraphic;程序TForm1.按钮1单击(发送方:TObject);开始memo1.lines.loadfromfile('c:\cvg.bin');image1.Picture.Graphic:=CreateGraphicFromVCardPhoto(memo1.text,'image/jpeg');结束;{cvg.bin文件在这里}{}Delphi的JPEG库无法处理所有JPEG文件。是的,罗伯特,德尔福不能处理所有类型的jpeg。我使用此过程和memo1.lines.savetofile。。。保存到磁盘,然后查看右图。过程SaveBase64ToFile(常量编码,文件名:字符串);var-fs:TFileStream;begin fs:=TFileStream.Create(文件名,fmCreate);如果不是Base64Decode(encoded,fs),请尝试,然后引发异常。Create('Invalid data!');最后是FreeAndNil(fs);结束;结束;