For a solution that doesn't use the Perl module rename that works for this use case:
files=$(find . -name '*.jpg' -type f)
newfiles=$(echo "$files" \
| sed -E 's|(.*/.*[^[:digit:]]+)([[:digit:]]+)(\.jpg)|\1\t\2\t\3|' \
| awk -F '\t' '{print $1 sprintf("%04d",$2) $3}')
while read f1; read -u 3 f2; do
echo mv "$f1" "$f2"
done <<< "$files" 3<<< "$newfiles"
Explanation
The files variable stores all the jpgs found. You can use "-regex" with find if you want.
The newfiles variable stores the new jpg filenames. The code separates out the pathname into three parts, with the middle part being the numbers at the end of the jpg filenames, which are then zero-padded to a width of 4.
The while loop reads in both variables, and executes any command using the lists of filenames found within those two variables. In this case, it is echoing the mv commands to the screen. Remove the echo to perform the actual move.
This code can be improved to work with paths which contain newlines, tabs, or backslashes by adding in null characters between filenames and reading those in with read -d, adding read -r, etc.
You can use and modify this in a future use scenario, for things other than renaming.
Output
Here's the output for your sample directory tree:
mv ./folderB/subfolder2/foto_01.jpg ./folderB/subfolder2/foto_0001.jpg
mv ./folderB/subfolder2/foto_02.jpg ./folderB/subfolder2/foto_0002.jpg
mv ./folderB/subfolder2/foto_03.jpg ./folderB/subfolder2/foto_0003.jpg
mv ./folderB/subfolder1/foto_01.jpg ./folderB/subfolder1/foto_0001.jpg
mv ./folderB/subfolder1/foto_02.jpg ./folderB/subfolder1/foto_0002.jpg
mv ./folderA/subfolder2/image002.jpg ./folderA/subfolder2/image0002.jpg
mv ./folderA/subfolder2/image003.jpg ./folderA/subfolder2/image0003.jpg
mv ./folderA/subfolder2/image001.jpg ./folderA/subfolder2/image0001.jpg
mv ./folderA/subfolder1/Photo_1.jpg ./folderA/subfolder1/Photo_0001.jpg
mv ./folderA/subfolder1/Photo_11.jpg ./folderA/subfolder1/Photo_0011.jpg