3

I have some images that are pulled from a server and $imgUrl holds the path of the image.

Right now I use <img src="<?php echo $imgUrl ?>" width="100" height="200"/> or CSS to scale down the image, but I want to do it in PHP so that I will serve already scaled images to the DOM

Any ideas?

Thanks

Teun Zengerink
  • 4,277
  • 5
  • 30
  • 32
Patrioticcow
  • 26,422
  • 75
  • 217
  • 337
  • 2
    easiest to use a tool like phpthumb: http://phpthumb.sourceforge.net/ – evan Jan 31 '12 at 18:20
  • Ensure you do this *before* pages are requested rather than on-demand, as on-demand makes the pages execute slower, thereby making your site slower. – Incognito Jan 31 '12 at 18:22
  • @evan If you had answered I would upvote. Unless OP really wants to write his/her own image manipulation library, which I would think would be painful in php. – Tim Jan 31 '12 at 18:22
  • @Tim It's actually not as hard as it sounds to write something that will suit his needs (not a full library, just a resizer). – Crashspeeder Jan 31 '12 at 18:28
  • yes, Tim is wright, i was asking for code for a resizer. i know about all these libraries, but i guess GD is my option – Patrioticcow Jan 31 '12 at 18:33
  • @Crashspeeder Ahh. I have never tried, so I will take you at your word. I had a very blurry sketch in my mind of sampling and interpolating pixels, reading binary streams into huge multidimensional arrays, supporting various compressed image formats, etc. – Tim Jan 31 '12 at 18:34
  • @Tim gd handles all of that for you. You just set some parameters for your image and it does the rest. I'm sure there are also libraries out there that implement gd to make the work even easier. – Crashspeeder Jan 31 '12 at 18:36
  • @Crashspeeder I see what you did there. Sorry, I misunderstood your first comment. – Tim Jan 31 '12 at 18:38

4 Answers4

6

This solution will cause the thumb to be created when it is requested for the first time. All future requests will fetch the already created thumb. It is using ImageMagick:

HTML:

<img src="script.php?img=example" />

PHP (script.php):

$width  = 140;
$height = 80;
$image  = $_GET['img'];
$ext    = 'png';

// Check if file exists
if ( ! file_exists('/path/to/the/'.$image.'.'.$ext))
{
    die('Unable to process the requested file.');
}

// Check if a thumb already exists, otherwise create a thumb
if (file_exists('/path/to/the/'.$image.'_thumb.'.$ext))
{
    $img = new imagick('/path/to/the/'.$image.'_thumb.'.$ext);
}
else
{
    $img = new imagick('/path/to/the/'.$image.'.'.$ext);
    $img->setImageFormat($ext);
    $img->scaleImage($width, 0);
    $img->cropImage($width, $height, 0, 0);
    $img->writeImage('/path/to/the/'.$image.'_thumb.'.$ext);
}

// Return as an image
header('Content-Type: image/'.$ext);
echo $img;
Teun Zengerink
  • 4,277
  • 5
  • 30
  • 32
2

You should create a smaller version and save it to a folder. Then you don't need to rezise them on every request (it's memory intensive). Use Gd or ImageMagick for resize.

Example with GD

phil-opp
  • 343
  • 1
  • 3
  • 11
1

Here is what I am using atm. Feel free to extract you needs:

 Usage:
 <CLASS>::scale_image($dir.$name, 1024, 768, $dir.'thumb_'.$name);

 /**
 * Most simple way to get File Extension
 * @param string $path Local path to File
 * @return string Extension in lower case
 */
public static function extension($path){
    return strtolower(pathinfo($path, PATHINFO_EXTENSION));
}
/**
 * Rename Filename for more secure usage
 * @param string $name filename
 * @return string more secure filename
 */
public static function secure_name($name){
    return urlencode(preg_replace('/[^a-z0-9 \-_\.]/i', '_', strtolower($name)));
}
/**
 * Scale Image without ratio changes
 * @param int $sw source width of orig image
 * @param int $sh source height of orig image
 * @param int $tw max target width
 * @param int $th max target height
 * @return array list($width, $height)
 */
public static function scale($sw, $sh, $tw, $th){
    if ($sw > $tw && $sw/$tw > $sh/$th) {
        $tw = $sw * ($tw / $sw); 
        $th = $sh * ($tw / $sw); 
    }else if ($sh > $th) { 
        $tw = $sw * ($th / $sh); 
        $th = $sh * ($th / $sh); 
    }else{
        $th = $sh;
        $tw = $sw;
    }
    return array(round($tw), round($th));
}
/**
 * Scale Image 
 * @param string $sPath
 * @param int $width max width
 * @param int $height max height
 * @param string $tPath Optional Path for Thumbnail
 * @param int $thumbScale Scale ratio for optional Thumbnail (Width and Height / $thumbScale)
 * @return void
 */
public static function scale_image($sPath, $width, $height, $tPath = NULL, $thumbScale = 10){
    if(!function_exists('imagecreatetruecolor')){
        return;
    }
    $ext = strtolower(self::extension($sPath));
    if($ext == 'jpg' or $ext == 'jpeg'){
        $src = imagecreatefromjpeg($sPath);
    }elseif($ext == 'png'){
        $src = imagecreatefrompng($sPath);
    }elseif($ext == 'gif'){
         $src = imagecreatefromgif($sPath);
    }else{
        return;
    }
    list($sw, $sh) = getimagesize($sPath);
    list($tw, $th) = File::scale($sw, $sh, $width, $height);
    $trg = imagecreatetruecolor($tw, $th);
    imagecopyresampled($trg, $src, 0, 0, 0, 0, $tw, $th, $sw, $sh);
    imagejpeg($trg, $sPath, 90);
    if($tPath){
        $tw = (int)$tw / $thumbScale;
        $th = (int)$th / $thumbScale;
        $trg = imagecreatetruecolor($tw, $th);
        imagecopyresampled($trg, $src, 0, 0, 0, 0, $tw, $th, $sw, $sh);
        imagejpeg($trg, $tPath, 90);
    }
}
Stefan Brinkmann
  • 965
  • 8
  • 11
1

Be aware that doing this in PHP will mean a memory intensive process either every time the image is accessed (if done on the fly) or when the image is saved (which means you'll be using more storage to save the converted images). If you're still sure this is something you need/want then look into using GD. See this answer for an idea or how to do this: Image GD resize to 100px while keep the ratio

Community
  • 1
  • 1
Crashspeeder
  • 4,291
  • 2
  • 16
  • 21