why are contacts images stored as absolute URLs?
The schema for contact records specifies that the image be stored as URL (civicrm_contact.image_URL).

As an historical matter, I don't know why this was chosen, but it does come with some trade-offs:


If you write a UI in a different PHP stack, it's easier to share image uploads if they're URLs. For example, webform_civicrm accepts uploads using Drupal/webform techniques and then simply sets the URL.
If you have a complex site that spans multiple domains, the contact images can be shared. Similarly, if you're migrating into Civi, you can import the URLs without rearranging the image files.
It's trivial to include the image URL as a mail-merge token.
If you migrate the Civi site to a different URL, the contact images break.
If you access via APIv3, it's can be awkward to manage image data.


To fix contact images after migrating to a different URL, use SQL to perform a search/replace on field image_URL of table civicrm_contact. For tips on composing a search/replace, see, e.g., https://stackoverflow.com/questions/1876762/mysql-way-to-update-portion-of-a-string