2009-09-02 4 views
3

XMPP vcard (JPEG 형식으로 생각되는 아바타 그림)에서 사진을 읽고 Delphi TImage 컨트롤에 표시하려면 어떻게해야합니까? 당신이 게시Delphi에서 XMPP (Jabber) vcard 사진을 어떻게 표시합니까?

<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

파이썬 함수'recieve_vcard()'는 이것이 단지 base64로 인코딩 된 데이터임을 보여줍니다. StackOverflow에서 "[delphi] base64"검색을 사용하여이 형식을 인코딩하고 디코딩하는 예제 코드와 링크를 많이 찾으십시오. – mghie

+0

@mghie : 이것을 대답으로 써서 받아 들일 수는없는 이유는 무엇입니까? –

답변

6

는 XML이 사진을 포함하지 않습니다

XMPP 서버는이 XML을 전송합니다. 그림의 내용이 SHA-1 hash입니다. 이전에 이미 이미지를 가져온 경우에 대비하여 해시를 처음 만 얻으므로 새 버전을 요청하는 대신 캐시 된 버전을 표시 할 수 있습니다.

해시가있는 이미지가없는 경우 새 vcard를 요청하십시오. 도착하면 PHOTO 엘리먼트 (있는 경우)를 읽습니다. 두 하위 요소, BINVALTYPE이있을 수 있습니다. BINVAL에는 Base-64 인코딩 버전의 이미지가 포함되고 TYPE에는 image/jpeg 또는 image/png과 같은 이미지 유형에 대한 MIME 유형 식별자가 포함됩니다.

이진 데이터를 디코딩하여 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; 

위의 코드는 Saving a Base64 string to disk as a binary using Delphi 2007에 대한 답변에서 설명 OmniXML에서 Base64Decode 기능을 사용합니다. 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; ... function 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

관련 문제