phpgdfopenfile-get-contentsimagecreatefrompng

Faster way to read and output images in browser with PHP


I am reading images from minimum of 1x1 pixel to maximum of 1600x1600 pixels. I have written three PHP methods and are working perfectly.

// using FGC
function output_fgc($filename)
{
    header("Content-Type: image/png");
    echo file_get_contents($filename);
}

// using fopen
function output_fp($filename)
{
    $handle = fopen($filename, 'rb');

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

    fpassthru($handle);
}

// using GD
function output_gd($filename)
{
    $im = imagecreatefrompng($filename);

    header('Content-Type: image/png');

    imagepng($im);
    imagedestroy($im);
}

It seems performance is same for all methods. Just want to know which uses more server resources? Are there any better methods than this? Thanks in advance.


Solution

  • When user request 200x100 Pixel placeholder image, first time create with GD, Save and Output, next time if same size is requested, I am just reading the saved file and outputting to the browser instead creating new again.

    If you can use Apache's mod_rewrite module, there's an even more efficient approach that doesn't need PHP at all once an image is created. See Create resized image cache but prevent abuse

    Stolen from there:

    HTML:

    <img src="images/cache/200x150-picture_001.jpg" />
    

    .htaccess code:

    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ images/image.php?f=$1 [L]
    

    This technique looks whether an image of the correct size/file name exists in the "cache" folder, and only if it doesn't, it calls your PHP script. Your script would have to parse the size info (like 200x100 as you say), resize, and output the image. The next time somebody requests the image, Apache will serve it statically, saving resources in the process.

    The only downside to this is that the PHP script will be called only once, so if the original image changes, the change will never propagate to the resized version. You may need to occasionally wipe all resized images to prevent this, or delete all resized images if the original changes.

    Also be sure to send caching info when outputting the image with PHP. See e.g. How to use HTTP cache headers with PHP