Search code examples
c#synchronizationresolutiongoogle-contacts-api

Google contacts api (gdata) syncs low resolution photos


I'm using google contacts api (gdata) to set a contact's photo in google contacts.
I'm using fiddler and I see that the request is sent according to Google Contacts Examples but the photo downloaded back from google is always 96x96.
The code I'm using to update and download the photo is:

public void UpdateUserPhoto(Contact contact, Stream photo)
{
      _contactsRequest.SetPhoto(contact, photo);
}

public static void DownloadPhoto(ContactsRequest cr, Contact contact)
{
    if (contact.PhotoEtag == null)
        return;
    Stream photoStream = cr.Service.Query(contact.PhotoUri);
    FileStream outStream = File.OpenWrite(string.Format(@"c:\friends\{0}.jpg",contact.Name.FullName));
    byte[] buffer;
    using (var memoryStream = new MemoryStream())
    {
        photoStream.CopyTo(memoryStream);
        buffer =  memoryStream.ToArray();
    }

    outStream.Write(buffer, 0, buffer.Length);
    photoStream.Close();
    outStream.Close();
}

I tried syncing the contacts to my phone and there too, the size was always limited to 96x96. Am I doing something wrong or does google not allow syncing more than 96x96? I can see many apps that do sync contacts with more than 96x96 then I guess it's possible, but what is the right way?

Edit

Here are the sync & retrieval of the photo as captured by fiddler:
Sync photo request:
PUT https://www.google.com/m8/feeds/photos/media/[email protected]/55f3484e8aaf1c82 HTTP/1.1
Etag: "SomeEtag"
If-Match: "SomeEtag."
Content-Type: image/jpg
User-Agent: G-GoogleContactsSync/GOAuth2RequestFactory-CS-Version=2.2.0.0
Authorization: Bearer myAuthorization
GData-Version: 3.0
Host: www.google.com
Content-Length: 34480

Sync photo response
HTTP/1.1 200 OK
Content-Type: application/atom+xml; charset=UTF-8; type=entry
GData-Version: 3.1
ETag: "KgxxHGIyfCt7I2BoA047FShUNFU3BWx8RDQ."
Date: Wed, 01 Oct 2014 20:13:06 GMT
Expires: Wed, 01 Oct 2014 20:13:06 GMT
Cache-Control: private, max-age=0
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Server: GSE
Alternate-Protocol: 443:quic,p=0.01
Content-Length: 694
(Here comes xml with Id, Updated, edited etc.)

Photo Request:
GET https://www.google.com/m8/feeds/photos/media/[email protected]/55f3484e8aaf1c82 HTTP/1.1
Content-Type: application/atom+xml; charset=UTF-8
User-Agent: G-GoogleContactsSync/GOAuth2RequestFactory-CS-Version=2.2.0.0
Authorization: Bearer myAuthorization
GData-Version: 3.0
Host: www.google.com

Photo Response:
HTTP/1.1 200 OK
Content-Type: image/jpeg
Expires: Wed, 01 Oct 2014 20:25:54 GMT
Date: Wed, 01 Oct 2014 20:25:54 GMT
Cache-Control: private, max-age=0, must-revalidate, no-transform
Vary: Accept, X-GData-Authorization, GData-Version
GData-Version: 3.1
ETag: "SomeEtag."
Transfer-Encoding: chunked
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Server: GSE
Alternate-Protocol: 443:quic,p=0.01


Solution

  • I retested this myself and uploaded pictures from a number of sources including contacts app on my android phone and tablet, the gmail contacts and the API. All of them will take a higher resolution picture but will only allow the size to be 96x96 using the Contact API v3.So when you download via any application using that API on the PC you will get a 96x96 image and there appears to be no way to vary that with that particular API.

    Meaning unless I've also missed something that the contact API v3 is limited to this size of image. I suspect the google+ equivalents are not.

    The way in which I have done this is to use the google plus api

      var service = new PlusService(new BaseClientService.Initializer());
      var request = new PeopleResource.GetRequest(service, "<your google user id>")
      {
          OauthToken = authParameters.AccessToken
      };
    
      Person person = request.Execute();
      Person.ImageData image = person.Image;
      string pictureUrl = image.Url;
    
      ... request to url here after munging sz
    

    now you are going to need to change the url that comes back to the size you want as the defaults is ?sz=50, if your original is at the size you specify it will show it or otherwise it will scale the image.

    However the contacts api and the google plus api are different beasts. You will need to use the domain functionality of google plus to pull out your contacts there and potentially they have different photos than you do in your contacts list (if any is set).

    Krystan