2009-09-02 19 views
3

XMPP vcard(JPEG形式のアバター画像)から写真を読み込み、それをDelphiのTImageコントロールに表示するにはどうすればよいですか?DelphiでXMPP(Jabber)vcard写真をどのように表示しますか?

XMPPサーバーは、このXMLを送信します。

<presence id="e3T50-75" to="[email protected]/spark" from="[email protected]" 
type="unavailable"> 
    <x xmlns="vcard-temp:x:update"> 
    <photo>897ce4538a4568f2e3c4838c69a0d60870c4fa49</photo> 
    </x> 
    <x xmlns="jabber:x:avatar"> 
    <hash>897ce4538a4568f2e3c4838c69a0d60870c4fa49</hash> 
    </x> 
</presence> 
+0

が、これはphytonの例ですが、私はデルファイ http://collincode.wordpress.com/2009/01/31/xmpp-jabber-photo-必要module-2/ – cvg

+0

Python関数 'recieve_vcard()'はこれが単にbase64でエンコードされたデータであることを示しています。 StackOverflowで "[delphi] base64"検索を使用して、この形式をエンコードおよびデコードするためのリンクとサンプルコードをたくさん見つけてください。 – mghie

+0

@mghie:なぜこれを答えるように書いて受け入れられるのですか? –

答えて

6

あなたがポストされたXMLは、画像が含まれていません。それは画像の内容のSHA-1 hashを含んでいます。一度そのイメージを取り込んでしまった場合に備えて、ハッシュを最初に取得するだけです。新しいバージョンをリクエストする代わりに、キャッシュされたバージョンを表示することができます。

ハッシュの画像がない場合は、新しいvcardをリクエストしてください。到着したら、PHOTO要素があればそれを読んでください。それは2つのサブ要素、BINVALTYPEを持つかもしれません。 BINVALには、イメージのBase-64エンコードバージョンが含まれ、TYPEには、image/jpegまたはimage/pngなど、イメージタイプのMIMEタイプ識別子が含まれます。

バイナリデータをデコードし、TFileStreamまたはTMemoryStreamなどのストリームに格納します。次に、あなたが持っているイメージの種類にふさわしい子孫TGraphicを選択します。それはTPngImage、またはTBitmapかもしれません。クラスをインスタンス化し、ストリームの内容をロードするように指示します。上記のコードはSaving a Base64 string to disk as a binary using Delphi 2007への答えで説明OmniXMLからBase64Decode機能を使用しています

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; 

:それはこのような何かを行くだろう。 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; 
+0

驚くばかりの答え、ロブ! 提案:vCard XMLの例を追加してください。 –

+0

できません。私はそのようなことを見たことがない。私は、このコードを必要とする人々はすでにvcardを取得する方法を知っていると仮定します。彼らがしなければ、自由にここで新しい質問をすることができます。 –

+0

ありがとうRob Kenndyしかし、私はいくつかのエラーを取得しているJpegエラー#53の実装はomnixmlutilsを使用しています。 {$ R * .dfm} ...関数ChooseGraphicClass(const MimeType:string):TGraphicClass; ...関数CreateGraphicFromVCardPhoto(const BinVal、MimeType:string):TGraphic;プロシージャTForm1.Button1Click(送信者:TObject); memo1.lines.loadfromfile( 'c:\ cvg.bin');を開始します。 image1.Picture.Graphic:= CreateGraphicFromVCardPhoto(memo1.text、 'image/jpeg');終わり; {cvg.binファイルはこちらhttp://www.anasel.com.tr/cvgxml.txt} {http://www.anasel.com.tr/cvg.bin} – cvg

関連する問題