In your first example lets assume that $_GET['id'] was properly validated and tested to be a legitimate image filename, and another test to verify that the file exists, you could use the GD library.
Instead of the "file_get_contents()" line, use GD's methods: (search GD at php.net)
header("Content-type: image/jpeg");
// test that GET is set and add the path or set image path/name to a default image named "no-image.jpg"
$img = isset($_GET['img']) ? 'images/'.$_GET['img'] : 'images/no-image.jpg';
// good idea to test file existence
is_file($img) or die();
// make gd image object
$requested_image = imagecreatefromjpeg($img);
// stream out the image
imagejpeg($requested_image);
// do your chores and eat your vegetables
imagedestroy($requested_image);
Might even test file name extensions which I didn't do in the example, NEVER TRUST DATA BEING SENT TO YOUR SCRIPTS, even if you *think* your other scripts are the only ones that should be making requests to these scripts, ALWAYS VALIDATE EVERYTHING!
I don't know if there are better libraries for image handling in PHP, but the GD library is the only one I am familiar with and it has worked very well for me.
I am only taking into consideration your first example where you are sending the image file name to the php script that will stream the image to the browser.