Between Exchange 2013 and 2016 there where few new operations introduced into EWS, one operation that was introduced was the SetUserPhoto operation which pairs with the GetUserPhoto operation that was introduced in Exchange 2013.
What this operation does is allows you to set/upload a high resolution photo for a user to be used in Exchange and Skype for Business in Exchange Online or Exchange 2016. A little bit more about the high ressolution user photo is that when you set this it uploads this as an item in the Non_IPM_Root of the Mailbox (so it is not visible to the user) with a message class of IPM.UserPhoto if you where to look at a Mailbox with a Mapi Editor you can see the object that this creates. eg
If you look at the UserPhoto Object itself you can see the different size formats are stored ready to access in a number of different Binary Mapi properties eg
So what the SetUserPhoto operation does is handles creating this object and all the different photo formats that applications might require.
Currently there isn't anything in the EWS Managed API to take advantage of this new operation so to use this you can either use the WSDL Proxy Objects (generated against Exchange 2016 or Exchange Online) or just raw soap like the following.
I've put together a Powershell script that use the EWS Managed API to do the discovery and then uses raw soap to do the upload the photo.. I've put this script up on GitHub here https://github.com/gscales/Powershell-Scripts/blob/master/Upload-Photo.ps1
To use this script you use the cmdlet like
Set-PhotoEWS -MailboxName mailbox@domain -Photo c:\temp\photo1.jpg
The script itself looks like