One option is to use the pre_get_avatar
filter to return custom avatar HTML, which will short-circuit get_avatar()
preventing it from reaching out to Gravatar for the image.
For example like this,
add_filter('pre_get_avatar', 'wpse_410434_author_img_html', 10, 3);
function wpse_410434_author_img_html( $avatar, $id_or_email, $args ) {
if ( $avatar || ! is_numeric( $id_or_email ) ) {
return $avatar;
}
$upload_dir = wp_upload_dir();
return sprintf(
'<img class="my-author-avatar" src="%1$s" alt="" width="%2$d" height="%2$d">',
esc_url(sprintf(
'%s/author%d.jpg',
$upload_dir['baseurl'],
absint( $id_or_email )
)),
esc_attr( $args['size'] )
);
}
N.B Untested, but should work. Tweak to match your exact setup and needs.