PHP 5.6.0beta1 released

imagecopyresampled

(PHP 4 >= 4.0.6, PHP 5)

imagecopyresampledCopia y cambia el tamaño de parte de una imagen redimensionándola

Descripción

bool imagecopyresampled ( resource $dst_image , resource $src_image , int $dst_x , int $dst_y , int $src_x , int $src_y , int $dst_w , int $dst_h , int $src_w , int $src_h )

imagecopyresampled() copia una porción rectangular de una imagen a otra imagen, interpolando de manera suave los valores de los píxeles por lo que, particularmete, al reducir el tamaño de una imagen, ésta todavía conserva mucha nitidez.

En otras palabras, imagecopyresampled() tomará un área rectangular de src_image de ancho src_w y alto src_h en la posición (src_x,src_y) y la coloca en un área rectangular de dst_image de ancho dst_w y alto dst_h en la posición (dst_x,dst_y).

Si las coordenadas del origen y destino y los anchos y altos difieren, se llevará a cabo la ampliación o reducción del fragmento de la imagen. Las coodernadas se refiren a la esquina superior izquierda. Esta función se puede usar para copiar regiones dentro de la misma imagen (si dst_image es el mismo que src_image) pero si las regiones se solapan el resultado será impredecible.

Parámetros

dst_image

Recurso de tipo enlace a la imagen de destino.

src_image

Recurso de tipo enlace a la imagen original.

dst_x

Coordenada x del punto de destino.

dst_y

Coordenada y del punto de destino.

src_x

Coordenada x del punto de origen.

src_y

Coordenada y del punto de origen.

dst_w

Ancho del destino.

dst_h

Alto del destino.

src_w

Ancho original.

src_h

Altura original.

Valores devueltos

Devuelve TRUE en caso de éxito o FALSE en caso de error.

Ejemplos

Ejemplo #1 Ejemplo sencillo

Este ejemplo redimensionará una imagen a la mitad de su tamaño original.

<?php
// El archivo
$nombre_archivo 'prueba.jpg';
$porcentaje 0.5;

// Tipo de contenido
header('Content-Type: image/jpeg');

// Obtener nuevas dimensiones
list($ancho$alto) = getimagesize($nombre_archivo);
$nuevo_ancho $ancho $porcentaje;
$nuevo_alto $alto $porcentaje;

// Redimensionar
$imagen_p imagecreatetruecolor($nuevo_ancho$nuevo_alto);
$imagen imagecreatefromjpeg($nombre_archivo);
imagecopyresampled($imagen_p$imagen0000$nuevo_ancho$nuevo_alto$ancho$alto);

// Imprimir
imagejpeg($imagen_pnull100);
?>

El resultado del ejemplo sería algo similar a:

Salida del ejemplo : Ejemplo sencillo

Ejemplo #2 Redimensionar una imagen proporcionalmente

Este ejemplo mostrará una imagen con el ancho, o alto, máximo de 200 píxeles.

<?php
// El archivo
$nombre_archivo 'prueba.jpg';

// Establecer un ancho y alto máximo
$ancho 200;
$alto 200;

// Tipo de contenido
header('Content-Type: image/jpeg');

// Obtener las nuevas dimensiones
list($ancho_orig$alto_orig) = getimagesize($nombre_archivo);

$ratio_orig $ancho_orig/$alto_orig;

if (
$ancho/$alto $ratio_orig) {
   
$ancho $alto*$ratio_orig;
} else {
   
$alto $ancho/$ratio_orig;
}

// Redimensionar
$image_p imagecreatetruecolor($ancho$alto);
$image imagecreatefromjpeg($nombre_archivo);
imagecopyresampled($image_p$image0000$ancho$alto$ancho_orig$alto_orig);

// Imprimir
imagejpeg($image_pnull100);
?>

El resultado del ejemplo sería algo similar a:

Salida del ejemplo : Redimensionar una imagen proporcionalmente

Notas

Nota:

Hay un problema debido a las limitaciones de la imagen de paleta (255+1 colores). Redimensionar o filtrar una imagen normalmente necesita más de 255 colores, se usa un tipo de aproximación para calcular el nuevo píxel redimensionado y su color. Con una imagen de paleta tratamos de asignar un color nuevo, si falló, escogemos el color computado más próximo (en teoría). Éste no es siempre el color visual más próximo. Puede producir un resultado extraño, como imágenes en blaco (o visualmente en blaco). Para saltarse este problema, por favor use una imagen de color verdadero como imagen de destino, como una creada por imagecreatetruecolor().

Ver también

imagecopyresized() - Copia y cambia el tamaño de parte de una imagen

add a note add a note

User Contributed Notes 69 notes

up
18
wbcarts at juno dot com
8 months ago
FOUR RECTANGLES

                  $src_image                                   $dst_image
+------------+---------------------------------+   +------------+--------------------+
|            |                                 |   |            |                    |
|            |                                 |   |         $dst_y                  |
|            |                                 |   |            |                    |
|         $src_y                               |   +-- $dst_x --+----$dst_width----+ |
|            |                                 |   |            |                  | |
|            |                                 |   |            |    Resampled     | |
|            |                                 |   |            |                  | |
+-- $src_x --+------ $src_width ------+        |   |       $dst_height             | |
|            |                        |        |   |            |                  | |
|            |                        |        |   |            |                  | |
|            |                        |        |   |            |                  | |
|            |                        |        |   |            +------------------+ |
|            |        Sample          |        |   |                                 |
|            |                        |        |   |                                 |
|            |                        |        |   |                                 |
|       $src_height                   |        |   |                                 |
|            |                        |        |   +---------------------------------+
|            |                        |        |
|            |                        |        |
|            +------------------------+        |
|                                              |
|                                              |
+----------------------------------------------+
up
11
promaty at gmail dot com
2 years ago
Here is my ultimate image resizer that preserves transparency for gif's and png's and has an option to crop images to fixed dimensions (preserves image proportions by default)

<?php
function image_resize($src, $dst, $width, $height, $crop=0){

  if(!list(
$w, $h) = getimagesize($src)) return "Unsupported picture type!";

 
$type = strtolower(substr(strrchr($src,"."),1));
  if(
$type == 'jpeg') $type = 'jpg';
  switch(
$type){
    case
'bmp': $img = imagecreatefromwbmp($src); break;
    case
'gif': $img = imagecreatefromgif($src); break;
    case
'jpg': $img = imagecreatefromjpeg($src); break;
    case
'png': $img = imagecreatefrompng($src); break;
    default : return
"Unsupported picture type!";
  }

 
// resize
 
if($crop){
    if(
$w < $width or $h < $height) return "Picture is too small!";
   
$ratio = max($width/$w, $height/$h);
   
$h = $height / $ratio;
   
$x = ($w - $width / $ratio) / 2;
   
$w = $width / $ratio;
  }
  else{
    if(
$w < $width and $h < $height) return "Picture is too small!";
   
$ratio = min($width/$w, $height/$h);
   
$width = $w * $ratio;
   
$height = $h * $ratio;
   
$x = 0;
  }

 
$new = imagecreatetruecolor($width, $height);

 
// preserve transparency
 
if($type == "gif" or $type == "png"){
   
imagecolortransparent($new, imagecolorallocatealpha($new, 0, 0, 0, 127));
   
imagealphablending($new, false);
   
imagesavealpha($new, true);
  }

 
imagecopyresampled($new, $img, 0, 0, $x, 0, $width, $height, $w, $h);

  switch(
$type){
    case
'bmp': imagewbmp($new, $dst); break;
    case
'gif': imagegif($new, $dst); break;
    case
'jpg': imagejpeg($new, $dst); break;
    case
'png': imagepng($new, $dst); break;
  }
  return
true;
}
?>

Example that I use when uploading new images to the server.

This saves the original picture in the form:
original.type

and creates a new thumbnail:
100x100.type

<?php
  $pic_type
= strtolower(strrchr($picture['name'],"."));
 
$pic_name = "original$pic_type";
 
move_uploaded_file($picture['tmp_name'], $pic_name);
  if (
true !== ($pic_error = @image_resize($pic_name, "100x100$pic_type", 100, 100, 1))) {
    echo
$pic_error;
   
unlink($pic_name);
  }
  else echo
"OK!";
?>

Cheers!
up
2
sam at durosoft.com
7 months ago
The ultimate smart image re-sizing routine. You provide the original image, and a desired width and/or height. The function will intelligently re-size the original image to fit, centered, within the specified dimensions. Either width or height can be omitted to have the re-size "lock" only on width or height. Fantastic for thumbnail generation. Designed to work with PNG's.

function resize_image_smart($orig, $dest_width=null, $dest_height=null)
{
  $orig_width = imagesx($orig);
  $orig_height = imagesy($orig);
  $vertical_offset = 0;
  $horizontal_offset = 0;
  if($dest_width == null)
  {
    if($dest_height == null)
    {
      die('$dest_width and $dest_height cant both be null!');
    }
    // height is locked
    $dest_width = $dest_height * $orig_width / $orig_height;
  } else {
    if($dest_height == null)
    {
      // width is locked
      $dest_height = $dest_width * $orig_height / $orig_width;
    } else {
      // both dimensions are locked
      $vertical_offset = $dest_height - ($orig_height * $dest_width) / $orig_width;
      $horizontal_offset = $dest_width - ($dest_height * $orig_width) / $orig_height;
      if($vertical_offset < 0) $vertical_offset = 0;
      if($horizontal_offset < 0) $horizontal_offset = 0;
    }
  }
  $img = imagecreatetruecolor($dest_width, $dest_height);
  imagesavealpha($img, true);
  imagealphablending($img, false);
  $transparent = imagecolorallocatealpha($img, 0, 0, 0, 127);
  imagefill($img, 0, 0, $transparent);
  imagecopyresampled($img, $orig, round($horizontal_offset / 2),
                                  round($vertical_offset / 2),
                                  0,
                                  0,
                                  round($dest_width - $horizontal_offset),
                                  round($dest_height - $vertical_offset),
                                  $orig_width,
                                  $orig_height);
  return $img;
}
up
2
z3n666 at gmail dot com
4 years ago
I was looking around and couldn't find a function that resizes images to any ratio without leaving a blank area, so i wrote this one. It's able to resize images to any size ratio, when the ratio is no match with the original it will crop proportional area on the original and resize it.

<?php

function _ckdir($fn) {
    if (
strpos($fn,"/") !== false) {
       
$p=substr($fn,0,strrpos($fn,"/"));
        if (!
is_dir($p)) {
           
_o("Mkdir: ".$p);
           
mkdir($p,777,true);
        }
    }
}
function
img_resizer($src,$quality,$w,$h,$saveas) {
   
/* v2.5 with auto crop */
   
$r=1;
   
$e=strtolower(substr($src,strrpos($src,".")+1,3));
    if ((
$e == "jpg") || ($e == "peg")) {
       
$OldImage=ImageCreateFromJpeg($src) or $r=0;
    } elseif (
$e == "gif") {
       
$OldImage=ImageCreateFromGif($src) or $r=0;
    } elseif (
$e == "bmp") {
       
$OldImage=ImageCreateFromwbmp($src) or $r=0;
    } elseif (
$e == "png") {
       
$OldImage=ImageCreateFromPng($src) or $r=0;
    } else {
       
_o("Not a Valid Image! (".$e.") -- ".$src);$r=0;
    }
    if (
$r) {
        list(
$width,$height)=getimagesize($src);
       
// check if ratios match
       
$_ratio=array($width/$height,$w/$h);
        if (
$_ratio[0] != $_ratio[1]) { // crop image

            // find the right scale to use
           
$_scale=min((float)($width/$w),(float)($height/$h));

           
// coords to crop
           
$cropX=(float)($width-($_scale*$w));
           
$cropY=(float)($height-($_scale*$h));   
           
           
// cropped image size
           
$cropW=(float)($width-$cropX);
           
$cropH=(float)($height-$cropY);
           
           
$crop=ImageCreateTrueColor($cropW,$cropH);
           
// crop the middle part of the image to fit proportions
           
ImageCopy(
               
$crop,
               
$OldImage,
               
0,
               
0,
                (int)(
$cropX/2),
                (int)(
$cropY/2),
               
$cropW,
               
$cropH
           
);
        }
       
       
// do the thumbnail
       
$NewThumb=ImageCreateTrueColor($w,$h);
        if (isset(
$crop)) { // been cropped
           
ImageCopyResampled(
               
$NewThumb,
               
$crop,
               
0,
               
0,
               
0,
               
0,
               
$w,
               
$h,
               
$cropW,
               
$cropH
           
);
           
ImageDestroy($crop);
        } else {
// ratio match, regular resize
           
ImageCopyResampled(
               
$NewThumb,
               
$OldImage,
               
0,
               
0,
               
0,
               
0,
               
$w,
               
$h,
               
$width,
               
$height
           
);
        }
       
_ckdir($saveas);
       
ImageJpeg($NewThumb,$saveas,$quality);
       
ImageDestroy($NewThumb);
       
ImageDestroy($OldImage);
    }
    return
$r;
}

?>
up
1
areddan at silverarm dot ie
8 years ago
<?php
// The file
$filein = ''; // File in
$fileout = 'ttt.gif'; // Fileout - optional

$imagethumbsize_w = 100; // thumbnail size (area cropped in middle of image)
$imagethumbsize_h = 75; // thumbnail size (area cropped in middle of image)
resize_then_crop( $filein,$fileout,$imagethumbsize_w,
$imagethumbsize_h,/*rgb*/"255","255","255");

//Author Alan Reddan Silverarm Solutions
//Date 27/01/2005
//Function that works well with images.
//It takes the image and reduces its size to best fit. i.e If you have an image
//that is 200 X 100 and you want a thumbnail of 75 X 50,
//it first resizes the image to 100 X 50
//and then takes out a portion 75 X 50 from then center of the input image.
//So loads of image information is retained.
//The corollary also holds if your input image is 100 X 200
//it first resizes image to 75 X 150 and then takes out a
//portion 75 X 75 from the centre
// The advantage here is that function decides on whether
//resize is by width or height itself.
//it also decides whether to use the height or the width as the base start point
//in the case that athumbnail is rectangular

function resize_then_crop( $filein,$fileout,
$imagethumbsize_w,$imagethumbsize_h,$red,$green,$blue)
{

// Get new dimensions
list($width, $height) = getimagesize($filein);
$new_width = $width * $percent;
$new_height = $height * $percent;

   if(
preg_match("/.jpg/i", "$filein"))
   {
      
$format = 'image/jpeg';
   }
   if (
preg_match("/.gif/i", "$filein"))
   {
      
$format = 'image/gif';
   }
   if(
preg_match("/.png/i", "$filein"))
   {
      
$format = 'image/png';
   }
  
       switch(
$format)
       {
           case
'image/jpeg':
          
$image = imagecreatefromjpeg($filein);
           break;
           case
'image/gif';
          
$image = imagecreatefromgif($filein);
           break;
           case
'image/png':
          
$image = imagecreatefrompng($filein);
           break;
       }

$width = $imagethumbsize_w ;
$height = $imagethumbsize_h ;
list(
$width_orig, $height_orig) = getimagesize($filein);

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

if (
$width < $imagethumbsize_w)
//if the width is smaller than supplied thumbnail size
{
$width = $imagethumbsize_w;
$height = ($imagethumbsize_w/ $width_orig) * $height_orig;;
}

if (
$height < $imagethumbsize_h)
//if the height is smaller than supplied thumbnail size
{
$height = $imagethumbsize_h;
$width = ($imagethumbsize_h / $height_orig) * $width_orig;
}

$thumb = imagecreatetruecolor($width , $height); 
$bgcolor = imagecolorallocate($thumb, $red, $green, $blue);  
ImageFilledRectangle($thumb, 0, 0, $width, $height, $bgcolor);
imagealphablending($thumb, true);

imagecopyresampled($thumb, $image, 0, 0, 0, 0,
$width, $height, $width_orig, $height_orig);
$thumb2 = imagecreatetruecolor($imagethumbsize_w , $imagethumbsize_h);
// true color for best quality
$bgcolor = imagecolorallocate($thumb2, $red, $green, $blue);  
ImageFilledRectangle($thumb2, 0, 0,
$imagethumbsize_w , $imagethumbsize_h , $white);
imagealphablending($thumb2, true);

$w1 =($width/2) - ($imagethumbsize_w/2);
$h1 = ($height/2) - ($imagethumbsize_h/2);

imagecopyresampled($thumb2, $thumb, 0,0, $w1, $h1,
$imagethumbsize_w , $imagethumbsize_h ,$imagethumbsize_w, $imagethumbsize_h);

// Output
//header('Content-type: image/gif');
//imagegif($thumb); //output to browser first image when testing

if ($fileout !="")imagegif($thumb2, $fileout); //write to file
header('Content-type: image/gif');
imagegif($thumb2); //output to browser
}
?>
up
2
zorroswordsman at gmail dot com
5 years ago
I've created a PHP5 image resize class, using ImageCopyResampled, that someone might find useful, with support for JPEG, PNG, and GIF formats. It retains the original image's aspect ratio when resizing, and doesn't resize or resample if the original width and height is smaller then the desired resize.

<?php

// Imaging
class imaging
{

   
// Variables
   
private $img_input;
    private
$img_output;
    private
$img_src;
    private
$format;
    private
$quality = 80;
    private
$x_input;
    private
$y_input;
    private
$x_output;
    private
$y_output;
    private
$resize;

   
// Set image
   
public function set_img($img)
    {

       
// Find format
       
$ext = strtoupper(pathinfo($img, PATHINFO_EXTENSION));

       
// JPEG image
       
if(is_file($img) && ($ext == "JPG" OR $ext == "JPEG"))
        {

           
$this->format = $ext;
           
$this->img_input = ImageCreateFromJPEG($img);
           
$this->img_src = $img;
           

        }

       
// PNG image
       
elseif(is_file($img) && $ext == "PNG")
        {

           
$this->format = $ext;
           
$this->img_input = ImageCreateFromPNG($img);
           
$this->img_src = $img;

        }

       
// GIF image
       
elseif(is_file($img) && $ext == "GIF")
        {

           
$this->format = $ext;
           
$this->img_input = ImageCreateFromGIF($img);
           
$this->img_src = $img;

        }

       
// Get dimensions
       
$this->x_input = imagesx($this->img_input);
       
$this->y_input = imagesy($this->img_input);

    }

   
// Set maximum image size (pixels)
   
public function set_size($size = 100)
    {

       
// Resize
       
if($this->x_input > $size && $this->y_input > $size)
        {

           
// Wide
           
if($this->x_input >= $this->y_input)
            {

               
$this->x_output = $size;
               
$this->y_output = ($this->x_output / $this->x_input) * $this->y_input;

            }

           
// Tall
           
else
            {

               
$this->y_output = $size;
               
$this->x_output = ($this->y_output / $this->y_input) * $this->x_input;

            }

           
// Ready
           
$this->resize = TRUE;

        }

       
// Don't resize
       
else { $this->resize = FALSE; }

    }

   
// Set image quality (JPEG only)
   
public function set_quality($quality)
    {

        if(
is_int($quality))
        {

           
$this->quality = $quality;

        }

    }

   
// Save image
   
public function save_img($path)
    {

       
// Resize
       
if($this->resize)
        {

           
$this->img_output = ImageCreateTrueColor($this->x_output, $this->y_output);
           
ImageCopyResampled($this->img_output, $this->img_input, 0, 0, 0, 0, $this->x_output, $this->y_output, $this->x_input, $this->y_input);

        }

       
// Save JPEG
       
if($this->format == "JPG" OR $this->format == "JPEG")
        {

            if(
$this->resize) { imageJPEG($this->img_output, $path, $this->quality); }
            else {
copy($this->img_src, $path); }

        }

       
// Save PNG
       
elseif($this->format == "PNG")
        {

            if(
$this->resize) { imagePNG($this->img_output, $path); }
            else {
copy($this->img_src, $path); }

        }

       
// Save GIF
       
elseif($this->format == "GIF")
        {

            if(
$this->resize) { imageGIF($this->img_output, $path); }
            else {
copy($this->img_src, $path); }

        }

    }

   
// Get width
   
public function get_width()
    {

        return
$this->x_input;

    }

   
// Get height
   
public function get_height()
    {

        return
$this->y_input;

    }

   
// Clear image cache
   
public function clear_cache()
    {

        @
ImageDestroy($this->img_input);
        @
ImageDestroy($this->img_output);

    }

}

##### DEMO #####

// Image
$src = "myimage.jpg";

// Begin
$img = new imaging;
$img->set_img($src);
$img->set_quality(80);

// Small thumbnail
$img->set_size(200);
$img->save_img("small_" . $src);

// Baby thumbnail
$img->set_size(50);
$img->save_img("baby_" . $src);

// Finalize
$img->clear_cache();

?>
up
2
tim at leethost dot com
6 years ago
Here's an improved and corrected version of my fastimagecopyresampled script.  Because I typically scale entire images it appears my previous code was not properly tested.  In any case, this new script has been thoroughly tested, cleaned up, and enhanced.  The code is a little tighter and quality values between 0 and 1 will yield a mosaic effect (basically lowering quality below the pervious lowest value of 1).  I would still suggest using a quality of 2 to 4 as that's the primary purpose of this script, which is high quality and fast results.  Don't be afraid of using a quality value of 1.5 for extreme cases where you have a bunch of very large images from digital cameras (like those 10M pixel cameras theses days) and creating thumbnails in batch mode.  Even a quality of 1.5 is a big improvement over imagecopyresized and is ultra-fast.

Anyway, enjoy and I hope this is the bug-free last version.

<?
function fastimagecopyresampled (&$dst_image, $src_image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h, $quality = 3) {
 
// Plug-and-Play fastimagecopyresampled function replaces much slower imagecopyresampled.
  // Just include this function and change all "imagecopyresampled" references to "fastimagecopyresampled".
  // Typically from 30 to 60 times faster when reducing high resolution images down to thumbnail size using the default quality setting.
  // Author: Tim Eckel - Date: 09/07/07 - Version: 1.1 - Project: FreeRingers.net - Freely distributable - These comments must remain.
  //
  // Optional "quality" parameter (defaults is 3). Fractional values are allowed, for example 1.5. Must be greater than zero.
  // Between 0 and 1 = Fast, but mosaic results, closer to 0 increases the mosaic effect.
  // 1 = Up to 350 times faster. Poor results, looks very similar to imagecopyresized.
  // 2 = Up to 95 times faster.  Images appear a little sharp, some prefer this over a quality of 3.
  // 3 = Up to 60 times faster.  Will give high quality smooth results very close to imagecopyresampled, just faster.
  // 4 = Up to 25 times faster.  Almost identical to imagecopyresampled for most images.
  // 5 = No speedup. Just uses imagecopyresampled, no advantage over imagecopyresampled.

 
if (empty($src_image) || empty($dst_image) || $quality <= 0) { return false; }
  if (
$quality < 5 && (($dst_w * $quality) < $src_w || ($dst_h * $quality) < $src_h)) {
   
$temp = imagecreatetruecolor ($dst_w * $quality + 1, $dst_h * $quality + 1);
   
imagecopyresized ($temp, $src_image, 0, 0, $src_x, $src_y, $dst_w * $quality + 1, $dst_h * $quality + 1, $src_w, $src_h);
   
imagecopyresampled ($dst_image, $temp, $dst_x, $dst_y, 0, 0, $dst_w, $dst_h, $dst_w * $quality, $dst_h * $quality);
   
imagedestroy ($temp);
  } else
imagecopyresampled ($dst_image, $src_image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);
  return
true;
}
?>
up
1
kazuya
1 month ago
<?php

$new_file
= img_resize("./img/", "test.jpg","copy_test.jpg",300);
echo
"<IMG src = '$new_file'>";

function
img_resize($path,$tmp_name,$new_name,$new_width){
    if (!
file_exists($path.$filename)){
        echo
"file not found!";
        exit;
    }
    if (!
is_writable($path)){
        echo
"error:permission denied!";
        exit;
    }
    list(
$width, $height) = getimagesize($path . $tmp_name);
   
$new_height = abs($new_width * $height / $width);
   
$image_p = imagecreatetruecolor($new_width, $new_height);
   
$image = imagecreatefromjpeg($path . $tmp_name);
   
imagecopyresampled($image_p, $image, 0, 0, 0, 0,
                       
$new_width, $new_height, $width, $height);
   
imagejpeg($image_p, $path . $new_name);
    return
$path.$new_name;
}

?>
up
1
bobbyboyojones at hotmail dot com
6 years ago
I hated that enlarging an image resulted in giant pixels rather than a smoother look, so I wrote this function.  It takes longer, but gives a much nicer look.

<?php

function imagecopyresampledSMOOTH(&$dst_img, &$src_img, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h, $mult=1.25){
   
// don't use a $mult that's too close to an int or this function won't make much of a difference

   
$tgt_w = round($src_w * $mult);
   
$tgt_h = round($src_h * $mult);
   
   
// using $mult <= 1 will make the current step w/h smaller (or the same), don't allow this, always resize by at least 1 pixel larger
   
if($tgt_w <= $src_w){ $tgt_w += 1; }
    if(
$tgt_h <= $src_h){ $tgt_h += 1; }
   
   
// if the current step w/h is larger than the final height, adjust it back to the final size
    // this check also makes it so that if we are doing a resize to smaller image, it happens in one step (since that's already smooth)
   
if($tgt_w > $dst_w){ $tgt_w = $dst_w; }
    if(
$tgt_h > $dst_h){ $tgt_h = $dst_h; }

   
$tmpImg = imagecreatetruecolor($tgt_w, $tgt_h);

   
imagecopyresampled($tmpImg, $src_img, 0, 0, $src_x, $src_y, $tgt_w, $tgt_h, $src_w, $src_h);
   
imagecopy($dst_img, $tmpImg, $dst_x, $dst_y, 0, 0, $tgt_w, $tgt_h);
   
imagedestroy($tmpImg);

   
// as long as the final w/h has not been reached, reep on resizing
   
if($tgt_w < $dst_w OR $tgt_h < $dst_h){
       
imagecopyresampledSMOOTH($dst_img, $dst_img, $dst_x, $dst_y, $dst_x, $dst_y, $dst_w, $dst_h, $tgt_w, $tgt_h, $mult);
    }
}

?>
up
1
liviu dot malaescu at gmail dot com
6 years ago
3800x2500px - 2s
3807x6768 - 4.7s
Tested on a core2duo e4300/1gb ram - only one core used.
It reduces first with nearest-neighbour and then with bicubic on the smaller image.
Thumb quality is fine :)

<?php
$cale_in
= "test.jpg"; //input-file
$cale_out = "test_thumb.jpg"; //output-file
$make_thumbs = "YES";
$thumbsize[0] = 100;
$thumbsize[1] = 75;
ini_set("memory_limit", "134217728"); // needed for huge pictures

// Bicubic resampling, not written by me
function ImageCopyResampleBicubic
(&$dst_img, &$src_img, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h)  {
   
ImagePaletteCopy ($dst_img, $src_img);
   
$rX = $src_w / $dst_w;
   
$rY = $src_h / $dst_h;
   
$w = 0;
    for (
$y = $dst_y; $y < $dst_h; $y++)  {
       
$ow = $w; $w = round(($y + 1) * $rY);
       
$t = 0;
        for (
$x = $dst_x; $x < $dst_w; $x++)  {
           
$r = $g = $b = 0; $a = 0;
           
$ot = $t; $t = round(($x + 1) * $rX);
            for (
$u = 0; $u < ($w - $ow); $u++)  {
                for (
$p = 0; $p < ($t - $ot); $p++)  {
                   
$c = ImageColorsForIndex ($src_img,
ImageColorAt ($src_img, $ot + $p, $ow + $u));
                   
$r += $c['red'];
                   
$g += $c['green'];
                   
$b += $c['blue'];
                   
$a++;
                }
            }
           
ImageSetPixel ($dst_img, $x, $y,
ImageColorClosest ($dst_img, $r / $a, $g / $a, $b / $a));
        }
    }
}

function
makeThumb($cale_in)  {
    global
$thumbsize;
   
$sursa = imagecreatefromjpeg($cale_in);
   
$is_jpeg = getimagesize($cale_in);
   
$ws = $is_jpeg[0];
   
$hs = $is_jpeg[1];
    if(
$ws > $thumbsize[0] && $hs > $thumbsize[1])
    {
       
$aspect = $ws/$hs;
        if(
$aspect <= 1.333333)  {
           
$hd = $thumbsize[1];
           
$wd = floor($hd*$aspect);
        }
        else  {
           
$wd = $thumbsize[0];
           
$hd = floor($wd/$aspect);
        }
       
$Z = ceil(log(($ws*$hs)/(4*$thumbsize[0]*$thumbsize[1])))+1;
        if(
log(($ws*$hs)/(4*$thumbsize[0]*$thumbsize[1])) < 0) $Z=1;
       
$dx = $dy = 0;
        if(
$Z > 1) {
           
$dest = imagecreatetruecolor(round($ws/$Z), round($hs/$Z));
            for(
$i=0; $i < $hs; $i+=$Z) {
                for(
$j=0; $j < $ws; $j+=$Z) {
                   
$rgb = imagecolorat($sursa, $j, $i);
                   
$r = ($rgb >> 16) & 0xFF;
                   
$g = ($rgb >> 8) & 0xFF;
                   
$b = $rgb & 0xFF;
                   
$pcol = imagecolorallocate($dest, $r, $g, $b);
                   
imagesetpixel($dest, $dx, $dy, $pcol);
                   
$dx++;
                }
               
$dx=0;
               
$dy++;
            }
        }
        else
        {
           
$dest = imagecreatetruecolor($ws, $hs);
           
imagecopy($dest, $sursa, 0, 0, 0, 0, $ws, $hs );   
        }
       
imagedestroy($sursa);
       
$destrs = imagecreatetruecolor($wd, $hd);
       
ImageCopyResampleBicubic($destrs,$dest,0,0,0,0,
$wd,$hd,round($ws/$Z),round($hs/$Z));
       
ImageJpeg($destrs, $cale_out, 100);   
        echo
"Z:$Z <b>|</b> ($ws x $hs) -> ($wd x $hd) @ ".$ws/$hs;
    }   
}

function
mf() {
    list(
$usec, $sec) = explode(" ", microtime());
   
$x[0] = $sec$x[1] = $usec;
    return
$x;
}

$timp1 = mf(); //starting to count
makeThumb($cale_in); //makes the actual thumb
$timp2 = mf(); //timer ends
$dsec = $timp2[0] - $timp1[0];
$dusec = $timp2[1] - $timp1[1];
echo
"<b>|</b> Time : <b>".round($dusec+$dsec,6)."s</b> <b>|</b><br />";

?>
up
0
julien at go-on-web dot com
14 days ago
Windows does not accept floating width and height...

So, in "Example #2 Resampling an image proportionally", prefer :
<?php
if ($width/$height > $ratio_orig) {
  
$width = round( $height*$ratio_orig );
} else {
  
$height = round( $width/$ratio_orig );
}
?>
(used "round")
otherwise your image wont be resized.
up
0
hoangvu4000 at gmail dot com
10 months ago
My complete function to resize an image  with exif data

<?php
function CreateThumbnail($pic,$thumb,$thumbwidth, $quality = 100)
{
        
       
$im1=ImageCreateFromJPEG($pic);
        if(
function_exists("exif_read_data")){
               
$exif = exif_read_data($pic);
                if(!empty(
$exif['Orientation'])) {
                switch(
$exif['Orientation']) {
                case
8:
                   
$im1 = imagerotate($im1,90,0);
                    break;
                case
3:
                   
$im1 = imagerotate($im1,180,0);
                    break;
                case
6:
                   
$im1 = imagerotate($im1,-90,0);
                    break;
                }
                }
        }
       
$info = @getimagesize($pic);
       
       
$width = $info[0];
        
       
$w2=ImageSx($im1);
       
$h2=ImageSy($im1);
       
$w1 = ($thumbwidth <= $info[0]) ? $thumbwidth : $info[0]  ;
        
       
$h1=floor($h2*($w1/$w2));
       
$im2=imagecreatetruecolor($w1,$h1);
        
       
imagecopyresampled ($im2,$im1,0,0,0,0,$w1,$h1,$w2,$h2);
       
$path=addslashes($thumb);
       
ImageJPEG($im2,$path,$quality);
       
ImageDestroy($im1);
       
ImageDestroy($im2);
        
}
?>
up
0
alex-thennstaett-remove at gmx dot net
1 year ago
Having updated GD-Library from 2.0.35-r1 to 2.0.35-r3 using negative numbers for $dstX or $dstY started to produce unpredictable results, such as inserting shrinked images and enlarging $dstH or $dstW all by itself. While it did work fine previously, one should avoid using or calculating negative numbers for imagecopyresampled from the beginning.
up
0
jagarock at gmail dot com
2 years ago
A simple function that will crop xxx px from the bottom of the image.

<?php
function cropBottom($image,$bottom) {
list(
$width, $height) = getimagesize($image);
$img = imagecreatefromjpeg($image);
$crop = imagecreatetruecolor($width,$height-$bottom);
imagecopyresampled ( $crop, $img, 0, 0, 0, 0, $width, $height, $width, $height );
imagejpeg($crop,$image,85);
}
?>
up
0
guru_boy87 at hotmail dot com
3 years ago
Function to resize an image.

<?php
function resizeImage($originalImage,$toWidth,$toHeight)
{

    list(
$width, $height) = getimagesize($originalImage);
   
$xscale=$width/$toWidth;
   
$yscale=$height/$toHeight;

    if (
$yscale>$xscale){
       
$new_width = round($width * (1/$yscale));
       
$new_height = round($height * (1/$yscale));
    }
    else {
       
$new_width = round($width * (1/$xscale));
       
$new_height = round($height * (1/$xscale));
    }
   
   
   
$imageResized = imagecreatetruecolor($new_width, $new_height);
   
$imageTmp     = imagecreatefromjpeg ($originalImage);
   
imagecopyresampled($imageResized, $imageTmp, 0, 0, 0, 0, $new_width, $new_height, $width, $height);

    return
$imageResized;
   

}
?>
up
0
seifer at loveletslive dot com
4 years ago
Okay so I saw that others have posted this already but I just messed around and made it so figured I would share it.

Mine works, not to say others don't, I haven't tested them.

This function creates a thumbnail of the specfied size.
If the thumbnail is a different ration it will automatically crop the center of the source image.

It works if the source image is bigger or smaller than the desired "cropped thumbnail."

Here is the code...
<?php
function CroppedThumbnail($imgSrc,$thumbnail_width,$thumbnail_height) { //$imgSrc is a FILE - Returns an image resource.
    //getting the image dimensions 
   
list($width_orig, $height_orig) = getimagesize($imgSrc);  
   
$myImage = imagecreatefromjpeg($imgSrc);
   
$ratio_orig = $width_orig/$height_orig;
   
    if (
$thumbnail_width/$thumbnail_height > $ratio_orig) {
      
$new_height = $thumbnail_width/$ratio_orig;
      
$new_width = $thumbnail_width;
    } else {
      
$new_width = $thumbnail_height*$ratio_orig;
      
$new_height = $thumbnail_height;
    }
   
   
$x_mid = $new_width/2//horizontal middle
   
$y_mid = $new_height/2; //vertical middle
   
   
$process = imagecreatetruecolor(round($new_width), round($new_height));
   
   
imagecopyresampled($process, $myImage, 0, 0, 0, 0, $new_width, $new_height, $width_orig, $height_orig);
   
$thumb = imagecreatetruecolor($thumbnail_width, $thumbnail_height);
   
imagecopyresampled($thumb, $process, 0, 0, ($x_mid-($thumbnail_width/2)), ($y_mid-($thumbnail_height/2)), $thumbnail_width, $thumbnail_height, $thumbnail_width, $thumbnail_height);

   
imagedestroy($process);
   
imagedestroy($myImage);
    return
$thumb;
}

//Create the thumbnail
$newThumb = CroppedThumbnail("MyImageName.jpg",75,100);

// And display the image...
header('Content-type: image/jpeg');
imagejpeg($newThumb);
?>
up
0
asgaroth dot belem at gmail dot com
4 years ago
In case you are having trouble ( like I did ) and getting some kind of noise in the resampled image.

then changing imagecopyresampled() with imagecopyresized()  removes the noise, found that here: http://bugs.php.net/bug.php?id=45030

Do not ask me why. but it works.
up
0
asgaroth dot belem at gmail dot com
4 years ago
About preserving the  transparency when resizing PNGs this was the only thing that worked for me:

<?php imagealphablending($new_watermark, false);
       
$color = imagecolortransparent($new_watermark, imagecolorallocatealpha($new_watermark, 0, 0, 0, 127));
       
imagefill($new_watermark, 0, 0, $color);
       
imagesavealpha($new_watermark, true);
       
imagecopyresampled($new_watermark, $watermark, 0, 0, 0, 0, $new_watermark_width, $new_watermark_height, imagesx($watermark),imagesy($watermark));
?>

Tried without success:

<?php imagealphablending($new_watermark, false);
       
$color = imagecolortransparent($new_watermark, imagecolorallocate($new_watermark, 0, 0, 0));
       
imagefill($new_watermark, 0, 0, $color);
       
imagesavealpha($new_watermark, true);
       
imagecopyresampled($new_watermark, $watermark, 0, 0, 0, 0, $new_watermark_width, $new_watermark_height, imagesx($watermark),imagesy($watermark));
 
?>

hope it helps someone.
up
0
satanas147 at gmail dot com
5 years ago
Another add-on to previous php5 class for thumbnail (with a merge of Matt and Zorro's proposals).
This is dedicated to generate thumbnail on the fly for a webpage using the subclass thumbnail.
It saves the generated thumb as myimage_tn, in the same directory.
I'm quite new with php5, so I think this could be optimized, but it seems to work fine.

<?php
// Imaging
class imaging
{
   
// Variables
   
private $img_input;
    private
$img_output;
    private
$img_src;
    private
$format;
    private
$quality = 80;
    private
$x_input;
    private
$y_input;
    private
$x_output;
    private
$y_output;
    private
$resize;

   
// Set image
   
public function set_img($img)
    {
       
// Find format
       
$ext = strtoupper(pathinfo($img, PATHINFO_EXTENSION));
       
// JPEG image
       
if(is_file($img) && ($ext == "JPG" OR $ext == "JPEG"))
        {
           
$this->format = $ext;
           
$this->img_input = ImageCreateFromJPEG($img);
           
$this->img_src = $img;
        }
       
// PNG image
       
elseif(is_file($img) && $ext == "PNG")
        {
           
$this->format = $ext;
           
$this->img_input = ImageCreateFromPNG($img);
           
$this->img_src = $img;
        }
       
// GIF image
       
elseif(is_file($img) && $ext == "GIF")
        {
           
$this->format = $ext;
           
$this->img_input = ImageCreateFromGIF($img);
           
$this->img_src = $img;
        }
       
// Get dimensions
       
$this->x_input = imagesx($this->img_input);
       
$this->y_input = imagesy($this->img_input);
    }

   
// Set maximum image size (pixels)
   
public function set_size($max_x = 100,$max_y = 100)
    {
       
// Resize
       
if($this->x_input > $max_x || $this->y_input > $max_y)
        {
           
$a= $max_x / $max_y;
           
$b= $this->x_input / $this->y_input;
            if (
$a<$b)
            {
               
$this->x_output = $max_x;
               
$this->y_output = ($max_x / $this->x_input) * $this->y_input;
            }
            else
            {
               
$this->y_output = $max_y;
               
$this->x_output = ($max_y / $this->y_input) * $this->x_input;
            }
           
// Ready
           
$this->resize = TRUE;
        }
       
// Don't resize      
       
else { $this->resize = FALSE; }
    }
   
// Set image quality (JPEG only)
   
public function set_quality($quality)
    {
        if(
is_int($quality))
        {
           
$this->quality = $quality;
        }
    }
   
// Save image
   
public function save_img($path)
    {
       
// Resize
       
if($this->resize)
        {
           
$this->img_output = ImageCreateTrueColor($this->x_output, $this->y_output);
           
ImageCopyResampled($this->img_output, $this->img_input, 0, 0, 0, 0, $this->x_output, $this->y_output, $this->x_input, $this->y_input);
        }
       
// Save JPEG
       
if($this->format == "JPG" OR $this->format == "JPEG")
        {
            if(
$this->resize) { imageJPEG($this->img_output, $path, $this->quality); }
            else {
copy($this->img_src, $path); }
        }
       
// Save PNG
       
elseif($this->format == "PNG")
        {
            if(
$this->resize) { imagePNG($this->img_output, $path); }
            else {
copy($this->img_src, $path); }
        }
       
// Save GIF
       
elseif($this->format == "GIF")
        {
            if(
$this->resize) { imageGIF($this->img_output, $path); }
            else {
copy($this->img_src, $path); }
        }
    }
   
// Get width
   
public function get_width()
    {
        return
$this->x_input;
    }
   
// Get height
   
public function get_height()
    {
        return
$this->y_input;
    }
   
// Clear image cache
   
public function clear_cache()
    {
        @
ImageDestroy($this->img_input);
        @
ImageDestroy($this->img_output);
    }
}
class
thumbnail extends imaging {
    private
$image;
    private
$width;
    private
$height;
   
    function
__construct($image,$width,$height) {
parent::set_img($image);
parent::set_quality(80);
parent::set_size($width,$height);
           
$this->thumbnail= pathinfo($image, PATHINFO_DIRNAME).pathinfo($image, PATHINFO_FILENAME).'_tn.'.pathinfo($image, PATHINFO_EXTENSION);
parent::save_img($this->thumbnail);
parent::clear_cache();
        }
    function
__toString() {
            return
$this->thumbnail;
    }
}

********
*
DEMO *
********
$thumb = new thumbnail('./image_dir/sub_dir/myimage.jpg',100,100);
echo
'<img src=\''.$thumb.'\' alt=\'myimage\' title=\'myimage\'/>';

   
?>
up
0
zuegs
5 years ago
Resampling GIFs and retain transparency dosen't work always, as dependent on the resample factor the resulting resampled image has some pattern-noise that prevents "imagegif" to find all the transparent-pixels.
One way to fix this, is to reset all pixels with high alpha to full-transparent:
<?php
// load/create images
$img_src=imagecreatefromgif($g_srcfile);
$img_dst=imagecreatetruecolor($g_iw,$g_ih);
imagealphablending($img_dst, false);

// get and reallocate transparency-color
$transindex = imagecolortransparent($img_src);
if(
$transindex >= 0) {
 
$transcol = imagecolorsforindex($img_src, $transindex);
 
$transindex = imagecolorallocatealpha($img_dst, $transcol['red'], $transcol['green'], $transcol['blue'], 127);
 
imagefill($img_dst, 0, 0, $transindex);
}

// resample
imagecopyresampled($img_dst, $img_src, 0, 0, 0, 0, $g_iw, $g_ih, $g_is[0], $g_is[1]);

// restore transparency
if($transindex >= 0) {
 
imagecolortransparent($img_dst, $transindex);
  for(
$y=0; $y<$g_ih; ++$y)
    for(
$x=0; $x<$g_iw; ++$x)
      if(((
imagecolorat($img_dst, $x, $y)>>24) & 0x7F) >= 100) imagesetpixel($img_dst, $x, $y, $transindex);

// save GIF
imagetruecolortopalette($img_dst, true, 255);
imagesavealpha($img_dst, false);
imagegif($img_dst, $g_dstfile);
imagedestroy($img_dst);
?>
up
0
Warren
5 years ago
This is a function I wrote for making thumbnails -  it will accept a source *image resource* and destination *path*, plus the max dimension and whether the thumbnail should be square.

I chose to accept a resource as the source to make it a bit more efficient to create multiple sizes. For example:

<?php
$src_im
=@imagecreatefromjpeg($pathtofile);
$large = resize($src_im,$destination_large,1024);
@
imagedestroy($src_im);
$medium = resize($large,$destination_medium,500);
@
imagedestroy($large);
$small = resize($medium,$destination_small,125);
@
imagedestroy($medium);
$square = resize($small,$destination_square,75,TRUE);
@
imagedestroy($small);
@
imagedestroy($square);

function
resize($src_im, $dpath, $maxd, $square=false) {
   
$src_width = imagesx($src_im);
   
$src_height = imagesy($src_im);
   
$src_w=$src_width;
   
$src_h=$src_height;
   
$src_x=0;
   
$src_y=0;
    if(
$square){
       
$dst_w = $maxd;
       
$dst_h = $maxd;
        if(
$src_width>$src_height){
           
$src_x = ceil(($src_width-$src_height)/2);
           
$src_w=$src_height;
           
$src_h=$src_height;
        }else{
           
$src_y = ceil(($src_height-$src_width)/2);
           
$src_w=$src_width;
           
$src_h=$src_width;
        }
    }else{
        if(
$src_width>$src_height){
           
$dst_w=$maxd;
           
$dst_h=floor($src_height*($dst_w/$src_width));
        }else{
           
$dst_h=$maxd;
           
$dst_w=floor($src_width*($dst_h/$src_height));
        }
    }
   
$dst_im=@imagecreatetruecolor($dst_w,$dst_h);
    @
imagecopyresampled($dst_im, $src_im, 0, 0, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);
    @
imagejpeg($dst_im,$dpath);
    return
$dst_im;
}
?>
up
0
MBorgPL at gmail dot com
5 years ago
Another addition to zorroswordsman at gmail dot com's resize class.

The function takes $_FILES['sent_image'] as 1st parameter. The 2nd is complete destination path.

It only moves images.

It returns destination path if succeeded, and false if any error occurred.

<?php
public function move_image($tmp_img, $dest_img)
{
   
//verifies if the uploaded file is an image
   
if (strpos($tmp_img['type'], 'image') !== false)
        {
       
//moves the uploaded file into the destination place
       
if (move_uploaded_file($tmp_img['tmp_name'], $dest_img)) {
            return
$dest_img;
        }
    }       
    return
false;
}
?>
up
0
MBorg_PL
5 years ago
Another tiny ammendment to zorroswordsman at gmail dot com's resize class AND matt at rees-jenkins dot co dot uk addition. The class may resize to different width and height not only same ones:

<?php
// Set maximum image size (pixels)
public function set_size($max_x = 100,$max_y = 100)
{
   
   
// Resize
   
if($this->x_input > $max_x || $this->y_input > $max_y)
    {

       
$a= $max_x / $max_y;
       
$b= $this->x_input / $this->y_input;
       
        if (
$a<$b)
        {

           
$this->x_output = $max_x;
           
$this->y_output = ($max_x / $this->x_input) * $this->y_input;

        }
        else
        {

           
$this->y_output = $max_y;
           
$this->x_output = ($max_y / $this->y_input) * $this->x_input;

        }
       
// Ready
       
       
$this->resize = TRUE;
       
    }
   
   
// Don't resize       
   
else { $this->resize = FALSE; }
   
}
?>

And the use of the class is now:

<?php

##### DEMO #####

// Image
$src = "myimage.jpg";

// Begin
$img = new imaging;
$img->set_img($src);
$img->set_quality(80);

// Small thumbnail
$img->set_size(250,150);
$img->save_img("small_250x150_" . $src);

// Baby thumbnail
$img->set_size(50,250);
$img->save_img("baby_50x250_" . $src);

// Finalize
$img->clear_cache();

?>
up
0
matt at rees-jenkins dot co dot uk
5 years ago
A tiny ammendment to zorroswordsman at gmail dot com's resize class. It was only resizing if both the width AND height where greater than the desired size. This should fix it:

<?php
// Set maximum image size (pixels)
function set_size($size = 100)
{
   
// Resize
   
if($this->x_input > $size || $this->y_input > $size)
    {
       
// Wide
       
if($this->x_input >= $this->y_input)
        {
           
$this->x_output = $size;
           
$this->y_output = ($this->x_output / $this->x_input) * $this->y_input;
        }
       
// Tall
       
else
        {
           
$this->y_output = $size;
           
$this->x_output = ($this->y_output / $this->y_input) * $this->x_input;
        }
       
// Ready
       
$this->resize = TRUE;
    }
   
// Don't resize
   
else { $this->resize = FALSE; }
}
?>
up
0
swizec at swizec dot com
5 years ago
Wrote a function for sanitising user uploaded images. It saves the native image in size roughly 800x600 so it still fits on most screens when opened, makes a desired size thumbnail and turns all images into high quality jpegs for smaller bandwidth use.

Thumbnails are made in a similar way a designer would make them in photoshop, first resize the most troublesome dimension to desired size, then crop the rest out so the image retains proportions and most of it ends up in the thumbnail.

<?php

// $image is $_FILES[ <image name> ]
// $imageId is the id used in a database or wherever for this image
// $thumbWidth and $thumbHeight are desired dimensions for the thumbnail
function processImage( $image, $imageId, $thumbWidth, $thumbHeight )
{
   
$type = $image[ 'type' ];
   
$galleryPath = 'images/collection/';
   
    if (
strpos( $type, 'image/' ) === FALSE )
    {
// not an image
       
return FALSE;
    }
   
$type = str_replace( 'image/', '', $type );
   
$createFunc = 'imagecreatefrom' . $type;
   
   
$im = $createFunc( $image[ 'tmp_name' ] );
   
   
$size = getimagesize( $image[ 'tmp_name' ] );
   
   
$w = $size[ 0 ];
   
$h = $size[ 1 ];
    if (
$w > 800 || $h > 600 )
    {
// we make sure the image isn't too huge
       
if ( $w > 800 )
        {
           
$nw = 800;
           
$nh = ceil( $nw*($h/$w) );
        }elseif(
$h > 600 )
        {
           
$nh = 600;
           
$nw = ceil( $nh*($w/$h) );
        }
       
       
$im2 = imagecreatetruecolor( $nw, $nh );
       
imagecopyresampled( $im2, $im, 0, 0, 0, 0, $nw, $nh, $w, $h );
       
imagedestroy( $im );
       
       
$im = $im2;
       
$w = $nw;
       
$h = $nh;
    }
   
   
// create thumbnail
   
$tw = $thumbWidth;
   
$th = $thumbHeight;
   
$imT = imagecreatetruecolor( $tw, $th );
   
    if (
$tw/$th > $th/$tw )
    {
// wider
       
$tmph = $h*($tw/$w);
       
$temp = imagecreatetruecolor( $tw, $tmph );
       
imagecopyresampled( $temp, $im, 0, 0, 0, 0, $tw, $tmph, $w, $h ); // resize to width
       
imagecopyresampled( $imT, $temp, 0, 0, 0, $tmph/2-$th/2, $tw, $th, $tw, $th ); // crop
       
imagedestroy( $temp );
    }else
    {
// taller
       
$tmpw = $w*($th/$h );
       
$imT = imagecreatetruecolor( $tmpw, $th );
       
imagecopyresampled( $imT, $im, 0, 0, 0, 0, $tmpw, $h, $w, $h ); // resize to height
       
imagecopyresampled( $imT, $temp, 0, 0, $tmpw/2-$tw/2, 0, $tw, $th, $tw, $th ); // crop
       
imagedestroy( $temp );
    }
   
   
// save the image
   
imagejpeg( $im, $galleryPath . $imgid . '.jpg', 100 );
   
imagejpeg( $imT, $galleryPath . $imgid . '_thumb.jpg', 100 );
}

?>
up
0
mattura gmail com
5 years ago
Here's a little function I wrote to resize images to a maximum dimension - based on what facebook does in the galleries. You put in a source, destination and a maximum dimension in pixels (eg 300), and for example if the image is long and thin, the longest edge will be 300px, yet the image retains proportions. A square image will become 300x300, a 6x4 (landscape) will become 300x200, a 4x6 (portrait) - 200x300 etc.
It works on jpg images, but other formats can easily be added.
<?php
function createThumb($spath, $dpath, $maxd) {
 
$src=@imagecreatefromjpeg($spath);
 if (!
$src) {return false;} else {
 
$srcw=imagesx($src);
 
$srch=imagesy($src);
  if (
$srcw<$srch) {$height=$maxd;$width=floor($srcw*$height/$srch);}
  else {
$width=$maxd;$height=floor($srch*$width/$srcw);}
  if (
$width>$srcw && $height>$srch) {$width=$srcw;$height=$srch;}  //if image is actually smaller than you want, leave small (remove this line to resize anyway)
 
$thumb=imagecreatetruecolor($width, $height);
  if (
$height<100) {imagecopyresized($thumb, $src, 0, 0, 0, 0, $width, $height, imagesx($src), imagesy($src));}
  else {
imagecopyresampled($thumb, $src, 0, 0, 0, 0, $width, $height, imagesx($src), imagesy($src));}
 
imagejpeg($thumb, $dpath);
  return
true;
 }
}
?>
up
0
arnar at netvistun dot is
6 years ago
A small thumb script. Lets you specify max height and width. The thumb will always be of a rectangular shape while the image itself retains it's proportions. Very clean.

<?php
// The file
$filename = 'a.jpg';

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

$thumbsize = 80;

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

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

$ratio_orig = $width_orig/$height_orig;

if (
$width/$height > $ratio_orig) {
  
$width = $height*$ratio_orig;
} else {
  
$height = $width/$ratio_orig;
}

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

// Output
imagejpeg($image_p, null, 100);
?>
up
0
rayg at daylongraphics dot com
6 years ago
Here's a simple function to resample one JPEG imagefile to another while keeping aspect ratio of the source within the destination's dimensions. You can also tune the allowable distortion if you end up making too many thumbnails with thin blank areas around them. Should work when enlarging images too. Function returns true if it worked, false if not.

function resample_picfile($src, $dst, $w, $h)
{
    // If distortion stretching is within the range below,
    // then let image be distorted.
    $lowend = 0.8;
    $highend = 1.25;

    $src_img = imagecreatefromjpeg($src);
    if($src_img)
    {
        $dst_img = ImageCreateTrueColor($w, $h);
        /* if you don't want aspect-preserved images
to have a black bkgnd, fill $dst_img with the color of your choice here.
        */

        if($dst_img)
        {
            $src_w = imageSX($src_img);
            $src_h = imageSY($src_img);

            $scaleX = (float)$w / $src_w;
            $scaleY = (float)$h / $src_h;
            $scale = min($scaleX, $scaleY);

            $dstW = $w;
            $dstH = $h;
            $dstX = $dstY = 0;

            $scaleR = $scaleX / $scaleY;
            if($scaleR < $lowend || $scaleR > $highend)
            {
                $dstW = (int)($scale * $src_w + 0.5);
                $dstH = (int)($scale * $src_h + 0.5);

                // Keep pic centered in frame.
                $dstX = (int)(0.5 * ($w - $dstW));
                $dstY = (int)(0.5 * ($h - $dstH));
            }
           
            imagecopyresampled(
                $dst_img, $src_img, $dstX, $dstY, 0, 0,
                $dstW, $dstH, $src_w, $src_h);
            imagejpeg($dst_img, $dst);
            imagedestroy($dst_img);
        }
        imagedestroy($src_img);
        return file_exists($dst);
    }
    return false;
}
up
0
RandomFeatureRequest
6 years ago
If anyone felt like implementing Bicubic Sharper and/or Bicubic Smoother, that would seriously rock.
up
0
wm at violet dot bg
6 years ago
This is a fixed version of ImageCopyResampledBicubic posted by liviu.malaescu
The original version wasn't respecting src_x & src_y args

<?php
   
function ImageCopyResampledBicubic(&$dst_image, &$src_image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h)  {
       
// we should first cut the piece we are interested in from the source
       
$src_img = ImageCreateTrueColor($src_w, $src_h);
       
imagecopy($src_img, $src_image, 0, 0, $src_x, $src_y, $src_w, $src_h);

       
// this one is used as temporary image
       
$dst_img = ImageCreateTrueColor($dst_w, $dst_h);

       
ImagePaletteCopy($dst_img, $src_img);
       
$rX = $src_w / $dst_w;
       
$rY = $src_h / $dst_h;
       
$w = 0;
        for (
$y = 0; $y < $dst_h; $y++)  {
           
$ow = $w; $w = round(($y + 1) * $rY);
           
$t = 0;
            for (
$x = 0; $x < $dst_w; $x++)  {
               
$r = $g = $b = 0; $a = 0;
               
$ot = $t; $t = round(($x + 1) * $rX);
                for (
$u = 0; $u < ($w - $ow); $u++)  {
                    for (
$p = 0; $p < ($t - $ot); $p++)  {
                       
$c = ImageColorsForIndex($src_img, ImageColorAt($src_img, $ot + $p, $ow + $u));
                       
$r += $c['red'];
                       
$g += $c['green'];
                       
$b += $c['blue'];
                       
$a++;
                    }
                }
               
ImageSetPixel($dst_img, $x, $y, ImageColorClosest($dst_img, $r / $a, $g / $a, $b / $a));
            }
        }

       
// apply the temp image over the returned image and use the destination x,y coordinates
       
imagecopy($dst_image, $dst_img, $dst_x, $dst_y, 0, 0, $dst_w, $dst_h);

       
// we should return true since ImageCopyResampled/ImageCopyResized do it
       
return true;
    }
?>
up
0
Michael Shepanski
6 years ago
Here is a function I thought I would share that will resample and copy an image with rounded corners.

<?php
/** ------------------------------------------------------------
 * Copy and resample an image with rounded corners.
 * ----------------------------------------------------------- */
function imageRoundedCopyResampled(&$dstimg, &$srcimg, $dstx, $dsty, $srcx,
                                  
$srcy, $dstw, $dsth, $srcw, $srch, $radius) {
   
# Resize the Source Image
   
$srcResized = imagecreatetruecolor($dstw, $dsth);
   
imagecopyresampled($srcResized, $srcimg, 0, 0, $srcx, $srcy,
                      
$dstw, $dsth, $srcw, $srch);
   
# Copy the Body without corners
   
imagecopy($dstimg, $srcResized, $dstx+$radius, $dsty,
             
$radius, 0, $dstw-($radius*2), $dsth);
   
imagecopy($dstimg, $srcResized, $dstx, $dsty+$radius,
             
0, $radius, $dstw, $dsth-($radius*2));
   
# Create a list of iterations; array(array(X1, X2, CenterX, CenterY), ...)
    # Iterations in order are: Top-Left, Top-Right, Bottom-Left, Bottom-Right
   
$iterations = array(
        array(
0, 0, $radius, $radius),
        array(
$dstw-$radius, 0, $dstw-$radius, $radius),
        array(
0, $dsth-$radius, $radius, $dsth-$radius),
        array(
$dstw-$radius, $dsth-$radius, $dstw-$radius, $dsth-$radius)
    );
   
# Loop through each corner 'iteration'
   
foreach($iterations as $iteration) {
        list(
$x1,$y1,$cx,$cy) = $iteration;
        for (
$y=$y1; $y<=$y1+$radius; $y++) {
            for (
$x=$x1; $x<=$x1+$radius; $x++) {
               
# If length (X,Y)->(CX,CY) is less then radius draw the point
               
$length = sqrt(pow(($cx - $x), 2) + pow(($cy - $y), 2));
                if (
$length < $radius) {
                   
imagecopy($dstimg, $srcResized, $x+$dstx, $y+$dsty,
                             
$x, $y, 1, 1);
                }
            }
        }
    }
}
?>
up
0
matt1walsh DESPAMMER gmail dot com
6 years ago
None of the stuff I've seen for resizing transparent GIFs works consistently and yields a good image. The hack I thought of is silly, but it works okay -- convert GIF to PNG. This worked for me.

$g_iw is new image width
$g_ih is new image height

$img_src=imagecreatefromgif($g_srcfile);
$img_dst=imagecreatetruecolor($g_iw,$g_ih);

//preserve alpha
imagecolortransparent($img_dst, imagecolorallocate($img_dst, 0, 0, 0));
imagealphablending($img_dst, false);
imagesavealpha($img_dst, true);
imagecopyresampled($img_dst, $img_src, 0, 0, 0, 0, $g_iw, $g_ih, $g_is[0], $g_is[1]);

imagepng($img_dst, $g_dstfile);
imagedestroy($img_dst);
up
0
Dave McCourt
6 years ago
This function is taken from lots of web sources so thanks to all for posting. It creates square or landscape thumbnails from .jpgs  from either portait or landscape original images. I decide in advance which way I want the thumbs to display for consistency. I usually sharpen the images as well post-upload, to save on server resources. I can post this code if anyone wants it. I hope this helps someone...

    # create thumbnails from jpgs
    # usage:
    # create_jpgthumb(uploaded file, final file (with path), thumb height, thumb width, jpg quality, scale thumb (true) or fixed size (false);
    function create_jpgthumb($original, $thumbnail, $max_width, $max_height, $quality, $scale = true) {
       
        list ($src_width, $src_height, $type, $w) = getimagesize($original);
       
        if (!$srcImage = @imagecreatefromjpeg($original)) {
            return false;
        }

        # image resizes to natural height and width
        if ($scale == true) {
                       
            if ($src_width > $src_height ) {
                $thumb_width = $max_width;
                $thumb_height = floor($src_height * ($max_width / $src_width));
            } else if ($src_width < $src_height ) {
                $thumb_height = $max_height;
                $thumb_width = floor($src_width * ($max_height / $src_height));
            } else {
                $thumb_width = $max_height;
                $thumb_height = $max_height;
            }

            if (!@$destImage = imagecreatetruecolor($thumb_width, $thumb_height)) {
                return false;
            }
           
            if (!@imagecopyresampled($destImage, $srcImage, 0, 0, 0, 0, $thumb_width, $thumb_height, $src_width, $src_height)) {
                return false;
            }
                       
        # image is fixed to supplied width and height and cropped
        } else if ($scale == false) {
       
            $ratio = $max_width / $max_height;
               
            # thumbnail is landscape
             if ($ratio > 1) {
            
                # uploaded pic is landscape
                if ($src_width > $src_height) {

                    $thumb_width = $max_width;
                    $thumb_height = ceil($max_width * ($src_height / $src_width));
                   
                    if ($thumb_height > $max_width) {
                        $thumb_height = $max_width;
                        $thumb_width = ceil($max_width * ($src_width / $src_height));
                    }

                # uploaded pic is portrait
                } else {
               
                    $thumb_height = $max_width;
                    $thumb_width = ceil($max_width * ($src_height / $src_width));
                   
                    if ($thumb_width > $max_width) {
                        $thumb_width = $max_width;
                        $thumb_height = ceil($max_width * ($src_height / $src_width));
                    }
                   
                    $off_h = ($src_height - $src_width) / 2;
           
                }
   
                if (!@$destImage = imagecreatetruecolor($max_width, $max_height)) {
                    return false;
                }
       
                if (!@imagecopyresampled($destImage, $srcImage, 0, 0, 0, $off_h, $thumb_width, $thumb_height, $src_width, $src_height)) {
                    return false;
                }

            # thumbnail is square
             } else {
            
                if ($src_width > $src_height) {
                    $off_w = ($src_width - $src_height) / 2;
                    $off_h = 0;
                    $src_width = $src_height;
                } else if ($src_height > $src_width) {
                    $off_w = 0;
                    $off_h = ($src_height - $src_width) / 2;
                    $src_height = $src_width;
                } else {
                    $off_w = 0;
                    $off_h = 0;
                }

                if (!@$destImage = imagecreatetruecolor($max_width, $max_height)) {
                    return false;
                }
       
                if (!@imagecopyresampled($destImage, $srcImage, 0, 0, $off_w, $off_h, $max_width, $max_height, $src_width, $src_height)) {
                    return false;
                }

             }
        
                           
        }
       
        @imagedestroy($srcImage);

        if (!@imageantialias($destImage, true)) {
            return false;
        }
       
        if (!@imagejpeg($destImage, $thumbnail, $quality)) {
            return false;
        }
                       
        @imagedestroy($destImage);
       
        return true;
    }
up
0
tim dot daldini at gmail dot be
6 years ago
Tim's function is a whole lot faster, however, the quality setting doesnt seem right since resizing very big images doesnt affect quality of the resulting thumbnails that much on quality 1 for example.

Anyone has figured out how to use a more correct quality setting by comparing image surfaces (for example) basing on Tim's function?

images with a total of 10Megapixels that contain 5Megapixels when resized should use the same quality setting like images that contain 1Megapixels but only 0.5 when resized.

Not hard to understand, but the memoryload would be a lot lower if the function could decide to use a setting of quality 1 automatically when resizing big images to small thumbnails. This would be handy especially when using the function for images of various sizes in the same application.
up
0
eblejr AT phrebh DOT com
6 years ago
Tim's code is fast, but if you're trying to put resampled images anywhere but in the top-left corner, it doesn't work.
up
0
Blendermf
6 years ago
tim, your resampling gives me better results than the gd function. It looks just as good as what my image resizing software does.
up
0
kristijan at leftor dot ba
6 years ago
There is bug in POST from tim at leethost dot com
25-Jan-2007 02:00.

Function work correctly when you making thumb from 0,0 to width/height. But if you want copy resized picture to other coordinates then you must change code in this:

function fastimagecopyresampled (&$dst_image, $src_image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h, $quality = 3) {
 if (empty($src_image) || empty($dst_image)) { return false; }
 if ($quality <= 1)
 {
   $temp = imagecreatetruecolor ($dst_w + 1, $dst_h + 1);
   imagecopyresized ($temp, $src_image, $dst_x, $dst_y, $src_x, $src_y, $dst_w + 1, $dst_h + 1, $src_w, $src_h);
   imagecopyresized ($dst_image, $temp, 0, 0, 0, 0, $dst_w, $dst_h, $dst_w, $dst_h);
   imagedestroy ($temp);
 }
 elseif ($quality < 5 && (($dst_w * $quality) < $src_w || ($dst_h * $quality) < $src_h))
 {
   $tmp_w = $dst_w * $quality;
   $tmp_h = $dst_h * $quality;
   $temp = imagecreatetruecolor ($tmp_w + 1, $tmp_h + 1);
   imagecopyresized ($temp, $src_image, 0, 0, $src_x, $src_y, $tmp_w + 1, $tmp_h + 1, $src_w, $src_h);
   imagecopyresampled ($dst_image, $temp, $dst_x, $dst_y, 0, 0, $dst_w, $dst_h, $tmp_w, $tmp_h);
   imagedestroy ($temp);
 } else
 {
   imagecopyresampled ($dst_image, $src_image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);
 }
 return true;
}
up
0
rich at corephp dot co dot uk
6 years ago
Be wary of this function when resizing images to make them *larger* than the original due to the memory consumption rate. For example a 200KB JPEG file (1024x768) will take up 4MB of memory when loaded, but when resampled to twice the the size the memory use jumps to 20.1MB. imagecopyresized does the same. Allow approx. 5 bytes per *pixel* for memory allowance when dealing with true colour images.
up
0
tim at leethost dot com
7 years ago
Here's a simple plug-and-play replacement to imagecopyresampled that will deliver results that are almost identical except MUCH faster (very typically 30 times faster).  I've been using this function for a few years but figured everyone could benefit from it.

For example, a 10 megapixel camera image (3872x2592 resolution) converted to thumbnail size using the default quality is 60 times faster than using imagecopyresampled (only 0.15 seconds from 8.9 seconds) and the image quality is almost identical.  There's also an optional "quality" parameter that allows you to select the quality you want (1 is lowest quality but fastest, 5 is highest quality but slowest, 3 is default).  All existing imagecopyresampled parameters fully work so it's truly plug-and-play.  It also automatically decides if it would be better to just use imagecopyresampled depending on source and destination image sizes.

My image analysis shows imagecopyresized renders on average 2.4% of pixels significantly different than imagecopyresampled.  These significantly different pixels give imagecopyresized the jagged, blocky, aliasing look.  Using fastimagecopyresampled with a quality of 2, the significantly different pixel rate is reduced to 0.8%.  With a quality of 3 (the default) it's reduced to 0.5% and at a quality of 4 it's reduced to only 0.03% but is still very typically 10-15 times faster for thumbnail creation.

Enjoy!

<?
function fastimagecopyresampled (&$dst_image, $src_image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h, $quality = 3) {
 
// Plug-and-Play fastimagecopyresampled function replaces much slower imagecopyresampled.
  // Just include this function and change all "imagecopyresampled" references to "fastimagecopyresampled".
  // Typically from 30 to 60 times faster when reducing high resolution images down to thumbnail size using the default quality setting.
  // Author: Tim Eckel - Date: 12/17/04 - Project: FreeRingers.net - Freely distributable.
  //
  // Optional "quality" parameter (defaults is 3).  Fractional values are allowed, for example 1.5.
  // 1 = Up to 600 times faster.  Poor results, just uses imagecopyresized but removes black edges.
  // 2 = Up to 95 times faster.  Images may appear too sharp, some people may prefer it.
  // 3 = Up to 60 times faster.  Will give high quality smooth results very close to imagecopyresampled.
  // 4 = Up to 25 times faster.  Almost identical to imagecopyresampled for most images.
  // 5 = No speedup.  Just uses imagecopyresampled, highest quality but no advantage over imagecopyresampled.

 
if (empty($src_image) || empty($dst_image)) { return false; }
  if (
$quality <= 1) {
   
$temp = imagecreatetruecolor ($dst_w + 1, $dst_h + 1);
   
imagecopyresized ($temp, $src_image, $dst_x, $dst_y, $src_x, $src_y, $dst_w + 1, $dst_h + 1, $src_w, $src_h);
   
imagecopyresized ($dst_image, $temp, 0, 0, 0, 0, $dst_w, $dst_h, $dst_w, $dst_h);
   
imagedestroy ($temp);
  } elseif (
$quality < 5 && (($dst_w * $quality) < $src_w || ($dst_h * $quality) < $src_h)) {
   
$tmp_w = $dst_w * $quality;
   
$tmp_h = $dst_h * $quality;
   
$temp = imagecreatetruecolor ($tmp_w + 1, $tmp_h + 1);
   
imagecopyresized ($temp, $src_image, $dst_x * $quality, $dst_y * $quality, $src_x, $src_y, $tmp_w + 1, $tmp_h + 1, $src_w, $src_h);
   
imagecopyresampled ($dst_image, $temp, 0, 0, 0, 0, $dst_w, $dst_h, $tmp_w, $tmp_h);
   
imagedestroy ($temp);
  } else {
   
imagecopyresampled ($dst_image, $src_image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);
  }
  return
true;
}
?>
up
0
mr bitmap
7 years ago
For all those that are using imagecreatefromwbmp() for.BMP files, I believe you are wrong.

imagecreatefromwbmp() is for WBMP image files used for WAP devices not windows BMP images.

I don't think PHP has any built in Windows BMP functions.

There are many examples here that make this mistake.

See the documentation for imagecreatefromwbmp()
up
0
caio at daisuki dot com dot br
7 years ago
Ok guys, the ultimate image merging tool, enjoy:

  function watermark($sourcefile, $watermarkfiles, $destination, $quality=90) {
  /*
 
    $sourcefile = Filename of the picture to be watermarked.
    $watermarkfile = files to add. Each is: array ( 'filename' => filename , 'position' => position to show(array), 'resample' => new dimension(array) )
       You can omit any except filename
    $destination = jpg or png file to output (jpg if source is jpg, png if source is png). Send blank to direct output 
    Sample:
 
    $batch = array ( array ( 'filename' => "watermark.png",
                             'position' => array(100,0),
                           ),
                    array ( 'filename' => "brilho.png",
                            'position' => array(200,200),
                            'resample' => array(30,30)
                           )
                   );
    watermark("picture.jpg", $batch, "", 90); <--  will add both images in bath on top of picture, preserving transparency
 
  */
 
  $ih = getimagesize($sourcefile);
  $ispng = $ih[2] == 3;
  if ($ispng)
    $sourcefile_id = imagecreatefrompng($sourcefile);
  else
    $sourcefile_id = imagecreatefromjpeg($sourcefile);
  
  $sourcefile_width=imageSX($sourcefile_id);
  $sourcefile_height=imageSY($sourcefile_id);  
 
  foreach ($watermarkfiles as $x => $watermarkfile) {
    $watermarkfile_id = imagecreatefrompng($watermarkfile['filename']);
    imageAlphaBlending($watermarkfile_id, false);
    imageSaveAlpha($watermarkfile_id, true);    
    $watermarkfile_width=imageSX($watermarkfile_id);
    $watermarkfile_height=imageSY($watermarkfile_id);
   
    // resample?
    if (isset($watermarkfile['resample'])) {
      $im_dest = imagecreatetruecolor ($watermarkfile['resample'][0], $watermarkfile['resample'][1]);
      imagealphablending($im_dest, false);
      imagecopyresampled($im_dest, $watermarkfile_id, 0, 0, 0, 0, $watermarkfile['resample'][0], $watermarkfile['resample'][1], $watermarkfile_width, $watermarkfile_height);
      imagesavealpha($im_dest, true);
      imagedestroy($watermarkfile_id);
      $watermarkfile_id = $im_dest;
      $watermarkfile_width = $watermarkfile['resample'][0];
      $watermarkfile_height = $watermarkfile['resample'][1];
    }
   
    // position ? if none given, centered
    if (isset($watermarkfile['position']))
      list($dest_x,$dest_y) = $watermarkfile['position'];
    else {
      $dest_x = ( $sourcefile_width / 2 ) - ( $watermarkfile_width / 2 ); // centered
      $dest_y = ( $sourcefile_height / 2 ) - ( $watermarkfile_height / 2 ); // centered
    }
   
    imagecopy($sourcefile_id, $watermarkfile_id, $dest_x, $dest_y, 0, 0, $watermarkfile_width, $watermarkfile_height);
    imagedestroy($watermarkfile_id);
  }
  if ($ispng)
    imagepng($sourcefile_id,$destination);
  else
    imagejpeg($sourcefile_id,$destination,$quality);
  imagedestroy($sourcefile_id);
}
up
0
spencejames2000 at yahoo dot co dot uk
7 years ago
For anyone suffering from the srcX and srcY bug (some versions of gd ignore them completely - see http://bugs.php.net/bug.php?id=12780 for details), a quick solution is to use this code snippet:

<?php
function imgcopyresampled(&$dst_img, $src_img, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h)
{
   
$tmp_img = imagecreatetruecolor($src_w, $src_h);
   
$rv2 = imagecopy($tmp_img, $src_img, 0,0, $src_x, $src_y, $src_w, $src_h);
   
$rv1 = imagecopyresampled($dst_img, $tmp_img, $dst_x,$dst_y, 0,0, $dst_w, $dst_h, $src_w, $src_h);
   
imagedestroy($tmp_img);
    return(
$rv1 and $rv2);
}
?>

By using imagecopy to extract the relevant portion of the source image, it works a lot more quickly than pike's solution below, and also without the extra blur.

It may be useful to use override_function in existing projects, although I have not tested this myself.
up
0
Tyron Madlener (tyron.at)
7 years ago
Creating a thumbnail (120x90 pixel) of a big image (3000x2000 pixel) took me about 5 seconds with imagecopyresampled()

Thats pretty much, so I tested a little how I could improve the speed. I found that imagecopyresized is way faster but results in poor quality.
So I combined both - I first reduce the big image via imagecopyresized to 1024x768 pixel and then create the small thumbnail via imagecopyresampled. The resulting quality is almost the same. In my tests, resizing took only about 2.2 seconds now - twice as fast :)

I also tried using that bicubic image resizing function in some earlier post here, but it was only faster when the thumbnails were smaller than 120x90 and the quality was not very good.

Here's the code if you wanna (I guess there are still a few possibilites to do some more optimiztions tough):

<?php
function CreateThumb($file,$maxwdt,$maxhgt, $dest) {
    list(
$owdt,$ohgt,$otype)=@getimagesize($file);

  switch(
$otype) {
    case
1$newimg=imagecreatefromgif($file); break;
    case
2$newimg=imagecreatefromjpeg($file); break;
    case
3$newimg=imagecreatefrompng($file); break;
    default: echo
"Unkown filetype (file $file, typ $otype)"; return;
  }
   
  if(
$newimg) {
    if(
$owdt>1500 || $ohgt>1200)
            list(
$owdt, $ohgt) = Resample($newimg, $owdt, $ohgt, 1024,768,0);
           
   
Resample($newimg, $owdt, $ohgt, $maxwdt, $maxhgt);
       
        if(!
$dest) return $newimg;
       
        if(!
is_dir(dirname($dest)))
           
mkdir(dirname($dest));
   
    switch(
$otype) {
      case
1: imagegif($newimg,dest); break;    
      case
2: imagejpeg($newimg,$dest,90); break;
      case
3: imagepng($newimg,$dest);  break;
    }
       
       
imagedestroy($newimg);
   
   
chmod($dest,0644);
  }
}

function
Resample(&$img, $owdt, $ohgt, $maxwdt, $maxhgt, $quality=1) {
  if(!
$maxwdt) $divwdt=0;
   else
$divwdt=Max(1,$owdt/$maxwdt);
  
  if(!
$maxhgt) $divhgt=0;
   else
$divhgt=Max(1,$ohgt/$maxhgt);
   
  if(
$divwdt>=$divhgt) {
   
$newwdt=$maxwdt;
   
$newhgt=round($ohgt/$divwdt);
  } else {
   
$newhgt=$maxhgt;
   
$newwdt=round($owdt/$divhgt);
  }
   
   
$tn=imagecreatetruecolor($newwdt,$newhgt);
    if(
$quality)
       
imagecopyresampled($tn,$img,0,0,0,0,$newwdt,$newhgt,$owdt,$ohgt);       
    else
       
imagecopyresized($tn,$img,0,0,0,0,$newwdt,$newhgt,$owdt,$ohgt);

   
imagedestroy($img);
   
   
$img = $tn;
   
    return array(
$newwdt, $newhgt);
}
?>
up
0
mracek at xko dot cz
8 years ago
Here is function which:
- resize and crop (crop format 4:3 or 1:1)
- methode resample/resize
- open jpg, gif, bmp, png
- save jpg (85%), gif, bmp, png
- show images

$FILE_MIMES = array(
'image/pjpeg'=>"jpg",
'image/jpeg'=>"jpg",
'image/jpg'=>"jpg",
'image/png'=>"png",
'image/x-png'=>"png",
'image/gif'=>"gif",
'image/bmp'=>"bmp");
$FILE_EXTS  = array('.jpeg','.jpg','.png','.gif','.bmp');
$MAX_SIZE  = 16777216;

$lng=array(
's_imgDimension'=>array(
       "80",
       "320"
       ),
's_imgCrop'    =>array(
       "- auto -",
       "na sirku",
       "na vysku",
       "ctverec",
       "- zadne -"
       ),
's_imgFormat'    =>array(
       "4/3",
       "1/1"
       ),
's_imgType'    =>array(
       "jpg",
       "png",
       "gif",
       "bmp"
       ),
's_imgMethode'    =>array(
       "resample",
       "resize"
       )
);

function PPimageTransform($photo1,$type1,$dim,$crop,
$format,$methode,$photo2,$type2)
{
if ($photo1!=="" && File_Exists($photo1))
{
   if (!($crop>0 && $crop<5)) $crop=0;
   width=x"
   list($w,$h) = GetImageSize($photo1);
   $w=($w<1)?1:$w;
   $h=($h<1)?1:$h;
   $wh=$w/$h;

   // format
   $format=($format=='4/3')?4/3:1;

   // auto crop
   if ($crop==0)
       {
       $z1=$format-  ($format-1)/2;
       $z2=$format+(1-$format-1)/2;
           if ($wh>$z1) {$crop=1;}
       elseif ($wh<$z2) {$crop=2;}
       else        {$crop=3;}
       }

   // scale
   if ($crop==4)
       {
       $a=$w>$h?$w:$h;
       $scale=$dim/$a;
       $nw=$w*$scale;$nw=($nw<1)?1:$nw;
       $nh=$h*$scale;$nh=($nh<1)?1:$nh;

       $d=array(0,0,floor($nw),floor($nh));
       $s=array(0,0,$w,$h);
       }
   else
       {
           if ($crop==3) {$nw=1;$nh=1;}
       elseif ($crop==2) {$nw=1/$format;$nh=1;}
       elseif ($crop==1) {$nw=1;$nh=1/$format;}
       $nw*=$dim;$nw=($nw<1)?1:$nw;
       $nh*=$dim;$nh=($nh<1)?1:$nh;
 
       $s1=$nw/$w;
       $s2=$nh/$h;
       $h1=$nh*$s1;
       $w2=$nw*$s2;

       $s1=($h1<=$nh)?$s1:0;
       $s2=($w2<=$nw)?$s2:0;
       $scale=($s1>$s2)?$s1:$s2;
       $scale=($scale<=0)?1:$scale;

       $d=array(0,0,floor($nw),floor($nh));
       $x1=floor(($w-$d[2]/$scale)/2);$x1=$x1<0?0:$x1;
       $y1=floor(($h-$d[3]/$scale)/2);$y1=$y1<0?0:$y1;
       $s=array($x1,$y1,floor($w-2*$x1),floor($h-2*$y1));
       }

   // input/output
   switch($type1)
       {
       case 'jpg': $imgIn = ImageCreateFromJPEG; break;
       case 'png': $imgIn = ImageCreateFromPNG;  break;
       case 'gif': $imgIn = ImageCreateFromGIF;  break;
       case 'bmp': $imgIn = ImageCreateFromWBMP; break;
       default: return FALSE; break;
       }
   switch($type2)
       {
       case 'jpg': $imgOut = ImageJPEG; break;
       case 'png': $imgOut = ImagePNG;  break;
       case 'gif': $imgOut = ImageGIF;  break;
       case 'bmp': $imgOut = ImageWBMP; break;
       default: return FALSE; break;
       }

   // resample (d-destination, s-source)
   $image1 = $imgIn($photo1);
   if ($methode==0)
       {
       $image2 = ImageCreateTruecolor($d[2],$d[3]);
       ImageCopyResampled($image2, $image1,
 $d[0],$d[1], $s[0],$s[1], $d[2],$d[3], $s[2],$s[3]);
       }
   else    {
       $image2 = ImageCreate($d[2],$d[3]);
       ImageCopyResized($image2, $image1,
$d[0],$d[1], $s[0],$s[1], $d[2],$d[3], $s[2],$s[3]);
       }

   // output
   if ($type2=='jpg')
       {$imgOut($image2,$photo2,85);}
   else    {$imgOut($image2,$photo2);}
   ImageDestroy($image2);
   ImageDestroy($image1);
   }
}
up
0
dmitry at dest dot by
8 years ago
Simple script on change of width and automatic creation of height, and also creation of the signature in the right we string to a corner. (Only for Jpg)

function easyResize($img_sourse, $save_to, $quality, $width, $str) {
$size = GetImageSize($img_sourse);
    $im_in = ImageCreateFromJPEG($img_sourse);
   
    $new_height = ($width * $size[1]) / $size[0]; // Generate new height for image
    $im_out = imagecreatetruecolor($width, $new_height);
   
    ImageCopyResampled($im_out, $im_in, 0, 0, 0, 0, $width, $new_height, $size[0], $size[1]);
       
    #Find X & Y for note
    $X_var = ImageSX($im_out);
    $X_var = $X_var - 130;
    $Y_var = ImageSY($im_out);
    $Y_var = $Y_var - 25;

    #Color
    $white = ImageColorAllocate($im_out, 0, 0, 0);
   
    #Add note(simple: site address)
    ImageString($im_out,2,$X_var,$Y_var,$str,$white);

    ImageJPEG($im_out, $save_to, $quality); // Create image
    ImageDestroy($im_in);
    ImageDestroy($im_out);
}

// $str -  Inscription on the image;
up
0
areddan at silverarm dot ie
8 years ago
$file =$_FILES[userfile];
//name of the input form file upload element is userfile

//$to_file is a full path including filename
//to where you want the thumnail to be copied to .
//example /usr/www/users/www/images/thumbs/thumb1.jpg

copy($file[tmp_name],$to_file) or die("The file $file[tmp_name] you are trying to upload couldn't be copied to $to_file");

//Extra stuff to put into the output to allow for jpeg / png or gif

//replace line: imagegif($thumb2, $fileout); //write to file with the following

switch($format)
       {
           case 'image/jpeg':
           imagejpeg($thumb2, $fileout,90); //write to file
           break;
           case 'image/gif';
           imagegif($thumb2, $fileout); //write to file
           break;
           case 'image/png':
           imagepng($thumb2, $fileout); //write to file
           break;
       }
up
0
com.hotmail@backglancer
8 years ago
wrote this for a game I was helping develop:

Auto Tile Maker -- takes the image and cuts it in several smaller pieces, deleting the original... i mean.. this is just for those of you who are lazy, coz the script is simple..
modify at will.

<?
// $newfile is the full address of your newly uploaded file
// $floc = is the location of that file ending with /
// $t is the $_FILES['blah'] of your uploaded file.
// whatever... you guys understand enough to modify this code

$size = getimagesize($newfile);
list(
$w, $h) = $size;

if (
$h > 20 || $w > 20) {
   
$type = array_pop($size);
    switch (
$type) {
        case
'image/jpeg' : $src_image = imagecreatefromjpeg($newfile); break;
       
// insert more cases here :) i'm lazy too
       
default : echo 'not an image!'; return;
    }

   
$i = 0;
    for (
$y = 0; $y < $h; $y += 20) {
    for (
$x = 0; $x < $w; $x += 20) {
       
$i++; // new file names will be like 1monkey.gif 2monkey.gif etc..
       
$new_image = imagecreatetruecolor(20, 20);

       
imagecopyresampled ($new_image, $src_image,
           
0, 0,
           
$x, $y,
           
20, 20,
           
20, 20
           
);
       
imagegif($new_image, $floc.$i.$t['name']);
       
imagedestroy($new_image);

    }
// x
   
} // y
   
unlink($newfile);
}
?>
up
0
smrtak at 4um dot cz
8 years ago
class cobrazek
    {
        function resizeMaxJpeg($file,$mx,$my,$q=85)
        {
            $dst = cobrazek::resizeMax(imagecreatefromjpeg($file),$mx,$my);
            if(!$dst)
                return false;
            if(!imagejpeg($dst,$file,$q))
                return false;
            return true;
        }
        function resizeMax($src,$mx,$my)
        {
            //zjisti velikost
            $sx = imagesx($src);
            $sy = imagesy($src);
            //spocitej cilovou velikost
            $v = min(min($mx,$sx)/$sx,min($my,$sy)/$sy);
            $dx = $v*$sx;
            $dy = $v*$sy;
            $dst = imagecreatetruecolor($dx,$dy);
            //resample
            imagecopyresampled ($dst,$src,0,0,0,0,$dx,$dy,$sx,$sy);
            //vystup
            return $dst;
        }
    }
up
0
pike-php at kw dot nl
8 years ago
If you have a bug that imagecopyresampled is completely ignoring srcX and srcY (a known and closed bug - http://bugs.php.net/bug.php?id=12780)  you can ofcourse apply two operations to do the same. E.g., instead of saying

ImageCopyResampled($dst_img, $src_img, 0, 0, $srcX, $srcY, $dstW, $dstH, $srcW, $srcH);

you can say

ImageCopyResampled($tmp_img, $src_img, -$srcX, -$srcY, "BUG","BUG", $orgW, $orgH, $orgW, $orgH);
ImageCopyResampled($dst_img, $tmp_img, 0, 0, "BUG","BUG", $dstW, $dstH, $srcW, $srcH);

which has the same effect but is twice as slow and blurry. you may replace "BUG","BUG" with anything you like without sideeffects :)

$2c,
*pike
up
0
George_A
8 years ago
For the best image quality...
How to get new proportional size of the image if the desible size of source image is approximatly equal to needed size. If needed size differs from source size on less than the user factor then transformation isn`t apply.

/**********************************************/
function imageCopyResize($image, $xSize, $ySize, $needed_user_factor, $new_image_path = "")
{
 //example: neded_user_factor = 0.2
 if($xSize == 0 || $ySize == 0)
    return array("At the leat one pair of size is 0",0,0);

 $size = getImageSize($image);
 $width = $size[0];
 $height = $size[1];
 $x_ratio = $xSize / $size[0];
 $y_ratio = $ySize / $size[1];
 if($x_ratio > $y_ratio)    $res_ratio = $y_ratio;
 else $res_ratio = $x_ratio;
 if(abs($res_ratio - 1) > $needed_user_factor)
    {
     $width = ceil($width * $res_ratio);
     $height = ceil($height * $res_ratio);
    }
 $fileinfo = pathinfo($image);
 $file_type = strtolower($fileinfo["extension"]);
 if($file_type == "jpg" || $file_type == "jpeg")
    $src = ImageCreateFromJpeg($image);
 else if($file_type == "gif")
    $src = ImageCreateFromGif($image);
 else if($file_type == "png")
    $src = ImageCreateFromPNG($image);
 else if($file_type == "bmp")   
    $src = ImageCreateFromBmp($image);    //Thanks Previous Coder
 else
   return array("Unknown image format: ".$file_type, 0, 0);  
 $output_path = ($new_image_path == "")?$image:$new_image_path;
 $dst = ImageCreateTrueColor($width, $height);
 ImageCopyResized($dst, $src, 0,0,0,0,$width, $height, $size[0], $size[1]);
 if($file_type == "jpg" || $file_type == "jpeg")
    ImageJpeg($dst, $output_path, 100);
 else if($file_type == "gif" || $file_type == "bmp")
     ImageGif($dst, $output_path);
 else if($file_type == "png")
    ImagePNG($dst, $output_path);

 ImageDestroy($src);
 ImageDestroy($dst);
 return array("", $width, $height);
}
/**********************************************/
up
0
erik at phpcastle dot com
8 years ago
I've changed the script from info at lontronics dot nl a little bit so the thumbnail is not cutted off when this is not necessary.

<?php
// Resize function

// $pictype is optional. When empty the image will not be cutted off
function resize($filename, $dest, $width, $height, $pictype = "")
{
 
$format = strtolower(substr(strrchr($filename,"."),1));
  switch(
$format)
  {
    case
'gif' :
   
$type ="gif";
   
$img = imagecreatefromgif($filename);
    break;
    case
'png' :
   
$type ="png";
   
$img = imagecreatefrompng($filename);
    break;
    case
'jpg' :
   
$type ="jpg";
   
$img = imagecreatefromjpeg($filename);
    break;
    case
'jpeg' :
   
$type ="jpg";
   
$img = imagecreatefromjpeg($filename);
    break;
    default :
    die (
"ERROR; UNSUPPORTED IMAGE TYPE");
    break;
  }

  list(
$org_width, $org_height) = getimagesize($filename);
 
$xoffset = 0;
 
$yoffset = 0;
  if (
$pictype == "thumb") // To minimize destortion
 
{
    if (
$org_width / $width > $org_height/ $height)
    {
     
$xtmp = $org_width;
     
$xratio = 1-((($org_width/$org_height)-($width/$height))/2);
     
$org_width = $org_width * $xratio;
     
$xoffset = ($xtmp - $org_width)/2;
    }
    elseif (
$org_height/ $height > $org_width / $width)
    {
     
$ytmp = $org_height;
     
$yratio = 1-((($width/$height)-($org_width/$org_height))/2);
     
$org_height = $org_height * $yratio;
     
$yoffset = ($ytmp - $org_height)/2;
    }
 
//Added this else part -------------
 
} else {   
     
$xtmp = $org_width/$width;
     
$new_width = $width;
     
$new_height = $org_height/$xtmp;
      if (
$new_height > $height){
       
$ytmp = $org_height/$height;
       
$new_height = $height;
       
$new_width = $org_width/$ytmp;
      }
     
$width = round($new_width);
     
$height = round($new_height);
  }
 

 
$img_n=imagecreatetruecolor ($width, $height);
 
imagecopyresampled($img_n, $img, 0, 0, $xoffset, $yoffset, $width, $height, $org_width, $org_height);

  if(
$type=="gif")
  {
   
imagegif($img_n, $dest);
  }
  elseif(
$type=="jpg")
  {
   
imagejpeg($img_n, $dest);
  }
  elseif(
$type=="png")
  {
   
imagepng($img_n, $dest);
  }
  elseif(
$type=="bmp")
  {
   
imagewbmp($img_n, $dest);
  }
  Return
true;
}
?>
up
0
info at lontronics dot nl
8 years ago
For an internet photoalbum I was looking for a script which I could simply drop in a directory with images and which would do the rest.
Therefor I am using the following resize script now. I have made the little thumb-part because I want to have all the same size thumbnails, but with as less as possible distortion. Therefor, images with other dimensions are resized, but also cut off a little.

Als $pictype = thumb, the extra dimension calculations are used
$width and $height are the new dimensions of $filename, the image
$dest is the directory where the new image must be copied in.

The script:

// Resize function
function resize($filename, $dest, $width, $height, $pictype)
{
    $format = strtolower(substr(strrchr($filename,"."),1));
    switch($format)
    {
        case 'gif' :
            $type ="gif";
            $img = imagecreatefromgif($filename);
            break;
        case 'png' :
            $type ="png";
            $img = imagecreatefrompng($filename);
            break;
        case 'jpg' :
            $type ="jpg";
            $img = imagecreatefromjpeg($filename);
            break;
        case 'jpeg' :
            $type ="jpg";
            $img = imagecreatefromjpeg($filename);
            break;
        default :
            die ("ERROR; UNSUPPORTED IMAGE TYPE");
            break;
    }
   
    list($org_width, $org_height) = getimagesize($filename);
    $xoffset = 0;
    $yoffset = 0;
    if ($pictype == "thumb") // To minimize destortion
    {
        if ($org_width / $width > $org_height/ $height)
        {
            $xtmp = $org_width;
            $xratio = 1-((($org_width/$org_height)-($width/$height))/2);
            $org_width = $org_width * $xratio;
            $xoffset = ($xtmp - $org_width)/2;
        }
        elseif ($org_height/ $height > $org_width / $width)
        {
            $ytmp = $org_height;
            $yratio = 1-((($width/$height)-($org_width/$org_height))/2);
            $org_height = $org_height * $yratio;
            $yoffset = ($ytmp - $org_height)/2;
        }
    }

    $img_n=imagecreatetruecolor ($width, $height);   
    imagecopyresampled($img_n, $img, 0, 0, $xoffset, $yoffset, $width, $height, $org_width, $org_height);

    if($type=="gif")
    {
        imagegif($img_n, $dest);
    }
    elseif($type=="jpg")
    {
        imagejpeg($img_n, $dest);
    }
    elseif($type=="png")
    {
        imagepng($img_n, $dest);
    }
    elseif($type=="bmp")
    {
        imagewbmp($img_n, $dest);
    }
    Return true;
}
up
0
Nicolas dot Grasset at notup2u dot net
8 years ago
If you are looking for a function that can resample your photos to a given size, no matter its original size and/or ratio, here it is. And to make more fun (beacause life has to be fun), you can even chose a border size for the picture!

$position can either be topleft, topright, bottomleft, bottomright or center.

<?php

function imagecopyresampledselection($filename, $desired_width, $desired_height, $bordersize, $position)
{   
   
// Get new dimensions
   
list($width, $height) = getimagesize($filename);
    if(
$desired_width/$desired_height > $width/$height):
       
$new_width = $desired_width;
       
$new_height = $height * ($desired_width / $width);
    else:
       
$new_width = $width * ($desired_height / $height);
       
$new_height = $desired_height;
    endif;
   
   
// Resize
   
$image_p = imagecreatetruecolor($new_width, $new_height);
   
$image_f = imagecreatetruecolor($desired_width, $desired_height);
   
$image = imagecreatefromjpeg($filename);
   
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
   
   
// Adjust position
   
switch($position)
    {
        case(
"topleft"):
           
$x = $bordersize;
           
$y = $bordersize;
            break;
           
        case(
"topright"):
           
$x = $new_width - $desired_width + $bordersize;
           
$y = $bordersize;
            break;
       
        case(
"bottomleft"):
           
$x = $bordersize;
           
$y = $new_height - $desired_height + $bordersize;
            break;
       
        case(
"bottomright"):
           
$x = $new_width - $desired_width + $bordersize;
           
$y = $new_height - $desired_height + $bordersize;
            break;
       
        case(
"center"):
           
$x = ($new_width - $desired_width) / 2 + $bordersize;
           
$y = ($new_height - $desired_height) / 2 + $bordersize;
            break;
    }
   
   
// Resample with 1px border
   
imagecopyresampled($image_f, $image_p, $bordersize, $bordersize, $x, $y,     $desired_width    - 2 * $bordersize,
                                                                               
$desired_height    - 2 * $bordersize,
                                                                               
$desired_width    - 2 * $bordersize,
                                                                               
$desired_height    - 2 * $bordersize);
   
    return
$image_f;
}

$image_f = imagecopyresampledselection('test.jpg', 571, 319, 1, "center");
header('Content-type: image/jpeg');
imagejpeg($image_f, null, 100);

?>

To see a result, just browse http://www.notup2u.net/v8

Nicolas Grasset
up
0
Anonymous
8 years ago
Here is my own custom utility which I call "Thumbnailer" (I know it is cheesy).
It's rather short, and it will take JPEG (you can change that easily), and
format it to a specified output width and height as a PNG
(or whatever else you choose):
<?php
//Dimensions
$outWidth=100; $outHeight=75;
//Do it
$imgSrc=imagecreatefromjpeg("[source]");
$srcWidth=imagesx($imgSrc);
$srcHeight=imagesy($imgSrc);
//Make thumbnails
$imgOut=imagecreatetruecolor($outWidth,$outHeight);
imagerectangle($imgOut,0,0,$outWidth,$outHeight,
 
imagecolorallocate($imgOut,0,0,0));
//Copy them proportionatly
$dx=0; $dy=0; $dw=$outWidth; $dh=$outHeight;
if (
$outWidth*$srcHeight!=$outHeight*$srcWidth) { //Non-proportional, cut-off
 //Which dimensions is larger
 
if ($srcWidth>$srcHeight) { //Empty space on top and bottom
 
$dw=$outWidth;
 
$dh=($dw*$srcHeight)/$srcWidth;
 
$dy=($outHeight-$dh)/2;
 }
 else {
//Empty space on left and right
 
$dh=$outHeight;
 
$dw=($dh*$srcWidth)/$srcHeight;
 
$dx=($outWidth-$dw)/2;
 }
}
imagecopyresampled($imgOut,$imgSrc,$dx,$dy,0,0,
 
$dw,$dh,$srcWidth,$srcHeight); //imagecopyresized for lower quality
//Create the thumbnail and destroy everything else
imagepng($imgOut,"[out]");
echo
"Image created successfully: $outWidth x $outHeight, ".round(filesize("[source]")/1024)." KB<br>";
imagedestroy($imgSrc);
imagedestroy($imgOut);
?>
I just use this as a loop to create thumbnails for a series of ordered images.
up
0
phpman at paodj dot net
8 years ago
<?php

function img_resize($path,$w=0,$h=0,$quality=100,$save=''){

 
$image_data=@getimagesize($path);

 
$image_type=$image_data[2];
 
$gd_ext=array('','jpg','gif');
  if(
$image_type!=1&&$image_type!=2) return false;
  if(
$save=='') header('Content-type: '.$image_data['mime']); else $save=eregi_replace('%ext',$gd_ext[$image_type],$save);

  if(
$w!=0){
   
$rapporto=$image_data[0]/$w;
    if(
$h!=0){
      if(
$image_data[1]/$rapporto>$h) $rapporto=$image_data[1]/$h;
    }
  }elseif(
$h!=0){
   
$tmp_h=$image_data[1]/$h;
  }else{
    return
false;
  }

 
$thumb_w=$image_data[0]/$rapporto;
 
$thumb_h=$image_data[1]/$rapporto;

  if(
$image_type==1) $img_src=@imagecreatefromgif($path);
  elseif(
$image_type==2) $img_src=@imagecreatefromjpeg($path);

 
$img_thumb=@imagecreatetruecolor($thumb_w,$thumb_h);
 
$result=@imagecopyresampled($img_thumb,$img_src,
0,0,0,0,$thumb_w,$thumb_h,$image_data[0],$image_data[1]);
  if(!
$img_src||!$img_thumb||!$result) return false;

  if(
$image_type==1) $result=@imagegif($img_thumb,$save);
  elseif(
$image_type==2) $result=@imagejpeg($img_thumb,$save,$quality);

  return
$result;
}

?>

This script resize images. It can also make thumbs. It use the resample of images for hight quality result.

It can show the result or save it (if $save isn't null).
It respect the width and/or the height of image.
It can replace the destination file extestion dinamically (filename.%ext)
Support gif & jpg.

Return false if something goes wrong.
up
0
Anonymous
8 years ago
It should be noted that the imagecopyresampled() function is much more blurry than Photoshop CS's default bicubic funtion. And looks similar to a blury version of Photoshop's bilinear function. The documentation fails to note which algorithm is used in resampling.
up
0
Pie pie
8 years ago
Confirming on what fluffle said, and to say his code will also crop and resize an image what is smaller than 100x100 pixels if you want. This is important because it means your images no matter how you decide to rezise them, will maintain their aspect ratios and with a minimum amount of image loss.

    //Get file type
    $mime = $orig_image_mimetype;
    $type = substr($mime, strpos($mime,'/')+1);
    switch($type) {
        case 'jpeg':
        case 'pjpeg':
            $big = imagecreatefromjpeg($file);
            break;
        case 'png':
        case 'x-png':
            $big = imagecreatefrompng($file);
             break;
        case 'gif':
            $big = imagecreatefromgif($file);
            break;
        default:
            return FALSE;
            break;
    }

The above code is what I use to support multiple file type resizing. I then use the same thing again when it's time to output the image using $result = imagejpeg($thumb,'',80), imagepng($thumb), and imagegif($thumb).
up
0
fluffle <at> gmail <dot> com
8 years ago
Just to clarify that src_w and src_h do not necessarily need to be the source image width and height, as they specify the size of the rectangle cropped from the source picture, with its top left corner situated at (src_x, src_y).

For example, the code below crops a jpeg image to be square, with the square situated in the centre of the original image, and then resizes it to a 100x100 thumbnail.

list($ow, $oh) = getimagesize($image_filename);
$big = imagecreatefromjpeg($image_filename);
$thumb = imagecreatetruecolor(100,100);
if ($ow > $oh) {
    $off_w = ($ow-$oh)/2;
    $off_h = 0;
    $ow = $oh;
} elseif ($oh > $ow) {
    $off_w = 0;
    $off_h = ($oh-$ow)/2;
    $oh = $ow;
} else {
    $off_w = 0;
    $off_h = 0;
}
imagecopyresampled($thumb, $big, 0, 0, $off_w, $off_h, 100, 100, $ow, $oh);
up
0
carnivorous_winds_fr AT yahoo DOT fr
8 years ago
I tried this code from a previous post.

<?
...
        
$t_im = imageCreateTrueColor($t_wd,$t_ht);
        
imageAntiAlias($t_im,true);
        
imagealphablending($t_im, false);
        
imagesavealpha($t_im,true);
        
$transparent = imagecolorallocatealpha($t_im, 255, 255, 255, 0);
         for(
$x=0;$x<$t_wd;$x++) {
           for(
$y=0;$y<$t_ht;$y++) {
            
imageSetPixel( $t_im, $x, $y, $transparent );
           }
         }
        
imageCopyResampled($t_im, $o_im, 0, 0, 0, 0, $t_wd, $t_ht, $o_wd, $o_ht);
        
imagePNG($t_im, $image_name);
...
?>

It seems that it is not working correctly. In my test the source picture in ImageCopyResampled() is smaller than the destination picture $t_im, the remaining part is white !

I changed transparent alpha channel to 127, and I tried to replace loops with imagefilledrectangle().

It works fine and these resource greedy loops are removed.

Here is the code with my change.

<?
...
        
$t_im = imageCreateTrueColor($t_wd,$t_ht);
        
imageAntiAlias($t_im,true);
        
imagealphablending($t_im, false);
        
imagesavealpha($t_im,true);
        
$transparent = imagecolorallocatealpha($t_im, 255, 255, 255, 127);
        
imagefilledrectangle($t_img, 0, 0, $t_wd, $t_ht, $transparent);
        
imageCopyResampled($t_im, $o_im, 0, 0, 0, 0, $t_wd, $t_ht, $o_wd, $o_ht);
        
imagePNG($t_im, $image_name);
...
?>
up
0
del at kartoon dot net
8 years ago
This snippet allows you to grab a thumbnail from the center of a large image.  This was used for a client photo gallery for art to give a teaser of the image to come (only a small portion).  You could get dynamic with this value.  I also put in a scaling factor in case you want to scale down first before chopping.

<?php
// The file
$filename = 'moon.jpg';
$percent = 1.0; // if you want to scale down first
$imagethumbsize = 200; // thumbnail size (area cropped in middle of image)
// Content type
header('Content-type: image/jpeg');

// Get new dimensions
list($width, $height) = getimagesize($filename);
$new_width = $width * $percent;
$new_height = $height * $percent;

// Resample
$image_p = imagecreatetruecolor($imagethumbsize , $imagethumbsize);  // true color for best quality
$image = imagecreatefromjpeg($filename);

// basically take this line and put in your versin the -($new_width/2) + ($imagethumbsize/2) & -($new_height/2) + ($imagethumbsize/2) for
// the 2/3 position in the 3 and 4 place for imagecopyresampled
// -($new_width/2) + ($imagethumbsize/2)
// AND
// -($new_height/2) + ($imagethumbsize/2)
// are the trick
imagecopyresampled($image_p, $image, -($new_width/2) + ($imagethumbsize/2), -($new_height/2) + ($imagethumbsize/2), 0, 0, $new_width , $new_width , $width, $height);

// Output

imagejpeg($image_p, null, 100);
?>
up
0
djneoform at gmail dot com
9 years ago
Here's a function i made that will force a given set of constraints on an image (usrfull if you want to make thumbnails that are all the same size) while keeping aspect ratio.

It resizes, then crops the extra off the top or bottom.

function forceConstraints($srcFile, $srcType, $dstType, $dstWidth, $dstHeight, $dstPath)
{
    if ($srcType == "image/jpeg")
        $handle = @imagecreatefromjpeg($srcFile);
    else if ($srcType == "image/png")
        $handle = @imagecreatefrompng($srcFile);
    else if ($srcType == "image/gif")
        $handle = @imagecreatefromgif($srcFile);
    else
        return false;

    if (!$handle)
        return false;

    $srcWidth  = @imagesx($handle);
    $srcHeight = @imagesy($handle);

    if ($srcWidth >= $dstWidth && $srcHeight >= $dstHeight)
    {
        $newHandle = @imagecreatetruecolor($dstWidth, $dstHeight);
        if (!$newHandle)
            return false;

        if($srcHeight < $srcWidth)
        {
            $ratio = (double)($srcHeight / $dstHeight);

            $cpyWidth = round($dstWidth * $ratio);
            if ($cpyWidth > $srcWidth)
            {
                $ratio = (double)($srcWidth / $dstWidth);
                $cpyWidth = $srcWidth;
                $cpyHeight = round($dstHeight * $ratio);
                $xOffset = 0;
                $yOffset = round(($srcHeight - $cpyHeight) / 2);
            } else {
                $cpyHeight = $srcHeight;
                $xOffset = round(($srcWidth - $cpyWidth) / 2);
                $yOffset = 0;
            }

        } else {
            $ratio = (double)($srcWidth / $dstWidth);

            $cpyHeight = round($dstHeight * $ratio);
            if ($cpyHeight > $srcHeight)
            {
                $ratio = (double)($srcHeight / $dstHeight);
                $cpyHeight = $srcHeight;
                $cpyWidth = round($dstWidth * $ratio);
                $xOffset = round(($srcWidth - $cpyWidth) / 2);
                $yOffset = 0;
            } else {
                $cpyWidth = $srcWidth;
                $xOffset = 0;
                $yOffset = round(($srcHeight - $cpyHeight) / 2);
            }
        }

        if (!@imagecopyresampled($newHandle, $handle, 0, 0, $xOffset, $yOffset, $dstWidth, $dstHeight, $cpyWidth, $cpyHeight))
            return false;
        @imagedestroy($handle);

        if ($dstType == "png")
            @imagepng($newHandle, $dstPath.".png");
        else if ($dstType == "jpg")
            @imagejpeg($newHandle, $dstPath.".jpg", 90);
        else if ($dstType == "gif")
            @imagegif($newHandle, $dstPath.".gif");
        else
            return false;
        @imagedestroy($newHandle);
        return true;

    } else {
        return "Sorry, that image is too small. The image must be at least ".$dstWidth."x".$dstHeight." pixels in size.";
    }
}
up
0
afrowuk at tiscali dot co dot uk
9 years ago
This simple function resizes a JPG image file giving just a maximum width, and resizes keeping the aspect ratio. This is useful if you have to resize a JPG image that must fit the width of i.e. a div element, but doesn't have to have a maximum height.
<?
function resizeJPG($jpgFile, $width) {

   
// Get new dimensions
   
list($width_orig, $height_orig) = getimagesize($jpgFile);
   
$height = (int) (($width / $width_orig) * $height_orig);

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

   
// Output
   
imagejpeg($image_p, $jpgFile, 100);

}
?>

-Stu
up
-1
wbcarts at juno dot com
8 months ago
FOUR RECTANGLES -- The Tools to Use this Function Creatively

A rectangle is not an image, but every image has a Rectangled boundary with x=0 and y=0. The width and height are obtained with the getimagesize function.

Because this function allows subimage areas to be defined, there are actually four rectangled areas that we need to be aware of.

* R1 -- Source Image Boundaries
* R2 -- Source Copy Area Boundaries
* R3 -- Destination Image Boundaries
* R4 -- Destination Resampled Placement Area Boundaries

+-----------------------+  +-----------------+
|          R1           |  |        R3       |
|                       |  |                 |
|    +------------+     |  |                 |
|    |            |     |  |                 |
|    |            |     |  |      +------+   |
|    |     R2     |     |  |      |      |   |
|    |            |     |  |      |  R4  |   |
|    |            |     |  |      |      |   |
|    |            |     |  |      +------+   |
|    +------------+     |  |                 |
|                       |  +-----------------+
|                       |
+-----------------------+

R1 contains all of the original pixel data. If R2 goes outside of R1 in any direction, then R2 will contain stuff that doesn't help. A lot of the time R2 == R1 exactly.

R3 defines the area that holds the resampled image data. If R4 goes outside of R3 in any direction, then the resampled image data in R4 will be clipped by R3. In other words, R3 has the final say as to which of R4's pixels will be included in the final image. Most of the time, R4 == R3.

In the end, R2 (and the pixels in it) will be strecthed, squeezed, and placed exactly over R4.

There are plenty of good examples on this page to create thumbnails etc. But what if R3 was not destined to be a thumbnail? What if we wanted to take the entire R1 image and shrink it to fit inside R2 for example, leaving the original picture as a border? With the knowledge we have just gained it is a simple matter of creating the Source & Destination Images from the same .jpg file, then R2 should be equal to R1, and R4 should be smaller and completely inside R3.

When we think of these rectangles as tools and not images, it becomes easier to see what's going on.
up
0
stemplar444 at yahoo dot com
9 years ago
Two comments regarding imageCopyResampleBicubic() published here.

Quality:
More grainy than imagecopyresampled(). Not very good for bigger destination images, I think.

Speed:
In my tests, it was only faster if destination size was smaller than ~200x200 pixel. The function becomes slower and slower the bigger the destination image gets. In contrast, imagecopyresampled() finished at the same speed, no matter how big the destination was. My source image resoloution ~ 1500x2000 pixel.
up
0
ron at korving dot demon dot nl
9 years ago
This Bicubic resample algorithm is based on the one Scott posted earlier, only this one is about 50% faster for truecolor images and about 10% faster for palette images.

<?

function imageCopyResampleBicubic($dst_img, $src_img, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h)
{
 
$scaleX = ($src_w - 1) / $dst_w;
 
$scaleY = ($src_h - 1) / $dst_h;

 
$scaleX2 = $scaleX / 2.0;
 
$scaleY2 = $scaleY / 2.0;

 
$tc = imageistruecolor($src_img);

  for (
$y = $src_y; $y < $src_y + $dst_h; $y++)
  {
   
$sY   = $y * $scaleY;
   
$siY  = (int) $sY;
   
$siY2 = (int) $sY + $scaleY2;

    for (
$x = $src_x; $x < $src_x + $dst_w; $x++)
    {
     
$sX   = $x * $scaleX;
     
$siX  = (int) $sX;
     
$siX2 = (int) $sX + $scaleX2;

      if (
$tc)
      {
       
$c1 = imagecolorat($src_img, $siX, $siY2);
       
$c2 = imagecolorat($src_img, $siX, $siY);
       
$c3 = imagecolorat($src_img, $siX2, $siY2);
       
$c4 = imagecolorat($src_img, $siX2, $siY);

       
$r = (($c1 + $c2 + $c3 + $c4) >> 2) & 0xFF0000;
       
$g = ((($c1 & 0xFF00) + ($c2 & 0xFF00) + ($c3 & 0xFF00) + ($c4 & 0xFF00)) >> 2) & 0xFF00;
       
$b = ((($c1 & 0xFF)   + ($c2 & 0xFF)   + ($c3 & 0xFF)   + ($c4 & 0xFF))   >> 2);

       
imagesetpixel($dst_img, $dst_x + $x - $src_x, $dst_y + $y - $src_y, $r+$g+$b);
      }
      else
      {
       
$c1 = imagecolorsforindex($src_img, imagecolorat($src_img, $siX, $siY2));
       
$c2 = imagecolorsforindex($src_img, imagecolorat($src_img, $siX, $siY));
       
$c3 = imagecolorsforindex($src_img, imagecolorat($src_img, $siX2, $siY2));
       
$c4 = imagecolorsforindex($src_img, imagecolorat($src_img, $siX2, $siY));

       
$r = ($c1['red']   + $c2['red']   + $c3['red']   + $c4['red']  ) << 14;
       
$g = ($c1['green'] + $c2['green'] + $c3['green'] + $c4['green']) << 6;
       
$b = ($c1['blue']  + $c2['blue']  + $c3['blue']  + $c4['blue'] ) >> 2;

       
imagesetpixel($dst_img, $dst_x + $x - $src_x, $dst_y + $y - $src_y, $r+$g+$b);
      }
    }
  }
}

?>
up
0
Anonymous
9 years ago
In add to all the posts that describes how to create thumbnails:

If you are trying to resample a png image with its transparency you need to do this workaround:

<?
...
         
$t_im = imageCreateTrueColor($t_wd,$t_ht);
         
imageAntiAlias($t_im,true);
         
imagealphablending($t_im, false);
         
imagesavealpha($t_im,true);
         
$transparent = imagecolorallocatealpha($t_im, 255, 255, 255, 0);
          for(
$x=0;$x<$t_wd;$x++) {
            for(
$y=0;$y<$t_ht;$y++) {
             
imageSetPixel( $t_im, $x, $y, $transparent );
            }
          }
         
imageCopyResampled($t_im, $o_im, 0, 0, 0, 0, $t_wd, $t_ht, $o_wd, $o_ht);
         
imagePNG($t_im, $image_name);
...
?>

The alphablending must be off so the imagesavealpha can be true.

The double FORs is need to fix the problem with imagefill function that not support colors with alpha setted.

It is TO SLOWLIER than imagefill, but do a nice work with static images.

Take a look and enjoy the nice result.

(this workaround needs the gd2 library)

[s]
Pigmeu
up
0
m.kumar [at] gmx.at
12 years ago
For those who think that resampling loads the server too badly, have a look at this fine article over at zend:

http://www.zend.com/zend/art/scriptcaching.php

it describes how to create static html from scripts, however, this technique is pretty easily applicable to images.

I've written a short script to outline how to adapt my above mentioned article for caching of thumbnails. see:
http://tzu.nme.at/php/cache.phps
up
-1
michael at heymichael dot com
4 years ago
imagecopyresampled() works amazingly well, but here is something NOT to try with it:

The resize routine I wrote looks for pixel widths, and resizes images based on the notion that if their widths and heights are too big, so are their byte sizes. It worked out well at first.

But when I saw huge byte-size images slipping through beneath my 1000px-wide benchmark, I figured I'd subject the smaller-width images to resizing if their filesize() exceeded 100K.

The idea was that I'd "resize" them keeping their original widths and heights (i.e. in (1) below, $newW = $oldW, $newH = $oldH), and letting the "75" at (2) below reduce the byte size.

DON'T try that. imagecopyresampled() will lock up the server trying to resize an 800px-wide image to a "new" width of 800px. (I caught that on my Windows server before ever putting it on the destination Linux server, so take that with a grain of salt.)

I got around it by making $newW = ($picW * 0.99), etc. You get the byte-size reduction you want without locking up.

(1) imagecopyresampled($image_p, $image, 0, 0, 0, 0, $newW, $newH, $picW, $picH);

(2) imagejpeg($image_p, $theFile, 75);
up
-1
crash
5 years ago
The suggestion of converting a gif to a png to retain transparency was useful. However the steps used to maintain the transparency work for a gif as well, so the conversion step is not necessary. Just do everything the same, and save as a gif anyway. i.e.

<?php
$g_iw is
new image width
$g_ih is
new image height

$img_src
=imagecreatefromgif($g_srcfile);
$img_dst=imagecreatetruecolor($g_iw,$g_ih);

//preserve alpha
imagecolortransparent($img_dst, imagecolorallocate($img_dst, 0, 0, 0));
imagealphablending($img_dst, false);
imagesavealpha($img_dst, true);
imagecopyresampled($img_dst, $img_src, 0, 0, 0, 0, $g_iw, $g_ih, $g_is[0], $g_is[1]);

imagegif($img_dst, $g_dstfile);
imagedestroy($img_dst);
?>
To Top