Following on from NogDog's suggestion: if the images are stored outside the site root then they won't be accessible by any URL except that of the page that is supposed to be serving them; that works for the image itself as well as the page it's displayed in.
Configure the web server so that the URL for the image looks like the URL for an image instead of a script. Say the request sent by the client is for
http://www.example.com/gallery/honestly-not-porn.jpeg. The server rewrites that to
gallery-script.php would do all the suggested checks for session/cookie values, before sending suitable response headers (including but not limited to cache/cookie control,
Content-length:<?=filesize($image_path);?>) and then dump the image data into the response with
An illegitimate request could get a 404 or 403 response or some fallback image depending on what you think would be appropriate. It should go without saying that the name given in the URL need have nothing to do with the name of the file on disk, provided you have a reliable mapping between them. Indeed, if you have sessions then you can store that mapping in the session data and generate it afresh (with new URLs) for each session. That is, if you don't mind users seeing different URLs for the same images on different visits.