Is it possible to resize dynamic images on the fly

I use the following 3rd party script to resize and cache images from a URL. It works as expected on URL’s that contain static images. I now find that I need to be able to manipulate dynamically generated images from image URL’s like: http://www.image-online.com/ShowImage.asp?2Id=c&Id=PA1&ImgId=030

Is it actually possible to resize dynamic images on the fly, or at all for that matter?

<?php

//////////////////////////////////////////////////////  THIS IS THE FUNCTION_RESIZE.PHP FILE ///////////////////////////////////////////////////////////////////////////////////////

/*
function by Wes Edling .. http://joedesigns.com
feel free to use this in any project, i just ask for a credit in the source code.
a link back to my site would be nice too.
*/

function resize($imagePath,$opts=null){

    # start configuration
    
    $cacheFolder = './cache/'; # path to your cache folder, must be writeable by web server
    $remoteFolder = $cacheFolder.'remote/'; # path to the folder you wish to download remote images into
    $quality = 90; # image quality to use for ImageMagick (0 - 100)
    
    $cache_http_minutes = 20;     # cache downloaded http images 20 minutes

    $path_to_convert = '/usr/bin/convert'; 
    
    ## you shouldn't need to configure anything else beyond this point

    $purl = parse_url($imagePath);
    $finfo = pathinfo($imagePath);
    $ext = $finfo['extension'];

    # check for remote image..
    if(isset($purl['scheme']) && $purl['scheme'] == 'http'):
        # grab the image, and cache it so we have something to work with..
        list($filename) = explode('?',$finfo['basename']);
        $local_filepath = $remoteFolder.$filename;
        $download_image = true;
        if(file_exists($local_filepath)):
            if(filemtime($local_filepath) < strtotime('+'.$cache_http_minutes.' minutes')):
                $download_image = false;
            endif;
        endif;
        if($download_image == true):
            $img = file_get_contents($imagePath);
            file_put_contents($local_filepath,$img);
        endif;
        $imagePath = $local_filepath;
    endif;

    if(file_exists($imagePath) == false):
        $imagePath = $_SERVER['DOCUMENT_ROOT'].$imagePath;
        if(file_exists($imagePath) == false):
            return 'image not found';
        endif;
    endif;

    if(isset($opts['w'])): $w = $opts['w']; endif;
    if(isset($opts['h'])): $h = $opts['h']; endif;

    $filename = md5_file($imagePath);

    if(!empty($w) and !empty($h)):
        $newPath = $cacheFolder.$filename.'_w'.$w.'_h'.$h.(isset($opts['crop']) && $opts['crop'] == true ? "_cp" : "").(isset($opts['scale']) && $opts['scale'] == true ? "_sc" : "").'.'.$ext;
    elseif(!empty($w)):
        $newPath = $cacheFolder.$filename.'_w'.$w.'.'.$ext;    
    elseif(!empty($h)):
        $newPath = $cacheFolder.$filename.'_h'.$h.'.'.$ext;
    else:
        return false;
    endif;

    $create = true;

    if(file_exists($newPath) == true):
        $create = false;
        $origFileTime = date("YmdHis",filemtime($imagePath));
        $newFileTime = date("YmdHis",filemtime($newPath));
        if($newFileTime < $origFileTime):
            $create = true;
        endif;
    endif;

    if($create == true):
        if(!empty($w) and !empty($h)):

            list($width,$height) = getimagesize($imagePath);
            $resize = $w;
        
            if($width > $height):
                $resize = $w;
                if(isset($opts['crop']) && $opts['crop'] == true):
                    $resize = "x".$h;                
                endif;
            else:
                $resize = "x".$h;
                if(isset($opts['crop']) && $opts['crop'] == true):
                    $resize = $w;
                endif;
            endif;

            if(isset($opts['scale']) && $opts['scale'] == true):
                $cmd = $path_to_convert." ".$imagePath." -resize ".$resize." -quality ".$quality." ".$newPath;
            else:
                $cmd = $path_to_convert." ".$imagePath." -resize ".$resize." -size ".$w."x".$h." xc:".(isset($opts['canvas-color'])?$opts['canvas-color']:"transparent")." +swap -gravity center -composite -quality ".$quality." ".$newPath;
            endif;
                        
        else:
            $cmd = $path_to_convert." ".$imagePath." -thumbnail ".(!empty($h) ? 'x':'').$w."".(isset($opts['maxOnly']) && $opts['maxOnly'] == true ? "\\>" : "")." -quality ".$quality." ".$newPath;
        endif;

        $c = exec($cmd);
        
    endif;

    # return cache file path
    return str_replace($_SERVER['DOCUMENT_ROOT'],'',$newPath);
    
}

////////////////////////////////////////////////////////////////  THIS IS THE EXAMPLE.PHP FILE //////////////////////////////////////////////////////////////////////////////////////////////////////////

<?php
# include the function here
include 'function.resize.php';

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
    <title>PHP Image Resize - Example</title>
    <style>
        body { 
            background: #ffffff; 
            color: #121212; 
            font-family: lucida grande; 
            text-align: center; 
        }
        h1 { font-size: 15px; text-align: center; }
        #main { margin: auto; width: 600px; text-align: left; }
        .block { margin: 20px; background: #fafafa; padding: 20px; text-align: center; border: 1px solid #cacaca; }
        pre { text-align: left; background: #010101; padding: 10px; font-size: 11px; }
        pre code { text-align: left; color: #ffffff; }
        .block p { color: #343434; font-size: 12px; }
    </style>
</head>

<body>

<div id='main'>

    <h1>PHP Image Resizer</h1>


    <div class='block'>
        <?php $settings = array('w'=>150,'h'=>150,'crop'=>true); ?>
        <div><img src='<?=resize('http://www.image-online.com/admin.jpg',$settings)?>' border='0' /></div>
        <p>Image cropped &amp; resized by width and height from a remote location.</p>
        <div><pre><code>src: http://www.image-online.com/admin.jpg<?php echo "\
\
"; print_r($settings)?></code></pre></div>
    </div>

</div>

</body>
</html>

?>

Thanks for looking

Colin

Simple test.


<?php
$dynamicurl = "http://some.address.here";
$im = createimagefromjpeg($dynamicurl);
header("Content-type: image/jpeg");
imagejpeg($im);
?>

If your page spits out an image, then the image can be loaded dynamically by GD, and can be manipulated by it.

Fatal error: Call to undefined function createimagefromjpeg() in on LINE 13

I pressume there could be a problem if you do not know the image type?

Fatal error: Call to undefined function createimagefromjpeg() in on LINE 13

With Starlions test code you should only have 4 lines!

An Imagemagick version to try:

<?php
$photo="http://www.image-online.com/ShowImage.asp?SecId=zc&Id=P1&ImgId=03073";

$cmd = "convert $photo -thumbnail 200x200 JPG:-";

header("Content-type: image/jpeg");
passthru($cmd, $retval);
?>  

You can use phpThumb for this purpose. You need to install phpThumb on your server. Afterwards, you must change its settings to allow resizing of remote images. Optionally, you can configure it to cache the resized versions of remote images as well (for performance). phpThumb can also be configured to perform some sanity checks, for example, not allow anyone but “my-website.com” to request resized images. Lastly, here is how you would use phpThumb on your website:


<img src="http://my-website.com/phpThumb.php?src=http%3A%2F%2Fother-website.com%2Fimage.php%3Fa%3D1%26b%3D2&w=200&h=200">
<!-- the url-encoded dynamic image url ----------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -->

Thanks for the replies.

Rubble
your example just returns the url of the page as an image ie: http://www.my-site.com/test.php. If I view the page source it is in fact a JPEG image but “The image http://www.my-site.com/test.php cannot be displayed because it contains errors”

Webdesignhouston
I did look to phpThumb but sadly it is not installed on the shared server that this site is hosted on. I was looking for other options before asking my host if it could be installed.

Colin

You can download phpThumb yourself, it does not need to be ‘installed’, you can simply include phpThumb in your code.

Here is a quick and dirty, nothing fancy working resizer that I use:

save as image.php


<?php
/* usage
http://mysite.com/image.php?im=path-to-image&ms=400

**/
$im      = $_GET['im'];
$maxsize = $_GET['ms'];
            

// The file
$filename = $im;

// Set a maximum height and width
$width  = $maxsize;
$height = $maxsize;

// Content type
header('Content-type: image/jpeg');

// Get new dimensions
list($width_orig, $height_orig) = getimagesize($filename);

if ($width && ($width_orig < $height_orig)) {
    $width = ($height / $height_orig) * $width_orig;
} else {
    $height = ($width / $width_orig) * $height_orig;
}

// Resample
$image_p = imagecreatetruecolor($width, $height);
$image   = imagecreatefromjpeg($filename);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);

// Output
imagejpeg($image_p);
imagedestroy($image);
imageDestroy($image_p);


?>

Proportionally resizes the image maintaining the aspect ratio.

Usage: http://mysite.com/image.php?im=path-to-image&ms=400
where ms is the maximum size (height or width) that you want.

Hi Spike

Thanks for the reply.

I have tried your “quick and dirty” method and it works to a point.

This will work: im=http://www.deepglamour.net/.a/6a00e553bc52568834010536e7b7ed970b-800wi&ms=200

This returns the url as an image: im=http://coloring-book-pages.com/showimage.asp?Cat=&ImageID=1555&ms=200

I have tried other random examples as well and the showimage.asp? in the url seems to break the script??

So I am guessing that this cannot be done because the image path is actually a webpage rather than a dynamic image, am I right?

The response headers show: Content-Type: image/jpeg, perhaps that could be useful.

C

Yes, it’s quite possible you’ll have to download the image first and save it on your server.

Alternatively, what you could do is something like the following (pseudo-code):


$img_string = file_get_contents("http://example.com/image.jpg");
$image = imagecreatefromstring($img_string);

That will download the image, then create a GD resource from it which you can resize.

Spike

Using your method IE (but not Firefox) returns these errors:

[I]<b>Warning</b>: getimagesize(http://ShowImage.asp?SecId=ml) [<a href=‘function.getimagesize’>function.getimagesize</a>]: could not make seekable - http://ShowImage.asp?SecId=ml in <b>/home/image.php</b> on line <b>23</b><br />
<br />
<b>Warning</b>: Division by zero in on line <b>28</b><br />
<br />
<b>Warning</b>: imagecreatetruecolor() [function.imagecreatetruecolor</a>]: Invalid image dimensions in <b>/home/image.php</b> on line <b>32</b><br />
<br />
<b>Warning</b>: imagecreatefromjpeg() [<a href=‘function.imagecreatefromjpeg’>function.imagecreatefromjpeg</a>]: Cannot read image data in <b>/image.php</b> on line <b>33</b><br />
<br />
<b>Warning</b>: imagecopyresampled(): supplied argument is not a valid Image resource in <b>/home/image.php</b> on line <b>34</b><br />
<br />
<b>Warning</b>: imagejpeg(): supplied argument is not a valid Image resource in <b>/home/image.php</b> on line <b>37</b><br />
<br />
<b>Warning</b>: imagedestroy(): supplied argument is not a valid Image resource in <b>/home/image.php</b> on line <b>38</b><br />
<br />
<b>Warning</b>: imagedestroy(): supplied argument is not a valid Image resource in <b>/home/image.php</b> on line <b>39</b><br />

[/I]Immerse

The option to download the images is not a path I wish to pursue. There are around 30,000 or more. imagecreatefromstring() does not work with the URL:
Data is not in a recognized format

C

Try this code:


<?php

$url = "http://www.sitepoint.com/forums/image.php?u=54806&dateline=1102411175";
$string = file_get_contents($url);
$gd = imagecreatefromstring($string);

var_dump($gd);

?>

It downloads your Sitepoint avatar into a string and then creates a GD resource from it.

It should output something like:


resource(4, gd)

If it does, it has successfully loaded the image.

Don’t forget you have to load the image into the $string variable before using imagecreatefromstring().

Do you have a URL for one of the images you want to work on?

Hi

Thanks for your time.

I am using this url for testing purposes: http://www-1.resales-online.com/live/ShowImage.asp?SecId=cwxmncsqllsqtea&Id=P1&ImgId=W1002259

Your code does indeed return the expected result so things are looking up at last.

Now I need some guidance to create my thumbnails from this???

C

Ok so I have figured this part out, I now have resized thumbnails :slight_smile:

Just need to get this into my page now.

C

<?php
$url = "http://www.someimage.asp?etcetc";
$string = file_get_contents($url);
// Resize to 145 X 133


    $src = imagecreatefromstring($string);
    $width = imagesx($src);
    $height = imagesy($src);
    $new_w = 145;
    $new_h = 133;
    


    $img = imagecreatetruecolor($new_w,$new_h);
    imagecopyresized($img,$src,0,0,0,0,$new_w,$new_h,$width,$height);
 

    header('Content-Type: image/jpeg');
    imagejpeg($img);
    imagedestroy($img);
?>