23

I am using this class:

class ImgResizer {

function ImgResizer($originalFile = '$newName') {
    $this -> originalFile = $originalFile;
}
function resize($newWidth, $targetFile) {
    if (empty($newWidth) || empty($targetFile)) {
        return false;
    }
    $src = imagecreatefromjpeg($this -> originalFile);
    list($width, $height) = getimagesize($this -> originalFile);
    $newHeight = ($height / $width) * $newWidth;
    $tmp = imagecreatetruecolor($newWidth, $newHeight);
    imagecopyresampled($tmp, $src, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);

    if (file_exists($targetFile)) {
        unlink($targetFile);
    }
    imagejpeg($tmp, $targetFile, 95);
}

}

Which works excellently, but it fails with png's, it creates a resized black image.

Is there a way to tweak this class to support png images?

nickhar
  • 19,981
  • 12
  • 60
  • 73
Toni Michel Caubet
  • 19,333
  • 56
  • 202
  • 378

7 Answers7

52
function resize($newWidth, $targetFile, $originalFile) {

    $info = getimagesize($originalFile);
    $mime = $info['mime'];

    switch ($mime) {
            case 'image/jpeg':
                    $image_create_func = 'imagecreatefromjpeg';
                    $image_save_func = 'imagejpeg';
                    $new_image_ext = 'jpg';
                    break;

            case 'image/png':
                    $image_create_func = 'imagecreatefrompng';
                    $image_save_func = 'imagepng';
                    $new_image_ext = 'png';
                    break;

            case 'image/gif':
                    $image_create_func = 'imagecreatefromgif';
                    $image_save_func = 'imagegif';
                    $new_image_ext = 'gif';
                    break;

            default: 
                    throw new Exception('Unknown image type.');
    }

    $img = $image_create_func($originalFile);
    list($width, $height) = getimagesize($originalFile);

    $newHeight = ($height / $width) * $newWidth;
    $tmp = imagecreatetruecolor($newWidth, $newHeight);
    imagecopyresampled($tmp, $img, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);

    if (file_exists($targetFile)) {
            unlink($targetFile);
    }
    $image_save_func($tmp, "$targetFile.$new_image_ext");
}
Chris Baker
  • 49,926
  • 12
  • 96
  • 115
P. Galbraith
  • 2,477
  • 21
  • 24
  • Would you mind re-writing it as the resize function? Its just that I particulary shared the class so we can extend it.. – Toni Michel Caubet Nov 30 '12 at 02:58
  • It is the content of the function so you just needed to wrap it with the same function tag. But I've done it for you above. – P. Galbraith Dec 01 '12 at 04:43
  • Hi! I just tested this and it gives me an error that it trows unknown exception... any idea why? (the thing is that in the swich it enters in the default, so is not reconising well the mime? – Toni Michel Caubet Apr 09 '13 at 16:15
  • @ToniMichelCaubet not sure have you tried printing $info to see what mime type is returned? – P. Galbraith Apr 10 '13 at 02:04
  • That original height / width are not defined in that function are they? – ForrestLyman Apr 04 '14 at 19:09
  • In my case I need to remove $new_image_ext from last line.. $image_save_func($tmp, "$targetFile"); – Confused Apr 04 '15 at 18:07
  • 1
    Works great, but it doesn't make sense to include $new_image_ext when specifying where to save the image. The expected input is for this resize function is `resize(100, "newfile.png", "oldfile.png")`. Also, `throw Exception` should be `throw new Exception`. Edited the question to reflect this. – fgblomqvist Aug 27 '15 at 12:14
  • $type = exif_imagetype($filePath); $extension = image_type_to_extension($type); $image_create_func = "imagecreatefrom$extension"; $image_save_func = "image$extension"; $new_image_ext = $extension; – Vilintritenmert Jan 20 '17 at 08:09
  • this does not keep transparency of png, does it? – Myoch Mar 07 '20 at 22:04
13

I've written a class that will do just that and is nice and easy to use. It's called
PHP Image Magician

$magicianObj = new imageLib('racecar.jpg');
$magicianObj -> resizeImage(100, 200);
$magicianObj -> saveImage('racecar_convertd.png', 100);

It supports Read and Write (including converting) the following formats

  • jpg
  • png
  • gif
  • bmp

And can read only

  • psd's

Example

// Include PHP Image Magician library
require_once('php_image_magician.php');

// Open JPG image
$magicianObj = new imageLib('racecar.jpg');

// Resize to best fit then crop
$magicianObj -> resizeImage(100, 200, 'crop');

// Save resized image as a PNG
$magicianObj -> saveImage('racecar_small.png');
Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
Jarrod
  • 9,349
  • 5
  • 58
  • 73
7

You can try this. Currently it's assuming the image will always be a jpeg. This will allow you to load a jpeg, png, or gif. I haven't tested but it should work.

function resize($newWidth, $targetFile) {
    if (empty($newWidth) || empty($targetFile)) {
        return false;
    }

    $fileHandle = @fopen($this->originalFile, 'r');

    //error loading file
    if(!$fileHandle) {
        return false;
    }

    $src = imagecreatefromstring(stream_get_contents($fileHandle));

    fclose($fileHandle);

    //error with loading file as image resource
    if(!$src) {
        return false;
    }

    //get image size from $src handle
    list($width, $height) = array(imagesx($src), imagesy($src));

    $newHeight = ($height / $width) * $newWidth;

    $tmp = imagecreatetruecolor($newWidth, $newHeight);

    imagecopyresampled($tmp, $src, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);

    //allow transparency for pngs
    imagealphablending($tmp, false);
    imagesavealpha($tmp, true);

    if (file_exists($targetFile)) {
        unlink($targetFile);
    }

    //handle different image types.
    //imagepng() uses quality 0-9
    switch(strtolower(pathinfo($this->originalFile, PATHINFO_EXTENSION))) {
        case 'jpg':
        case 'jpeg':
            imagejpeg($tmp, $targetFile, 95);
            break;
        case 'png':
            imagepng($tmp, $targetFile, 8.5);
            break;
        case 'gif':
            imagegif($tmp, $targetFile);
            break;
    }

    //destroy image resources
    imagedestroy($tmp);
    imagedestroy($src);
}
Sharpless512
  • 3,062
  • 5
  • 35
  • 60
Austin Brunkhorst
  • 20,704
  • 6
  • 47
  • 61
3

Try this one and using this you can also save your image to specific path.

function resize($file, $imgpath, $width, $height){
    /* Get original image x y*/
    list($w, $h) = getimagesize($file['tmp_name']);
    /* calculate new image size with ratio */
    $ratio = max($width/$w, $height/$h);
    $h = ceil($height / $ratio);
    $x = ($w - $width / $ratio) / 2;
    $w = ceil($width / $ratio);

    /* new file name */
    $path = $imgpath;
    /* read binary data from image file */
    $imgString = file_get_contents($file['tmp_name']);
    /* create image from string */
    $image = imagecreatefromstring($imgString);
    $tmp = imagecreatetruecolor($width, $height);
    imagecopyresampled($tmp, $image, 0, 0, $x, 0, $width, $height, $w, $h);
    /* Save image */
    switch ($file['type']) {
       case 'image/jpeg':
          imagejpeg($tmp, $path, 100);
          break;
       case 'image/png':
          imagepng($tmp, $path, 0);
          break;
       case 'image/gif':
          imagegif($tmp, $path);
          break;
          default:
          //exit;
          break;
        }
     return $path;

     /* cleanup memory */
     imagedestroy($image);
     imagedestroy($tmp);
}

Now you need to call this function while saving image as like...

<?php

    //$imgpath = "Where you want to save your image";
    resize($_FILES["image"], $imgpath, 340, 340);

?>
Taryn
  • 242,637
  • 56
  • 362
  • 405
Hardik
  • 1,283
  • 14
  • 34
1

I took the P. Galbraith's version, fixed the errors and changed it to resize by area (width x height). For myself, I wanted to resize images that are too big.

function resizeByArea($originalFile,$targetFile){

    $newArea = 375000; //a little more than 720 x 480

    list($width,$height,$type) = getimagesize($originalFile);
    $area = $width * $height;

if($area > $newArea){

    if($width > $height){ $big = $width; $small = $height; }
    if($width < $height){ $big = $height; $small = $width; }

    $ratio = $big / $small;

    $newSmall = sqrt(($newArea*$small)/$big);
    $newBig = $ratio*$newSmall;

    if($width > $height){ $newWidth = round($newBig, 0); $newHeight = round($newSmall, 0); }
    if($width < $height){ $newWidth = round($newSmall, 0); $newHeight = round($newBig, 0); }

    }

switch ($type) {
    case '2':
            $image_create_func = 'imagecreatefromjpeg';
            $image_save_func = 'imagejpeg';
            $new_image_ext = '.jpg';
            break;

    case '3':
            $image_create_func = 'imagecreatefrompng';
         // $image_save_func = 'imagepng';
         // The quality is too high with "imagepng"
         // but you need it if you want to allow transparency
            $image_save_func = 'imagejpeg';
            $new_image_ext = '.png';
            break;

    case '1':
            $image_create_func = 'imagecreatefromgif';
            $image_save_func = 'imagegif';
            $new_image_ext = '.gif';
            break;

    default: 
            throw Exception('Unknown image type.');
}

    $img = $image_create_func($originalFile);
    $tmp = imagecreatetruecolor($newWidth,$newHeight);
    imagecopyresampled( $tmp, $img, 0, 0, 0, 0,$newWidth,$newHeight, $width, $height );

    ob_start();
    $image_save_func($tmp);
    $i = ob_get_clean();

    // if file exists, create a new one with "1" at the end
    if (file_exists($targetFile.$new_image_ext)){
      $targetFile = $targetFile."1".$new_image_ext;
    }
    else{
      $targetFile = $targetFile.$new_image_ext;
    }

    $fp = fopen ($targetFile,'w');
    fwrite ($fp, $i);
    fclose ($fp);

    unlink($originalFile);
}

If you want to allow transparency, check this : http://www.akemapa.com/2008/07/10/php-gd-resize-transparent-image-png-gif/

I tested the function, it works fine!

pmrotule
  • 9,065
  • 4
  • 50
  • 58
0

the accepted answer has alot of errors here is it fixed

<?php 




function resize($newWidth, $targetFile, $originalFile) {

    $info = getimagesize($originalFile);
    $mime = $info['mime'];

    switch ($mime) {
            case 'image/jpeg':
                    $image_create_func = 'imagecreatefromjpeg';
                    $image_save_func = 'imagejpeg';
                    $new_image_ext = 'jpg';
                    break;

            case 'image/png':
                    $image_create_func = 'imagecreatefrompng';
                    $image_save_func = 'imagepng';
                    $new_image_ext = 'png';
                    break;

            case 'image/gif':
                    $image_create_func = 'imagecreatefromgif';
                    $image_save_func = 'imagegif';
                    $new_image_ext = 'gif';
                    break;

            default: 
                    throw Exception('Unknown image type.');
    }

    $img = $image_create_func($originalFile);
    list($width, $height) = getimagesize($originalFile);
    $newHeight = ($height / $width) * $newWidth;
    $tmp = imagecreatetruecolor($newWidth, $newHeight);
    imagecopyresampled($tmp, $img, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);

    if (file_exists($targetFile)) {
            unlink($targetFile);
    }
    $image_save_func($tmp, "$targetFile.$new_image_ext");
}



$img=$_REQUEST['img'];
$id=$_REQUEST['id'];

  //  echo $img
resize(120, $_SERVER['DOCUMENT_ROOT'] ."/images/$id",$_SERVER['DOCUMENT_ROOT'] ."/images/$img") ;


?>
bdaz
  • 163
  • 4
  • 13
0

I know this is very old thread, but I found PHP has imagescale function built in, which does the required job. See documentation here

Example usage:

$temp = imagecreatefrompng('1.png'); 
$scaled_image= imagescale ( $temp, 200 , 270);

Here 200 is width and 270 is height of resized image.

Sudhir
  • 113
  • 8