Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8096707
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 5, 20262026-06-05T21:32:05+00:00 2026-06-05T21:32:05+00:00

I’ve used this code for a while now for a few sites I’ve built

  • 0

I’ve used this code for a while now for a few sites I’ve built which is great for galleries but it uses up a lot of memory and I keep getting memory allocation errors within the error log. Is there anything that can be changed to make this script better?

<?php
// Smart Image Resizer 1.4.1
// Resizes images, intelligently sharpens, crops based on width:height ratios, color fills
// transparent GIFs and PNGs, and caches variations for optimal performance

// Created by: Joe Lencioni (http://shiftingpixel.com)
// Date: August 6, 2008
// Based on: http://veryraw.com/history/2005/03/image-resizing-with-php/

/////////////////////
// LICENSE
/////////////////////

// I love to hear when my work is being used, so if you decide to use this, feel encouraged
// to send me an email. Smart Image Resizer is released under a Creative Commons
// Attribution-Share Alike 3.0 United States license
// (http://creativecommons.org/licenses/by-sa/3.0/us/). All I ask is that you include a link
// back to Shifting Pixel (either this page or shiftingpixel.com), but don’t worry about
// including a big link on each page if you don’t want to–one will do just nicely. Feel
// free to contact me to discuss any specifics (joe@shiftingpixel.com).

/////////////////////
// REQUIREMENTS
/////////////////////

// PHP and GD

/////////////////////
// PARAMETERS
/////////////////////

// Parameters need to be passed in through the URL's query string:
// image        absolute path of local image starting with "/" (e.g. /images/toast.jpg)
// width        maximum width of final image in pixels (e.g. 700)
// height       maximum height of final image in pixels (e.g. 700)
// color        (optional) background hex color for filling transparent PNGs (e.g. 900 or 16a942)
// cropratio    (optional) ratio of width to height to crop final image (e.g. 1:1 or 3:2)
// nocache      (optional) does not read image from the cache
// quality      (optional, 0-100, default: 90) quality of output image

/////////////////////
// EXAMPLES
/////////////////////

// Resizing a JPEG:
// <img src="/image.php/image-name.jpg?width=100&amp;height=100&amp;image=/path/to/image.jpg" alt="Don't forget your alt text" />

// Resizing and cropping a JPEG into a square:
// <img src="/image.php/image-name.jpg?width=100&amp;height=100&amp;cropratio=1:1&amp;image=/path/to/image.jpg" alt="Don't forget your alt text" />

// Matting a PNG with #990000:
// <img src="/image.php/image-name.png?color=900&amp;image=/path/to/image.png" alt="Don't forget your alt text" />

/////////////////////
// CODE STARTS HERE
/////////////////////

if (!isset($_GET['image']))
{
    header('HTTP/1.1 400 Bad Request');
    echo 'Error: no image was specified';
    exit();
}

define('MEMORY_TO_ALLOCATE',    '100M');
define('DEFAULT_QUALITY',       90);
define('CURRENT_DIR',           dirname(__FILE__));
define('CACHE_DIR_NAME',        '/imagecache/');
define('CACHE_DIR',             CURRENT_DIR . CACHE_DIR_NAME);
define('DOCUMENT_ROOT',         $_SERVER['DOCUMENT_ROOT']);

// Images must be local files, so for convenience we strip the domain if it's there
$image          = preg_replace('/^(s?f|ht)tps?:\/\/[^\/]+/i', '', (string) $_GET['image']);

// For security, directories cannot contain ':', images cannot contain '..' or '<', and
// images must start with '/'
if ($image{0} != '/' || strpos(dirname($image), ':') || preg_match('/(\.\.|<|>)/', $image))
{
    header('HTTP/1.1 400 Bad Request');
    echo 'Error: malformed image path. Image paths must begin with \'/\'';
    exit();
}

// If the image doesn't exist, or we haven't been told what it is, there's nothing
// that we can do
if (!$image)
{
    header('HTTP/1.1 400 Bad Request');
    echo 'Error: no image was specified';
    exit();
}

// Strip the possible trailing slash off the document root
$docRoot    = preg_replace('/\/$/', '', DOCUMENT_ROOT);

if (!file_exists($docRoot . $image))
{
    header('HTTP/1.1 404 Not Found');
    echo 'Error: image does not exist: ' . $docRoot . $image;
    exit();
}

// Get the size and MIME type of the requested image
$size   = GetImageSize($docRoot . $image);
$mime   = $size['mime'];

// Make sure that the requested file is actually an image
if (substr($mime, 0, 6) != 'image/')
{
    header('HTTP/1.1 400 Bad Request');
    echo 'Error: requested file is not an accepted type: ' . $docRoot . $image;
    exit();
}

$width          = $size[0];
$height         = $size[1];

$maxWidth       = (isset($_GET['width'])) ? (int) $_GET['width'] : 0;
$maxHeight      = (isset($_GET['height'])) ? (int) $_GET['height'] : 0;

if (isset($_GET['color']))
    $color      = preg_replace('/[^0-9a-fA-F]/', '', (string) $_GET['color']);
else
    $color      = FALSE;

// If either a max width or max height are not specified, we default to something
// large so the unspecified dimension isn't a constraint on our resized image.
// If neither are specified but the color is, we aren't going to be resizing at
// all, just coloring.
if (!$maxWidth && $maxHeight)
{
    $maxWidth   = 99999999999999;
}
elseif ($maxWidth && !$maxHeight)
{
    $maxHeight  = 99999999999999;
}
elseif ($color && !$maxWidth && !$maxHeight)
{
    $maxWidth   = $width;
    $maxHeight  = $height;
}

// If we don't have a max width or max height, OR the image is smaller than both
// we do not want to resize it, so we simply output the original image and exit
if ((!$maxWidth && !$maxHeight) || (!$color && $maxWidth >= $width && $maxHeight >= $height))
{
    $data   = file_get_contents($docRoot . '/' . $image);

    $lastModifiedString = gmdate('D, d M Y H:i:s', filemtime($docRoot . '/' . $image)) . ' GMT';
    $etag               = md5($data);

    doConditionalGet($etag, $lastModifiedString);

    header("Content-type: $mime");
    header('Content-Length: ' . strlen($data));
    echo $data;
    exit();
}

// Ratio cropping
$offsetX    = 0;
$offsetY    = 0;

if (isset($_GET['cropratio']))
{
    $cropRatio      = explode(':', (string) $_GET['cropratio']);
    if (count($cropRatio) == 2)
    {
        $ratioComputed      = $width / $height;
        $cropRatioComputed  = (float) $cropRatio[0] / (float) $cropRatio[1];

        if ($ratioComputed < $cropRatioComputed)
        { // Image is too tall so we will crop the top and bottom
            $origHeight = $height;
            $height     = $width / $cropRatioComputed;
            $offsetY    = ($origHeight - $height) / 2;
        }
        else if ($ratioComputed > $cropRatioComputed)
        { // Image is too wide so we will crop off the left and right sides
            $origWidth  = $width;
            $width      = $height * $cropRatioComputed;
            $offsetX    = ($origWidth - $width) / 2;
        }
    }
}

// Setting up the ratios needed for resizing. We will compare these below to determine how to
// resize the image (based on height or based on width)
$xRatio     = $maxWidth / $width;
$yRatio     = $maxHeight / $height;

if ($xRatio * $height < $maxHeight)
{ // Resize the image based on width
    $tnHeight   = ceil($xRatio * $height);
    $tnWidth    = $maxWidth;
}
else // Resize the image based on height
{
    $tnWidth    = ceil($yRatio * $width);
    $tnHeight   = $maxHeight;
}

// Determine the quality of the output image
$quality    = (isset($_GET['quality'])) ? (int) $_GET['quality'] : DEFAULT_QUALITY;

// Before we actually do any crazy resizing of the image, we want to make sure that we
// haven't already done this one at these dimensions. To the cache!
// Note, cache must be world-readable

// We store our cached image filenames as a hash of the dimensions and the original filename
$resizedImageSource     = $tnWidth . 'x' . $tnHeight . 'x' . $quality;
if ($color)
    $resizedImageSource .= 'x' . $color;
if (isset($_GET['cropratio']))
    $resizedImageSource .= 'x' . (string) $_GET['cropratio'];
$resizedImageSource     .= '-' . $image;

$resizedImage   = md5($resizedImageSource);

$resized        = CACHE_DIR . $resizedImage;

// Check the modified times of the cached file and the original file.
// If the original file is older than the cached file, then we simply serve up the cached file
if (!isset($_GET['nocache']) && file_exists($resized))
{
    $imageModified  = filemtime($docRoot . $image);
    $thumbModified  = filemtime($resized);

    if($imageModified < $thumbModified) {
        $data   = file_get_contents($resized);

        $lastModifiedString = gmdate('D, d M Y H:i:s', $thumbModified) . ' GMT';
        $etag               = md5($data);

        doConditionalGet($etag, $lastModifiedString);

        header("Content-type: $mime");
        header('Content-Length: ' . strlen($data));
        echo $data;
        exit();
    }
}

// We don't want to run out of memory
ini_set('memory_limit', MEMORY_TO_ALLOCATE);

// Set up a blank canvas for our resized image (destination)
$dst    = imagecreatetruecolor($tnWidth, $tnHeight);

// Set up the appropriate image handling functions based on the original image's mime type
switch ($size['mime'])
{
    case 'image/gif':
        // We will be converting GIFs to PNGs to avoid transparency issues when resizing GIFs
        // This is maybe not the ideal solution, but IE6 can suck it
        $creationFunction   = 'ImageCreateFromGif';
        $outputFunction     = 'ImagePng';
        $mime               = 'image/png'; // We need to convert GIFs to PNGs
        $doSharpen          = FALSE;
        $quality            = round(10 - ($quality / 10)); // We are converting the GIF to a PNG and PNG needs a compression level of 0 (no compression) through 9
    break;

    case 'image/x-png':
    case 'image/png':
        $creationFunction   = 'ImageCreateFromPng';
        $outputFunction     = 'ImagePng';
        $doSharpen          = FALSE;
        $quality            = round(10 - ($quality / 10)); // PNG needs a compression level of 0 (no compression) through 9
    break;

    default:
        $creationFunction   = 'ImageCreateFromJpeg';
        $outputFunction     = 'ImageJpeg';
        $doSharpen          = TRUE;
    break;
}

// Read in the original image
$src    = $creationFunction($docRoot . $image);

if (in_array($size['mime'], array('image/gif', 'image/png')))
{
    if (!$color)
    {
        // If this is a GIF or a PNG, we need to set up transparency
        imagealphablending($dst, false);
        imagesavealpha($dst, true);
    }
    else
    {
        // Fill the background with the specified color for matting purposes
        if ($color[0] == '#')
            $color = substr($color, 1);

        $background = FALSE;

        if (strlen($color) == 6)
            $background = imagecolorallocate($dst, hexdec($color[0].$color[1]), hexdec($color[2].$color[3]), hexdec($color[4].$color[5]));
        else if (strlen($color) == 3)
            $background = imagecolorallocate($dst, hexdec($color[0].$color[0]), hexdec($color[1].$color[1]), hexdec($color[2].$color[2]));
        if ($background)
            imagefill($dst, 0, 0, $background);
    }
}

// Resample the original image into the resized canvas we set up earlier
ImageCopyResampled($dst, $src, 0, 0, $offsetX, $offsetY, $tnWidth, $tnHeight, $width, $height);

if ($doSharpen)
{
    // Sharpen the image based on two things:
    //  (1) the difference between the original size and the final size
    //  (2) the final size
    $sharpness  = findSharp($width, $tnWidth);

    $sharpenMatrix  = array(
        array(-1, -2, -1),
        array(-2, $sharpness + 12, -2),
        array(-1, -2, -1)
    );
    $divisor        = $sharpness;
    $offset         = 0;
    imageconvolution($dst, $sharpenMatrix, $divisor, $offset);
}

// Make sure the cache exists. If it doesn't, then create it
if (!file_exists(CACHE_DIR))
    mkdir(CACHE_DIR, 0755);

// Make sure we can read and write the cache directory
if (!is_readable(CACHE_DIR))
{
    header('HTTP/1.1 500 Internal Server Error');
    echo 'Error: the cache directory is not readable';
    exit();
}
else if (!is_writable(CACHE_DIR))
{
    header('HTTP/1.1 500 Internal Server Error');
    echo 'Error: the cache directory is not writable';
    exit();
}

// Write the resized image to the cache
$outputFunction($dst, $resized, $quality);

// Put the data of the resized image into a variable
ob_start();
$outputFunction($dst, null, $quality);
$data   = ob_get_contents();
ob_end_clean();

// Clean up the memory
ImageDestroy($src);
ImageDestroy($dst);

// See if the browser already has the image
$lastModifiedString = gmdate('D, d M Y H:i:s', filemtime($resized)) . ' GMT';
$etag               = md5($data);

doConditionalGet($etag, $lastModifiedString);

// Send the image to the browser with some delicious headers
header("Content-type: $mime");
header('Content-Length: ' . strlen($data));
echo $data;

function findSharp($orig, $final) // function from Ryan Rud (http://adryrun.com)
{
    $final  = $final * (750.0 / $orig);
    $a      = 52;
    $b      = -0.27810650887573124;
    $c      = .00047337278106508946;

    $result = $a + $b * $final + $c * $final * $final;

    return max(round($result), 0);
} // findSharp()

function doConditionalGet($etag, $lastModified)
{
    header("Last-Modified: $lastModified");
    header("ETag: \"{$etag}\"");

    $if_none_match = isset($_SERVER['HTTP_IF_NONE_MATCH']) ?
        stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) : 
        false;

    $if_modified_since = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ?
        stripslashes($_SERVER['HTTP_IF_MODIFIED_SINCE']) :
        false;

    if (!$if_modified_since && !$if_none_match)
        return;

    if ($if_none_match && $if_none_match != $etag && $if_none_match != '"' . $etag . '"')
        return; // etag is there but doesn't match

    if ($if_modified_since && $if_modified_since != $lastModified)
        return; // if-modified-since is there but doesn't match

    // Nothing has changed since their last request - serve a 304 and exit
    header('HTTP/1.1 304 Not Modified');
    exit();
} // doConditionalGet()

// old pond
// a frog jumps
// the sound of water

// —Matsuo Basho
?>
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-05T21:32:06+00:00Added an answer on June 5, 2026 at 9:32 pm

    If your server has imagemagick installed, it can be done like this:

    exec("convert $filename -quality 60 -resize x100 -gravity center -crop 100x100+0+0 +repage $newfilename");
    

    else:

    Resize & Crop with GD2

    Hope it helps

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I used javascript for loading a picture on my website depending on which small
I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
this is what i have right now Drawing an RSS feed into the php,
I have this code to decode numeric html entities to the UTF8 equivalent character.
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
I have this code: - (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock { NSString *someString = [[NSString
link Im having trouble converting the html entites into html characters, (&# 8217;) i
I want to count how many characters a certain string has in PHP, but
For some reason, after submitting a string like this Jack’s Spindle from a text
I am trying to understand how to use SyndicationItem to display feed which is

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.