Resize images with PHP, support PNG, JPG
Asked Answered
V

7

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?

Vogler answered 28/11, 2012 at 2:28 Comment(2)
This question might help you figure it out: #10032346Nonflammable
imagecreatefrompng($filename)Enroot
P
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");
}
Patronizing answered 28/11, 2012 at 2:42 Comment(9)
Would you mind re-writing it as the resize function? Its just that I particulary shared the class so we can extend it..Vogler
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.Patronizing
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?Vogler
@ToniMichelCaubet not sure have you tried printing $info to see what mime type is returned?Patronizing
That original height / width are not defined in that function are they?Amby
In my case I need to remove $new_image_ext from last line.. $image_save_func($tmp, "$targetFile");Taffy
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.Alienor
$type = exif_imagetype($filePath); $extension = image_type_to_extension($type); $image_create_func = "imagecreatefrom$extension"; $image_save_func = "image$extension"; $new_image_ext = $extension;Salientian
this does not keep transparency of png, does it?Makowski
T
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');
Trombley answered 7/3, 2013 at 2:7 Comment(1)
Is your library able to fix the size of height based on width automatically?Braziel
C
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);
}
Concealment answered 28/11, 2012 at 2:49 Comment(6)
I don't understant 'asuming the image is a jpg'Vogler
In the original resize method, $originalFile is only dealt with resizing as a jpeg (imagecreatefromjpeg/imagejpeg).Concealment
I tried to replace my resize() function to yours and it didn't generate any image ;SVogler
@Sharpless512 made an edit to put break statements in appropriate places in a switch/case statement.Ludwig
Thanks I didn't catch that one. (pun not intended)Concealment
This is the first example that didn't include imagecreatefromjpeg() and the first one that has worked for me as soon as I got rid of it. The other examples worked but the image was entirely black.Superior
A
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);

?>
Auxin answered 19/11, 2014 at 6:20 Comment(2)
what if i want to reduce total picture quality by 50% not a fixed amount to maintain aspect ratio?Ornamentation
With a few alterations it worked well. <-Iceland
V
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!

Variation answered 1/3, 2013 at 18:13 Comment(1)
Interesting! will give it some tests and let you know. thanks!Vogler
C
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") ;


?>
Cumulous answered 25/12, 2013 at 7:0 Comment(0)
S
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.

Sedimentary answered 29/7, 2020 at 6:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.