如何在 Delphi 中显示 XMPP (Jabber) vcard 照片?

发布于 2024-08-04 01:42:20 字数 486 浏览 3 评论 0原文

如何从 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>897ce4538a4568f2e3c4838c69a0d60870c4fa49</photo>
  </x>
  <x xmlns="jabber:x:avatar">
    <hash>897ce4538a4568f2e3c4838c69a0d60870c4fa49</hash>
  </x>
</presence>

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>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浅唱々樱花落 2024-08-11 01:42:20

您发布的 XML 不包含图片。它包含 SHA-1 哈希 图片内容。最初,如果您之前已经获取过该图像一次,您只会获得哈希值,因此您可以显示缓存的版本,而不是重新请求它。

如果您没有具有该哈希值的图像,请请求新的 vcard。当它到达时,读取 PHOTO 元素(如果有)。它可能有两个子元素:BINVALTYPEBINVAL 将包含图像的 Base-64 编码版本,TYPE 将包含图像类型的 MIME 类型标识符,例如 image/jpeg< /em> 或 image/png

解码二进制数据并将其存储在流中,例如 TFileStreamTMemoryStream。接下来,选择适合您拥有的图像类型的 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;

上面的代码使用 OmniXML 中的 Base64Decode 函数,在的答案中描述使用 Delphi 2007 将 Base64 字符串作为二进制文件保存到磁盘。获得 TGraphic 值后,您可以将其分配给 TImage 或执行您可以使用 TGraphic 执行的其他操作。

ChooseGraphicClass 函数的工作方式可能如下:

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;

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 and TYPE. BINVAL will contain the Base-64-encoded version of the image, and TYPE 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 or TMemoryStream. Next, choose which TGraphic descendant is appropriate for the kind of image you have. It might be TPngImage, or it might be TBitmap. Instantiate the class, and tell it to load the stream's contents. It would go something like this:

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;

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 the TGraphic value, you can assign it to a TImage or do whatever else you can do with TGraphics.

The ChooseGraphicClass function might work like this:

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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文