How can I read a photo from an XMPP vcard (an avatar picture, which I think is in JPEG format) and display it in a Delphi TImage control?
The XMPP server sends this XML:
<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>
The XML you posted does not contain the picture. It contains the SHA-1 hash of the picture's contents. You only get the hash, initially, in case you have already fetched that image once before, so you can display the cached version instead of requesting it anew.
If you don't have an image with that hash, then request a new vcard. When it arrives, read the
PHOTO
element, if it's available. It may have two subelements,BINVAL
andTYPE
.BINVAL
will contain the Base-64-encoded version of the image, andTYPE
will contain the MIME type identifier for the image type, such as image/jpeg or image/png.Decode the binary data and store it in a stream, such as
TFileStream
orTMemoryStream
. Next, choose whichTGraphic
descendant is appropriate for the kind of image you have. It might beTPngImage
, or it might beTBitmap
. Instantiate the class, and tell it to load the stream's contents. It would go something like this:The code above uses the
Base64Decode
function from OmniXML, described in the answer to Saving a Base64 string to disk as a binary using Delphi 2007. Once you have theTGraphic
value, you can assign it to aTImage
or do whatever else you can do withTGraphic
s.The
ChooseGraphicClass
function might work like this: