Well, to draw out your example, you could use bits of the id to provide the directory name. Will you be storing billions of images? If not, a simple integer ID would be enough. That can give nine decimal digits. With a thousand files per directory, there's an obvious triple-depth structure there by taking the ID number in groups of three digits.
I'd actually start from the right and work towards the left: that will keep the files uniformly distributed, instead of having one directory max out before starting another.
// ensure we have nine digits.
$filename = str_pad($id_number, 9, '0', STR_PAD_LEFT);
$filename = strrev($filename);
$filename = substr($filename,0,3) . '/' . substr($filename,3,3) . '/' . $id_number . '.jpg';
Smart would be to contruct directories as and when needed. When saving image # 64322 (which maps to 223/460/64322.jpg), you'd first look to see if directory 223 exists. If not, create it. Then go into directory 223. If 460 doesn't exist, create it, and then save 64322.jpg in there. That will save creating over a million directories in advance. Image #1 will be in 100/000/1.jpg, Image #2 will be in 200/000/2.jpg, and so on.
Fixing the directory structure in advance would be better than rearranging files and directories whenever some threshold is crossed. Even so, if you do manage to have so many filenames that you need ten digits to accommodate them all, you can easily go from 233/460/64322.jpg to 233/460/000/64322.jpg and thus also have room for 233/460/000/1000064332.jpg.
Hiding the image-file retrieval behind a script (so that the src= attribute refers to a PHP script) will hide these shenanigans from the user.