tags:

views:

25

answers:

4

I have this piece of code that calls a random image and sends it to another page. That page calls this script via an image link. What I am trying to figure out is how to make it specify an image width when the image is past my max width. I got this far then got completely lost.

 <?php

    $folder = '';

    $exts = 'jpg jpeg png gif';

    $files = array(); $i = -1; 
    if ('' == $folder) $folder = './';

    $handle = opendir($folder);
    $exts = explode(' ', $exts);
    while (false !== ($file = readdir($handle))) {
    foreach($exts as $ext) { 
    if (preg_match('/\.'.$ext.'$/i', $file, $test)) { 
    $files[] = $file; 
    ++$i;
    }
    }
    }
    closedir($handle);
    mt_srand((double)microtime()*1000000); 
    $rand = mt_rand(0, $i); 

    $image =($folder.$files[$rand]); 

    if (file_exists($image))
    {
      list($width) = getimagesize($image);
      $maxWidth = 150;
      if ($width > $maxWidth)
      {
        header('Location: '.$folder.$files[$rand]); // Voila!;
      }
      else
      {
        header('Location: '.$folder.$files[$rand]); // Voila!
      }
    }
    ?>
A: 

You can not specify that in the header. There are 2 ways to go about it.

1 : in the image tag, specify the width attribute, however this will force the smaller images to scale up as well, so probably not the best course of action.

2 : Resize the image on the fly with GD library and send the resultant image instead of the original.

Edit:

For resizing you may look into this very simple to use image resize class. http://www.white-hat-web-design.co.uk/articles/php-image-resizing.php

include('SimpleImage.php');
$image = new SimpleImage();
$image->load('picture.jpg');
$image->resizeToWidth($maxWidth);
$image->save('picture2.jpg');

Now you can redirect to picture2.jpg or send the image content inline. Also if the image is used often, then check on top of the script, if your resized image exists, if it does send it otherwise continue to resize.

Sabeen Malik
crap - every script for resizing I have found with gd requires you to know in advance the height/width you want the image. I just want it to be no more then a certain width, and if it is larger then that width then to have it resize into whatever will keep it at less than that width. Can it still return the resized image as the header as it does now?
Josepth Vodary
@Josepth Vodary ... look at my updated answer, that class will allow you to resize based on width only as well.
Sabeen Malik
A: 

You could use CSS max-width and max-height properties.

Petah
A: 

Here isa couple of resize functions, I think at least one of them maintains the aspect ratio.

function resize_image($file, $w, $h, $crop = false) {
    list($width, $height) = getimagesize($file);
    $r = $width / $height;
    if ($crop) {
        if ($width > $height) {
            $width = ceil($width-($width*($r-$w/$h)));
        } else {
            $height = ceil($height-($height*($r-$w/$h)));
        }
        $newwidth = $w;
        $newheight = $h;
    } else {
        if ($w/$h > $r) {
            $newwidth = $h*$r;
            $newheight = $h;
        } else {
            $newheight = $w/$r;
            $newwidth = $w;
        }
    }
    $src = imagecreatefromjpeg($file);
    $dst = imagecreatetruecolor($newwidth, $newheight);
    imagecopyresampled($dst, $src, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);

    return $dst;
}

And:

function thumb_aspect_crop($source_path, $desired_width, $desired_height) {
    list( $source_width, $source_height, $source_type ) = getimagesize($source_path);

    switch ($source_type) {
        case IMAGETYPE_GIF:
            $source_gdim = imagecreatefromgif($source_path);
            break;

        case IMAGETYPE_JPEG:
            $source_gdim = imagecreatefromjpeg($source_path);
            break;

        case IMAGETYPE_PNG:
            $source_gdim = imagecreatefrompng($source_path);
            break;
    }

    $source_aspect_ratio = $source_width / $source_height;
    $desired_aspect_ratio = $desired_width / $desired_height;

    if ($source_aspect_ratio > $desired_aspect_ratio) {
        // Triggered when source image is wider
        $temp_height = $desired_height;
        $temp_width = (int) ( $desired_height * $source_aspect_ratio );
    } else {
        // Triggered otherwise (i.e. source image is similar or taller)
        $temp_width = $desired_width;
        $temp_height = (int) ( $desired_width / $source_aspect_ratio );
    }

    // Resize the image into a temporary GD image
    $temp_gdim = imagecreatetruecolor($temp_width, $temp_height);
    imagecopyresampled(
            $temp_gdim,
            $source_gdim,
            0, 0,
            0, 0,
            $temp_width, $temp_height,
            $source_width, $source_height
    );

    // Copy cropped region from temporary image into the desired GD image
    $x0 = ( $temp_width - $desired_width ) / 2;
    $y0 = ( $temp_height - $desired_height ) / 2;

    $desired_gdim = imagecreatetruecolor($desired_width, $desired_height);
    imagecopy(
            $desired_gdim,
            $temp_gdim,
            0, 0,
            $x0, $y0,
            $desired_width, $desired_height
    );

    return $desired_gdim;
}
Petah
+1  A: 

Try to use Primage class, like in example

SeniorDev