5

EDIT: This can be easily done in CSS, I didn't know CSS much at the time of writing this

enter image description here

I have created a thumbnail creator using PHP. The thumbnails generated should be of the same size. But the problem is the use of uploads images having different aspect ratio like landscape or portrait the thumbnail becomes ugly. So I created the picture above for clarification. Whatever be the uploaded image, it will be put into a rectangle image. So the aspect ratio doesn't change and thumbnails will be of the same size. Can anyone pls help me or tell some ideas?

Gijo Varghese
  • 11,264
  • 22
  • 73
  • 122
  • I think this ressources will be of help: http://stackoverflow.com/questions/16774521/scale-image-using-php-and-maintaining-aspect-ratio http://math.stackexchange.com/questions/180804/how-to-get-the-aspect-ratio-of-an-image – LeaveAirykson Apr 18 '14 at 06:46
  • @LeaveAirykson ok. Let me try... – Gijo Varghese Apr 18 '14 at 06:49
  • @LeaveAirykson Thanks. It worked little bit. Half is done. Now what i need is to put the image obtained in a white rectangle. Can you please help me?? – Gijo Varghese Apr 18 '14 at 10:13
  • look at this answer, it may be of help [Add whitespace to image and save file to server](http://stackoverflow.com/a/8758730/3123098) – LeaveAirykson Apr 18 '14 at 13:23
  • Look at this post http://stackoverflow.com/questions/6384722/how-to-resize-a-image-in-php-to-fit-it-into-a-box-of-custom-size-preserving-its this might help you. – Subedi Kishor Jun 16 '14 at 11:54
  • While CSS is a cool tool, I would never use it for thumbnail creation unless it's a dynamic image you could resize. The reason being is a "thumbnail" should be a small image in filesize. CSS is just going tell the browser to downscale the large version, which means large file sizes which could break continuity of pages loading. – WASasquatch Apr 21 '21 at 00:03

4 Answers4

15
define('THUMBNAIL_IMAGE_MAX_WIDTH', 150);
define('THUMBNAIL_IMAGE_MAX_HEIGHT', 150);

function generate_image_thumbnail($source_image_path, $thumbnail_image_path)
{
    list($source_image_width, $source_image_height, $source_image_type) = getimagesize($source_image_path);
    switch ($source_image_type) {
        case IMAGETYPE_GIF:
            $source_gd_image = imagecreatefromgif($source_image_path);
            break;
        case IMAGETYPE_JPEG:
            $source_gd_image = imagecreatefromjpeg($source_image_path);
            break;
        case IMAGETYPE_PNG:
            $source_gd_image = imagecreatefrompng($source_image_path);
            break;
    }
    if ($source_gd_image === false) {
        return false;
    }
    $source_aspect_ratio = $source_image_width / $source_image_height;
    $thumbnail_aspect_ratio = THUMBNAIL_IMAGE_MAX_WIDTH / THUMBNAIL_IMAGE_MAX_HEIGHT;
    if ($source_image_width <= THUMBNAIL_IMAGE_MAX_WIDTH && $source_image_height <= THUMBNAIL_IMAGE_MAX_HEIGHT) {
        $thumbnail_image_width = $source_image_width;
        $thumbnail_image_height = $source_image_height;
    } elseif ($thumbnail_aspect_ratio > $source_aspect_ratio) {
        $thumbnail_image_width = (int) (THUMBNAIL_IMAGE_MAX_HEIGHT * $source_aspect_ratio);
        $thumbnail_image_height = THUMBNAIL_IMAGE_MAX_HEIGHT;
    } else {
        $thumbnail_image_width = THUMBNAIL_IMAGE_MAX_WIDTH;
        $thumbnail_image_height = (int) (THUMBNAIL_IMAGE_MAX_WIDTH / $source_aspect_ratio);
    }
    $thumbnail_gd_image = imagecreatetruecolor($thumbnail_image_width, $thumbnail_image_height);
    imagecopyresampled($thumbnail_gd_image, $source_gd_image, 0, 0, 0, 0, $thumbnail_image_width, $thumbnail_image_height, $source_image_width, $source_image_height);

    $img_disp = imagecreatetruecolor(THUMBNAIL_IMAGE_MAX_WIDTH,THUMBNAIL_IMAGE_MAX_WIDTH);
    $backcolor = imagecolorallocate($img_disp,0,0,0);
    imagefill($img_disp,0,0,$backcolor);

        imagecopy($img_disp, $thumbnail_gd_image, (imagesx($img_disp)/2)-(imagesx($thumbnail_gd_image)/2), (imagesy($img_disp)/2)-(imagesy($thumbnail_gd_image)/2), 0, 0, imagesx($thumbnail_gd_image), imagesy($thumbnail_gd_image));

    imagejpeg($img_disp, $thumbnail_image_path, 90);
    imagedestroy($source_gd_image);
    imagedestroy($thumbnail_gd_image);
    imagedestroy($img_disp);
    return true;
}

generate_image_thumbnail('original_image.jpg', 'thumb_image.jpg'); //call the function

with that code, you will get something similar to

enter image description here

kraysak
  • 1,746
  • 1
  • 13
  • 14
  • 1
    In line 37, it needs to be $img_disp = imagecreatetruecolor(THUMBNAIL_IMAGE_MAX_WIDTH, THUMBNAIL_IMAGE_MAX_HEIGHT); (replace second parameter by THUMBNAIL_IMAGE_MAX_HEIGHT). – Olaf Jun 20 '15 at 08:56
  • 2
    this does not work with a PNG transparent image with black text, creates a BLACK image thumb. – Muhammad Omer Aslam Dec 29 '18 at 17:12
1

Look at the source code of my Mr Thumb Image Resizing. :)

public function proportion($max_width, $max_height) {

    if (!( $this->halt )) {
        if ($this->image['extension'] == 'gif') {
            $this->image['ratio'] = ( $this->image['width'] > $this->image['height'] ) ? $max_width / $this->image['width'] : $max_height / $this->image['height'];
            if ($this->image['width'] > $max_width || $this->image['height'] > $max_height) {
                $new_width = $this->image['width'] * $this->image['ratio'];
                $new_height = $this->image['height'] * $this->image['ratio'];
            } else {
                $new_width = $this->image['width'];
                $new_height = $this->image['height'];
            }
            $this->image['composite'] = imagecreatetruecolor($new_width, $new_height);
            imagecopyresampled($this->image['composite'], $this->image['render'], 0, 0, 0, 0, $new_width, $new_height, $this->image['width'], $this->image['height']);
            $this->image['colorcount'] = imagecolorstotal($this->image['render']);
            imagetruecolortopalette($this->image['composite'], true, $this->image['colorcount']);
            imagepalettecopy($this->image['composite'], $this->image['render']);
            $this->image['transparentcolor'] = imagecolortransparent($this->image['render']);
            imagefill($this->image['composite'], 0, 0, $this->image['transparentcolor']);
            imagecolortransparent($this->image['composite'], $this->image['transparentcolor']);
        } else {
            $this->image['ratio'] = ( $this->image['width'] > $this->image['height'] ) ? $max_width / $this->image['width'] : $max_height / $this->image['height'];
            if ($this->image['width'] > $max_width || $this->image['height'] > $max_height) {
                $new_width = $this->image['width'] * $this->image['ratio'];
                $new_height = $this->image['height'] * $this->image['ratio'];
            } else {
                $new_width = $this->image['width'];
                $new_height = $this->image['height'];
            }
            $this->image['composite'] = imagecreatetruecolor($new_width, $new_height);
            imagecopyresampled($this->image['composite'], $this->image['render'], 0, 0, 0, 0, $new_width, $new_height, $this->image['width'], $this->image['height']);
        }
    } else {
        echo 'Execution halted!';
    }
}
kupendra
  • 1,002
  • 1
  • 15
  • 37
WASasquatch
  • 1,044
  • 3
  • 11
  • 19
  • I am new to PHP. Can you pls tell me how to call this function, where to put the filename, destination like that?? – Gijo Varghese Apr 18 '14 at 09:46
  • @user3392772 Click the link. Look at the example of it's use under `example.php` http://www.phpclasses.org/browse/file/28565.html Changing `$image` variable to `$image = $_GET['i']` will allow you to link images in a basic HTML tag like `My Image` You can also change the max width and height variables to queries to define width/height on the fly `My Image` – WASasquatch Apr 18 '14 at 19:49
0

Here's a function that might help you out. You tell it the width you want to maintain, and it will preserve the aspect ratio while also producing a thumbnail.

public static function makeThumb($src, $dest, $desired_width, $format = 'image/jpeg')
{
    /* read the source image */
    $source_image = null;
    if($format == 'image/jpeg')
    {
        $source_image = imagecreatefromjpeg($src);
    }
    else if($format == 'image/png')
    {
        $source_image = imagecreatefrompng($src);
    }

    $width = imagesx($source_image);
    $height = imagesy($source_image);

    /* find the "desired height" of this thumbnail, relative to the desired width  */
    $desired_height = floor($height * ($desired_width / $width));

    /* create a new, "virtual" image */
    $virtual_image = imagecreatetruecolor($desired_width, $desired_height);

    imageAlphaBlending($virtual_image, false);
    imageSaveAlpha($virtual_image, true);

    /* copy source image at a resized size */
    imagecopyresampled($virtual_image, $source_image, 0, 0, 0, 0, $desired_width, $desired_height, $width, $height);

    /* create the physical thumbnail image to its destination */
    if($format == 'image/jpeg')
    {
        imagejpeg($virtual_image, $dest);
    }
    else if($format == 'image/png')
    {
        imagepng($virtual_image, $dest);
    }
}
lewsid
  • 1,900
  • 2
  • 17
  • 19
0

Use ImageMagick API .Check out this

define('THUMB_WIDTH', 60);
define('THUMB_HEIGHT', 80);
define('MAGICK_PATH','/usr/local/bin/');

function makeThumbnail($in, $out) {
    $width = THUMB_WIDTH;
    $height = THUMB_HEIGHT;
    list($w,$h) = getimagesize($in);

    $thumbRatio = $width/$height;
    $inRatio = $w/$h;
    $isLandscape = $inRatio > $thumbRatio;

    $size = ($isLandscape ? '1000x'.$height : $width.'x1000');
    $xoff = ($isLandscape ? floor((($inRatio*$height)-$width)/2) : 0);
    $command = MAGICK_PATH."convert $in -resize $size -crop {$width}x{$height}+{$xoff}+0 ".
        "-colorspace RGB -strip -quality 90 $out";

    exec($command);
}

Refer to this link - http://coffeeshopped.com/2009/01/creating-image-thumbnails-using-php-and-imagemagick or http://in1.php.net/manual/en/class.imagick.php

Chetan Gawai
  • 2,361
  • 1
  • 25
  • 36