First, let me describe the issue.
When using a CDN other than Cloudflare, your static files including images will be served from a CDN subdomain, like cdn.mydomain.com. However, the image URLs in the XML sitemap will remain mydomain.com/image.jpg instead of cdn.mydomain.com/image.jpg.
This would be fine IF Google would actually honor canonical tags in the HTTP headers of image URLs that these CDN providers send. However, the sad reality is that they don't honor canonicals of image URLs, only for web search (ie. normal HTML pages including say PDFs). This has been tested by me and others (https://blog.strategiq.co/do-canonical-tags-on-images-work-a-brighton-seo-experiment-512808985296 see last sub heading "Canonical from image to imageā¦")
And Google confirm this indirectly. Here:
they say that canonical headers are supported for web search results only, which excludes image search. The example they use is a PDF, which shows in web search, not in image search. Here's the article: https://support.google.com/webmasters/answer/139066?hl=en
And John Mueller confirms this: https://www.seroundtable.com/google-rel-canonical-for-images-nope-22549.html
Here are two articles that describe the correct solution to this issue, which is to simply use the CDN subdomain in the XML sitemap for image URLs instead of the origin domain. See https://crunchify.com/maxcdn-and-wordpress-image-index-seo-issue-in-google-search-console-fix-cdn-image-links-and-avoid-duplicate-content-penalty/
and http://www.gauraw.com/get-google-index-website-images-using-cdn-services/
Now my idea is that it would be amazing if Rank Math would simply add an optional input field to general sitemap settings called "CDN Hostname" (with description "Enter your CDN hostname here without https:// prefix if you host your images on a CDN domain that's indexable and different from your main domain. This will replace the hostname in image URLs in the sitemap with the CDN hostname. Ex.: cdn.example.com") that would replace the hostname in image URLs (ie. <image:loc>) with the input value. So for example https://example.com/wp-content/uploads/image.jpg would be replaced with https://cdn.example.com/wp-content/uploads/image.jpg within the XML sitemap if the input field value is "cdn.example.com".
Below is a code snippet that should do exactly that which Alex came up with:
function rankmath_cdn_image_seo_fix( $uri ) {
return str_replace( 'https://example.com', 'https://cdn.example.com', $uri );
}
add_filter( 'xml_img_src', 'rankmath_cdn_image_seo_fix' );
However, it would be much better to have this as an option in Rank Math as described above. It should be easy to implement.