you can break caches by appending a ?[somevar]=[random string] after the image tag. They determine freshness by url (is it the same?) then, if the url is the same, by checking last modified date, E-Tag, etc.
You can also serve them up using php to load the image and pass it through, and adding some custom headers before sending the image and flushing the buffer:
Last-Modified: [current time/date] -for cache server
E-Tag: [random string] -for cache server
Expires: [yesterday] -for cache server
Cache-Control: must-revalidate, max-age=1 -for cache server
Pragma: no-cache, NoCache(for internet exploder) -for browser, most caches ignore this
caches are not all the same so it's good to hedge your bets 8)
These combined will probably break any cache unless the cache actually compares the files, which would be intense in a large ISP.
http://www.mnot.net/cache_docs/#PRAGMA
Is a tutorial that explains how to get all of your content cached. For spotlight images or banner serving you basically want to do the exact opposite of what this page tells you ROFL.
A more internet friendly way to accomplish is to go ahead and let the cache servers cache the images, since when an image is hit, and it's cached, a request still reaches the server, it'll show a 304 response for these and record the request URI so you can match on the image. The difference is usually less than 100 bytes are sent over the wire in such an exchange so it's a lot more efficient for your server. The connection time for the exchange is also cut. This means less memory and bandwidth get used for 304s.
If you are watching the log for the site you can get the data as sure as if serving it from a script, and make your scalability better.
I only know all of this because I wrote a 3rd party ad server once which audited doubleclick for our clients.
-r