Create individual files via Bash with MD5 hashes of all files in a directory recursively
A gotcha, sort of...

Although the one-liner works, the use of $0 is inappropriate. From man bash:

   -c        If the -c option is present, then commands are read from  the
             first non-option argument command_string.  If there are argu-
             ments  after  the  command_string,  the  first  argument   is
             assigned  to  $0  and any remaining arguments are assigned to
             the positional parameters.  The assignment  to  $0  sets  the
             name  of  the  shell, which is used in warning and error mes-
             sages.


That is, the file names to compute MD5 for are not appropriate values as the "shell". Positional arguments are in $1, $2, and so on, that would be appropriate for this purpose. You can fix that using the -- special argument, that signals the end of options and disables further option processing:

find ... -exec bash -c 'printf $(md5 -q "$1") &gt; "${1%.*}.md5"' -- {} \;


Simplify

Is it really important to strip the .jpg at the end of filenames?
Would it be terrible if the files looked like this?

./2016/05/17/photo-312.jpg
./2016/05/17/photo-312.jpg.md5
./2016/05/19/photo-1234.jpg
./2016/05/19/photo-1234.jpg.md5
./2016/05/19/photo-5678.jpg
./2016/05/19/photo-5678.jpg.md5


Because that would simplify the script a bit.

Is it really important to print only the MD5 digest without trailing newline?
That would simplify the script a bit more.
And that would get rid of the -q flag which is only supported by BSD's  md5 tool, and not by GNU's md5sum.
With this change, the script would be usable in Linux by defining md5 as an alias to md5sum.

Actually, it would be great to install GNU's md5sum (md5sha1sum package in Brew and MacPorts), because it has a -c flag to verify the file easily. For example, you would be able to verify the checksum of all files with:

find . -name '*.md5' -execdir md5sum -c {} \;


To create the files:

find . -type f -name "*.jpg" -execdir sh -c 'md5sum "{}" &gt; "{}".md5' \;


Note that -execdir is necessary instead of -exec, so that the filenames don't have the directory part. Otherwise the .md5 files would contain the full path of files, and the md5sum -c verification would only work if invoked from the same relative path from where the digest file was created.

Use sh if good enough

The Bash script in -exec doesn't do anything Bash specific, so you could replace bash with sh.

Redundant "%s" in printf

Instead of printf "%s" something you could simply write printf something.