pythonflaskvcf-vcardvobject

Python importing Vcard Photo


I'm trying to import a photo into my card using vobject. I have the image stored inside my static folder and the filename inside my database. I would like to import it in my VCard.

So far I have made this:

    if request.method == "POST":
            rowr = User.query.filter_by(user_id = user_id).first()
            rowes = Profile.query.filter_by(user_id = user_id).first()
            vcf_file_path = 'static/Contacto.vcf'
            with open(vcf_file_path , 'w') as file_vcard:
                vcard = vobject.vCard()
                o = vcard.add('fn')
                o.value = rowes.pname

                if rowr.img_url != 'default.png':
                    o = vcard.add('PHOTO')
                    o.value = rowr.img_url

                if rowes.pemail != None:
                    o = vcard.add('email')
                    o.type_param = 'INTERNET'
                    o.value = rowes.pemail

                if rowes.pcellphone != None:
                    o = vcard.add('TEL')
                    o.type_param = 'Número Celular'
                    o.value = str(rowes.pcellphone)

                if rowes.webpage != None:
                    o = vcard.add('url')
                    o.type_param = "Página Web"
                    o.value = rowes.webpage

                if rowes.textarea != None:
                    o = vcard.add('note')
                    o.type_param = "note"
                    o.value = rowes.textarea

                file_vcard.write(vcard.serialize())

But it's clearly no displaying the image in my VCard. I've tried writing the entire path but also didn't work. Thanks in advance


Solution

  • Looks like you're writing the string 'default.jpg' to the photo field, when actually you need to write the base64 encoded image. You could do this with a function like:

    import base64
    def b64_image(filename):
        with open(filename, 'rb') as f:
            b64 = base64.b64encode(f.read())
            return b64.decode('utf-8')
    

    Then call it like:

    o = vcard.add('PHOTO;ENCODING=b;TYPE=image/jpeg')
    o.value = b64_image('default.jpg')
    

    Obviously pass that function a valid path to the image file, which in your case may be rowr.img_url.

    I based this format on the vCard Format Specification.

    When tested this creates a line in the vcf file which looks like:

    PHOTO;ENCODING=B;TYPE=IMAGE/JPEG:iVBORw0KGgoAAA...........
    

    I opened this in Contacts v12.0 on OSx and it renders my sample image:

    vcard sample with working image