iosperlbase64vcf-vcardembperl

can't add a base64-encoded image to vCard


I've successfully used Perl (via Embperl) to create a dynamically-generated vCard for employees, populating all the fields except for the photo. I can't get that working no matter what. (The code to generate a photo-less vCard works fine.)

According to the information I can find online, the image must be base64-encoded in the vCard itself. The vCard spec (I'm using 3.0) supports URL-linked images, but my iPhone won't link to them that way. So it's base64 or nothing.

Now, I know the base64-encoding works, because if use the code to just show an image...

[-
$photo = "/path/to/directory/".$employeeID.".jpg";
open($file, "<", $photo) || warn "Can't open $photo: $!\n";
#binmode $file;
$jpg = join('', <$file>);
$decoded = MIME::Base64::encode_base64($jpg);
$vcard_content  = $decoded;
-]
<img src="data:image/jpeg;base64,[+ $decoded +]">

...then the photo shows up perfectly in my browser. (Someone suggested I needed binmode $file; in there, but removing it seems to make no difference in the output.)

But if I include it in the vCard instead, the photo simply doesn't show up with the rest of the contact data:

$vcard_content  = "BEGIN:VCARD\r";
$vcard_content .= "VERSION:3.0\r";
$vcard_content .= "N:".$v_last.";".$v_first.";".$v_middle.";;\r";
# etc.
$vcard_content .= "PHOTO;ENCODING=b;TYPE=JPEG:".$decoded."\r";
# etc.
$vcard_content .= "END:VCARD";

Am I mis-formatting the vCard data somehow?


Solution

  • After importing the vCard into OS X Contacts and exporting it again, then viewing the exported vCard with a text editor, I noticed that the first part of the base64-encoded image was there but the rest was not. The encoding stopped right where a whitespace (\r apparently) character appeared in the encoded string.

    So I removed all the whitespace characters from the base64 encoding before building the vCard:

    $decoded = MIME::Base64::encode_base64($jpg);
    $decoded =~ s/\s//g;
    

    And now the photo imports correctly.