Output an Image in PHP

Output an Image in PHP

$file = '../image.jpg';
$type = 'image/jpeg';
header('Content-Type:'.$type);
header('Content-Length: ' . filesize($file));
readfile($file);

PHP: How to output image files?

What you need to do to output image files is in order:

PHP loads the image from the file, this is file_get_contents or otherwise fopen to open and access the file itself. If the file is a specific image file you can open the file with imagecreatefromjpeg() which will do just that, generate an image file from a JPEG source.

Then, once the file is loaded from anywhere on your filesystem, including directories outside of your web root, PHP can output the data caught in point 1, above, with some HTTP Headers and direct reference to the loaded image.

NOTE: this means that the sole output of this PHP file is the image,
so file.php === image.jpg in this case.

So a brief example:

image is stored in /home/images/image1.jpg

PHP file runs from /home/site/imagecall.php

PHP file says:

<?php
if (file_exists('/home/images/image1.jpg')){
$image = imagecreatefromjpeg('/home/images/image1.jpg');
if ($image){
header('Content-Type: image/jpeg');
imagejpeg($image);
imagedestroy($image);
}
else {
die("Image could not be loaded");
}
}

This is a starting point for you and by no means an absolute guide. Explore.

Useful references:

http://php.net/manual/en/function.imagecreatefromjpeg.php

http://php.net/manual/en/function.file-get-contents.php

output image in php page

Print the var $image with echo (and close the image tag with a frontslash at the end of the tag for correct html):

<img src= "<?php echo $image; ?>" style="width:304px;height:228px;" />

Other possible reasons the image is not displayed (after you print the image name out with echo):

  • the value of your var $image mismatched with the imagename.
  • the image is not stored in the same folder as the php document.
  • your image is saved in CMYK mode, and not in RGB.
  • the file permission of the image
  • configuration of the webserver (apache for ex.)

Output readfile image to HTML

The code you're using to output the image would be its own page, not just a function you call. For example, let's call it image.php:

<?php
$file = '../image.jpg';
$type = 'image/jpeg';
header('Content-Type:'.$type);
header('Content-Length: ' . filesize($file));
readfile($file);
?>

Then in your HTML you would reference image.php as though it were an image, since that's exactly what it outputs:

<img src="image.php" />

HTTP doesn't care about things like "file types", there are just headers and data. image.php returns an image header (Content-Type:image/jpeg) and image data, so as far as the browser is concerned it's an image "file".

How to output image and download using php

You can use imagejpeg() to output the image to the browser. (Docs)

// Set the content type header - in this case image/jpeg
header('Content-Type: image/jpeg');

// Output the image
imagejpeg($image);

When you leave out the second parameter of imagejpeg() or set it to null the image will be sent to the browser (in binary form).

To trigger the download in the browser, you need to set another header value:

header('Content-Disposition: attachment; filename="YourFilenameHere.jpg"');

This tells the browser, that it should download the file as YourFilenameHere.jpg.

Outputting image using php

You have two basic options: first, using an external image-loader/handler script (e.g. <img src="image.php?i=sunshine.jpg" />); second, base64-encoding the image data (e.g. <img src="data:image/png;base64, i26dfdXAd..." />). The second option will make your HTML bloat like there's no tomorrow. So let's simply look at the image.php handler approach.

How does the handler know what image to show? It'll need a query string, e.g. image.php?i=sunshine.jpg; or image.php?i=sunshine&x=jpg; or image.php?i=sunshine&x=jpg&s=600, if you wanted to load a particular size, and so on. You will have to use that format in your HTML source, there's no script that would automagically know what image to load. Then, it's "who" (you), not "what", that sends the parameters. You'll want to make sure that the variables are properly sanitized (as your sample handler is doing); like any user-modifiable input, they shouldn't be trusted, especially anywhere near filesystem operations (directory traversal, etc.). These variables will be available as $_GET['i'], $_GET['x'], etc. to your handler script.

If you feel like URL parameters are a hassle, or just look dirty, you could always rewrite URLs. Link an image as <img src="images/sunshine.jpg" />, and have a .htaccess rewrite rule in place in the /images/ folder (containing only your script) that passes all image requests to your handler script. See the "htaccess redirect all images to handler" Q/A for an example. You could also use this approach for handling down-scaled image versions, with source URLs like <img src="images/sunshine__600.jpg" /> mapped to a rewrite rule.

On the use of readfile() (the most memory-friendly way of blurting out large chunks of data), as long as you output the header('Content-type: image/jpeg'); (or other appropriate MIME header) before your readfile() call, it will work in the desired way. That is to say, browser won't know the difference between images served directly from the filesys by the webserver, or images served from outside the webroot with a handler. It's just data with an image HTTP header.


Edit: Bonus. Coded a minimalist safe-to-deploy file-handler.

<?php
/*
* Receive image call as: <img src="img.php?i=name.jpg" />
* Output matching image file from $basepath directory
*/

$basepath = '../images/'; // Path to image folder

$mimes = [ // Allowed image types:
'jpg' => 'image/jpeg',
'png' => 'image/png',
'gif' => 'image/gif',
'svg' => 'image/svg+xml',
];

!isset($_GET['i']) && die(); // Nothing to do here.

// Parse & Verify Extension
$ext = strtolower(pathinfo($_GET['i'], PATHINFO_EXTENSION));
!isset($mimes[$ext]) && die('Invalid filetype!'); // If MIME N/A: die!

// Parse & Sanitize Filename
$file = basename($_GET['i']);
$file = preg_replace('#[^[:alnum:] ._-]#', '', $file);

$filepath = realpath($basepath . $file);
$filepath === false && die('Invalid filename!'); // If image N/A: die!

// Output MIME header and image:
header('Content-Type:' . $mimes[$ext]);
readfile($filepath);
exit;

If you need to accommodate jpeg etc. variants, simply a) duplicate the MIME definitions in the $mimes array, or b) add an extension normalization routine. If you need to access images in subfolders, e.g. ?i=sun/shine.jpg, rework the filename parse/sanitize routine without basename. (Be sure you're safe from directory traversal!). Characters other than [:alnum:] ._-] are removed from the requested filename. Modify the regex as necessary.

Return a PHP page as an image

The PHP Manual has this example:

<?php
// open the file in a binary mode
$name = './img/ok.png';
$fp = fopen($name, 'rb');

// send the right headers
header("Content-Type: image/png");
header("Content-Length: " . filesize($name));

// dump the picture and stop the script
fpassthru($fp);
exit;
?>

The important points is that you must send a Content-Type header. Also, you must be careful not include any extra white space (like newlines) in your file before or after the <?php ... ?> tags.

As suggested in the comments, you can avoid the danger of extra white space at the end of your script by omitting the ?> tag:

<?php
$name = './img/ok.png';
$fp = fopen($name, 'rb');

header("Content-Type: image/png");
header("Content-Length: " . filesize($name));

fpassthru($fp);

You still need to carefully avoid white space at the top of the script. One particularly tricky form of white space is a UTF-8 BOM. To avoid that, make sure to save your script as "ANSI" (Notepad) or "ASCII" or "UTF-8 without signature" (Emacs) or similar.



Related Topics



Leave a reply



Submit