PHP Thumbnail Image Resizing with Proportions

PHP - Create Thumbnail & maintaining aspect ratio

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

Sample Image

Dynamic thumbnail with correct aspect ratio

Hm...you're sure there is no maximum height? To have a correct aspect ratio this should be OK:

// Scaling
$newwidth = $maxwidth;
$ratio = $width / $height;
$newheight = $newwidth / ratio;

So the width would always be 200 and the height accordingly.

PHP Uploading a Large image and resizing with proportion like Photoshop

The easiest way to achieve this without buckets of PHP code is with Image Magick. See examples and sample command line here: http://www.imagemagick.org/Usage/resize/#fill

(can call from PHP using exec() or similar)

Edit: Implementation as follows:

if($_FILES['user_image']['type'] == "image/jpeg" && $_FILES['user_image']['size'] < 3000000)
{
// VARS
$target_folder = 'images/';
$upload_image = $target_folder.basename($_FILES['user_image']['name']);

$thumbnail = $target_folder."medium_x.jpg";
$actual = $target_folder."large_x.jpg";

$newwidth = "300";
$newheight = "525";

if(move_uploaded_file($_FILES['user_image']['tmp_name'], $upload_image))
{
exec('convert '.$upload_image.' -resize '.$newwidth.'x'.$newheight.'^ '.$thumbnail);
rename($upload_image, $actual);
}
}
...
etc

You could optimise the way you handle the upload but I didn't want too totally change the structure of your code as I don't know what surrounds it. But basically, you push the image to ImageMagick's convert, and it will work it's magic.

If you want to crop as well as scale, the exec command would be:

exec('convert '.$upload_image.' -resize '.$newwidth.'x'.$newheight.'^ -gravity center -extent '.$newwidth.'x'.$newheight.' '.$thumbnail);

PHP - Create thumbnail maintaining aspect ratio & remove blank portion?

Maybe the easiest way is to preserve the aspect ratio.


// RESIZE AN IMAGE PROPORTIONALLY AND CROP TO THE CENTER

function resize_and_crop($original_image_url, $thumb_image_url, $thumb_w, $thumb_h, $quality=75)
{
// ACQUIRE THE ORIGINAL IMAGE: http://php.net/manual/en/function.imagecreatefromjpeg.php
$original = imagecreatefromjpeg($original_image_url);
if (!$original) return FALSE;

// GET ORIGINAL IMAGE DIMENSIONS
list($original_w, $original_h) = getimagesize($original_image_url);

// RESIZE IMAGE AND PRESERVE PROPORTIONS
$thumb_w_resize = $thumb_w;
$thumb_h_resize = $thumb_h;
if ($original_w > $original_h)
{
$thumb_h_ratio = $thumb_h / $original_h;
$thumb_w_resize = (int)round($original_w * $thumb_h_ratio);
}
else
{
$thumb_w_ratio = $thumb_w / $original_w;
$thumb_h_resize = (int)round($original_h * $thumb_w_ratio);
}
if ($thumb_w_resize < $thumb_w)
{
$thumb_h_ratio = $thumb_w / $thumb_w_resize;
$thumb_h_resize = (int)round($thumb_h * $thumb_h_ratio);
$thumb_w_resize = $thumb_w;
}

// CREATE THE PROPORTIONAL IMAGE RESOURCE
$thumb = imagecreatetruecolor($thumb_w_resize, $thumb_h_resize);
if (!imagecopyresampled($thumb, $original, 0,0,0,0, $thumb_w_resize, $thumb_h_resize, $original_w, $original_h)) return FALSE;

// ACTIVATE THIS TO STORE THE INTERMEDIATE IMAGE
// imagejpeg($thumb, 'thumbs/temp_' . $thumb_w_resize . 'x' . $thumb_h_resize . '.jpg', 100);

// CREATE THE CENTERED CROPPED IMAGE TO THE SPECIFIED DIMENSIONS
$final = imagecreatetruecolor($thumb_w, $thumb_h);

$thumb_w_offset = 0;
$thumb_h_offset = 0;
if ($thumb_w < $thumb_w_resize)
{
$thumb_w_offset = (int)round(($thumb_w_resize - $thumb_w) / 2);
}
else
{
$thumb_h_offset = (int)round(($thumb_h_resize - $thumb_h) / 2);
}

if (!imagecopy($final, $thumb, 0,0, $thumb_w_offset, $thumb_h_offset, $thumb_w_resize, $thumb_h_resize)) return FALSE;

// STORE THE FINAL IMAGE - WILL OVERWRITE $thumb_image_url
if (!imagejpeg($final, $thumb_image_url, $quality)) return FALSE;
return TRUE;
}

// USE CASE
echo '<a target="_blank" href="images/image_600x374.jpg">Original 600x374</a><br/>';

resize_and_crop('images/image_600x374.jpg', 'thumbs/temp_100x100.jpg', 100, 100);
echo '<a target="_blank" href="thumbs/temp_100x100.jpg">100x100</a><br/>';

resize_and_crop('images/image_600x374.jpg', 'thumbs/temp_200x100.jpg', 200, 100);
echo '<a target="_blank" href="thumbs/temp_200x100.jpg">200x100</a><br/>';

resize_and_crop('images/image_600x374.jpg', 'thumbs/temp_200x300.jpg', 200, 300);
echo '<a target="_blank" href="thumbs/temp_200x300.jpg">200x300</a><br/>';

Scale Image Using PHP and Maintaining Aspect Ratio

I had written a peice of code like this for another project I've done. I've copied it below, might need a bit of tinkering! (It does required the GD library)

These are the parameters it needs:

$image_name - Name of the image which is uploaded
$new_width - Width of the resized photo (maximum)
$new_height - Height of the resized photo (maximum)
$uploadDir - Directory of the original image
$moveToDir - Directory to save the resized image

It will scale down or up an image to the maximum width or height

function createThumbnail($image_name,$new_width,$new_height,$uploadDir,$moveToDir)
{
$path = $uploadDir . '/' . $image_name;

$mime = getimagesize($path);

if($mime['mime']=='image/png') {
$src_img = imagecreatefrompng($path);
}
if($mime['mime']=='image/jpg' || $mime['mime']=='image/jpeg' || $mime['mime']=='image/pjpeg') {
$src_img = imagecreatefromjpeg($path);
}

$old_x = imageSX($src_img);
$old_y = imageSY($src_img);

if($old_x > $old_y)
{
$thumb_w = $new_width;
$thumb_h = $old_y*($new_height/$old_x);
}

if($old_x < $old_y)
{
$thumb_w = $old_x*($new_width/$old_y);
$thumb_h = $new_height;
}

if($old_x == $old_y)
{
$thumb_w = $new_width;
$thumb_h = $new_height;
}

$dst_img = ImageCreateTrueColor($thumb_w,$thumb_h);

imagecopyresampled($dst_img,$src_img,0,0,0,0,$thumb_w,$thumb_h,$old_x,$old_y);

// New save location
$new_thumb_loc = $moveToDir . $image_name;

if($mime['mime']=='image/png') {
$result = imagepng($dst_img,$new_thumb_loc,8);
}
if($mime['mime']=='image/jpg' || $mime['mime']=='image/jpeg' || $mime['mime']=='image/pjpeg') {
$result = imagejpeg($dst_img,$new_thumb_loc,80);
}

imagedestroy($dst_img);
imagedestroy($src_img);

return $result;
}

Resize uploaded image to proportion

Simple math:

$original_width = 50;
$original_height = 50;
$width = 250;
$ratio = $width/$original_width;

$height = $original_height * $ratio;

Resizing the image in php for viewing purposes only

I use a simple PHP class which has several options for resizing. You can easily store the thumbnails via this class. As @jeroen said, you only have to do it once and they can be cached. It just requires PHP5 and GD library. Here is usage example:

// *** Include the class
include("resize-class.php");

// *** 1) Initialise / load image
$resizeObj = new resize('sample.jpg');

// *** 2) Resize image (options: exact, portrait, landscape, auto, crop)
$resizeObj -> resizeImage(150, 150, 'crop');

// *** 3) Save image ('image-name', 'quality [int]')
$resizeObj -> saveImage('sample-resized.jpg', 100);

And this is that class:

<?php
Class resize
{
// *** Class variables
private $image;
private $width;
private $height;
private $imageResized;

function __construct($fileName)
{
// *** Open up the file
$this->image = $this->openImage($fileName);

// *** Get width and height
$this->width = imagesx($this->image);
$this->height = imagesy($this->image);
}

## --------------------------------------------------------

private function openImage($file)
{
// *** Get extension
$extension = strtolower(strrchr($file, '.'));

switch($extension)
{
case '.jpg':
case '.jpeg':
$img = @imagecreatefromjpeg($file);
break;
case '.gif':
$img = @imagecreatefromgif($file);
break;
case '.png':
$img = @imagecreatefrompng($file);
break;
default:
$img = false;
break;
}
return $img;
}

## --------------------------------------------------------

public function resizeImage($newWidth, $newHeight, $option="auto")
{
// *** Get optimal width and height - based on $option
$optionArray = $this->getDimensions($newWidth, $newHeight, $option);

$optimalWidth = $optionArray['optimalWidth'];
$optimalHeight = $optionArray['optimalHeight'];

// *** Resample - create image canvas of x, y size
$this->imageResized = imagecreatetruecolor($optimalWidth, $optimalHeight);
imagecopyresampled($this->imageResized, $this->image, 0, 0, 0, 0, $optimalWidth, $optimalHeight, $this->width, $this->height);

// *** if option is 'crop', then crop too
if ($option == 'crop') {
$this->crop($optimalWidth, $optimalHeight, $newWidth, $newHeight);
}
}

## --------------------------------------------------------

private function getDimensions($newWidth, $newHeight, $option)
{

switch ($option)
{
case 'exact':
$optimalWidth = $newWidth;
$optimalHeight= $newHeight;
break;
case 'portrait':
$optimalWidth = $this->getSizeByFixedHeight($newHeight);
$optimalHeight= $newHeight;
break;
case 'landscape':
$optimalWidth = $newWidth;
$optimalHeight= $this->getSizeByFixedWidth($newWidth);
break;
case 'auto':
$optionArray = $this->getSizeByAuto($newWidth, $newHeight);
$optimalWidth = $optionArray['optimalWidth'];
$optimalHeight = $optionArray['optimalHeight'];
break;
case 'crop':
$optionArray = $this->getOptimalCrop($newWidth, $newHeight);
$optimalWidth = $optionArray['optimalWidth'];
$optimalHeight = $optionArray['optimalHeight'];
break;
}
return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
}

## --------------------------------------------------------

private function getSizeByFixedHeight($newHeight)
{
$ratio = $this->width / $this->height;
$newWidth = $newHeight * $ratio;
return $newWidth;
}

private function getSizeByFixedWidth($newWidth)
{
$ratio = $this->height / $this->width;
$newHeight = $newWidth * $ratio;
return $newHeight;
}

private function getSizeByAuto($newWidth, $newHeight)
{
if ($this->height < $this->width)
// *** Image to be resized is wider (landscape)
{
$optimalWidth = $newWidth;
$optimalHeight= $this->getSizeByFixedWidth($newWidth);
}
elseif ($this->height > $this->width)
// *** Image to be resized is taller (portrait)
{
$optimalWidth = $this->getSizeByFixedHeight($newHeight);
$optimalHeight= $newHeight;
}
else
// *** Image to be resizerd is a square
{
if ($newHeight < $newWidth) {
$optimalWidth = $newWidth;
$optimalHeight= $this->getSizeByFixedWidth($newWidth);
} else if ($newHeight > $newWidth) {
$optimalWidth = $this->getSizeByFixedHeight($newHeight);
$optimalHeight= $newHeight;
} else {
// *** Sqaure being resized to a square
$optimalWidth = $newWidth;
$optimalHeight= $newHeight;
}
}

return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
}

## --------------------------------------------------------

private function getOptimalCrop($newWidth, $newHeight)
{

$heightRatio = $this->height / $newHeight;
$widthRatio = $this->width / $newWidth;

if ($heightRatio < $widthRatio) {
$optimalRatio = $heightRatio;
} else {
$optimalRatio = $widthRatio;
}

$optimalHeight = $this->height / $optimalRatio;
$optimalWidth = $this->width / $optimalRatio;

return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
}

## --------------------------------------------------------

private function crop($optimalWidth, $optimalHeight, $newWidth, $newHeight)
{
// *** Find center - this will be used for the crop
$cropStartX = ( $optimalWidth / 2) - ( $newWidth /2 );
$cropStartY = ( $optimalHeight/ 2) - ( $newHeight/2 );

$crop = $this->imageResized;
//imagedestroy($this->imageResized);

// *** Now crop from center to exact requested size
$this->imageResized = imagecreatetruecolor($newWidth , $newHeight);
imagecopyresampled($this->imageResized, $crop , 0, 0, $cropStartX, $cropStartY, $newWidth, $newHeight , $newWidth, $newHeight);
}

## --------------------------------------------------------

public function saveImage($savePath, $imageQuality="100")
{
// *** Get extension
$extension = strrchr($savePath, '.');
$extension = strtolower($extension);

switch($extension)
{
case '.jpg':
case '.jpeg':
if (imagetypes() & IMG_JPG) {
imagejpeg($this->imageResized, $savePath, $imageQuality);
}
break;

case '.gif':
if (imagetypes() & IMG_GIF) {
imagegif($this->imageResized, $savePath);
}
break;

case '.png':
// *** Scale quality from 0-100 to 0-9
$scaleQuality = round(($imageQuality/100) * 9);

// *** Invert quality setting as 0 is best, not 9
$invertScaleQuality = 9 - $scaleQuality;

if (imagetypes() & IMG_PNG) {
imagepng($this->imageResized, $savePath, $invertScaleQuality);
}
break;

// ... etc

default:
// *** No extension - No save.
break;
}

imagedestroy($this->imageResized);
}

## --------------------------------------------------------

}
?>


Related Topics



Leave a reply



Submit