I have seen bug reports on here already about this, but I can add more detail here. Every time a contact is ‘imported’ into Android the quality degrades. So if you set a nice picture for someone on your CardDAV server, when you sync to Android it degrades. Then you change the contact’s number on your Android device. When you sync again the vCard will go in its entirety (including degraded picture) back to your CardDAV server.
Now you change the contact again on another sync’d client.
The Android device syncs again, degrades the photo further. Repeat process until pictures are barely visible.
Looking in: https://github.com/rfc2822/davdroid/blob/master/src/at/bitfire/davdroid/resource/Contact.java
at Line 388:
if (photo != null)
vcard.addPhoto(new Photo(photo, ImageType.JPEG));
It seems at this point DAVDroid is saying take the photo byte stream and make it into a JPEG (hence further compressing it). I do not know how to access the ezvcard source to verify this …
If this turns out to be a problem with the Android Contact Provider then I think a bug should be submitted to AOSP… but seems unlikely as the Google sync adapters would have the same problem.