Andrew
Andrew

Reputation: 7788

Resize images and fit each image into the square mantaining aspect ratio (backend)

I don't have any experience with PHP and images in general, but I have a need to resize all images into the square when they get uploaded.

Since I have multiple products and they have different pictures that comes in different sizes, I think that the best approach is to 'standardize' them during the upload by taking an image and 'fitting' it into the 800x800 white square while maintaining the aspect ratio (if longest size >800 then downsize, if longest size <800, then re-size).

My initial solution was created via JavaScript, where I tried to find the biggest picture and resize all other images according to it. Although, it is not very useful and can be faulty since if there is a delay in image load, images might not be loaded for JS to perform the operation, thus not showing images at all.

$product = getProductById($productid);

$filesArray = array();


if (isset($_GET['files']) && $productid > 0) {
    $error = false;
    $files = array();
    $fileName = '';

    $uploaddir = "../images/products/";
    foreach ($_FILES as $file) {
        $ext = pathinfo($file['name'], PATHINFO_EXTENSION);
        $random_name = $widgets->randomFileName();
        $randomFullFileName = $productid .'_'. $random_name . '.' . $ext;

        //copy to location
        //----------------
        //HERE I NEED TO CREATE A 800x800px SQUARE and fit the image into it
        //----------------
        if (move_uploaded_file($file['tmp_name'], $uploaddir . $randomFullFileName)) {

            //save to database
            $image_id = updateProduct('default_image', 'images/products/'.$randomFullFileName, $productid);

            if ($image_id > 0) {
                echo 'Added new image';
            } else {
                echo 'Error, unable to add. <br> Please try again.';
            }
        } else {
            echo 'Error, unable to add. <br> Please try again.';
        }
    }
}

Before: 600x300 BEFORE

After: 800x800 with white borders to fill-in the space AFTER

Upvotes: 2

Views: 3072

Answers (2)

userlond
userlond

Reputation: 3828

Original answer

How about imagine?

Insert this code before //save to database comment:

<?php
$imagine = new Imagine\Gd\Imagine();
$size = new Imagine\Image\Box(800, 800);
$mode = Imagine\Image\ImageInterface::THUMBNAIL_INSET;
$imagine
    ->open($uploaddir . $randomFullFileName)
    ->thumbnail($size, $mode)
    ->save($uploaddir . $randomFullFileName);

New answer

As resize is not working like expected (thanks to @Pradeep Sanjaya), I would paste solution based on snippet from link:

/**
 * Image resize
 * @param string $input Full path to source image
 * @param string $output Full path to result image
 * @param int $width Width of result image
 * @param int $height Height of result image
 */
function resizeImage($input, $output, $width, $height)
{
    $imagine = new Imagine\Gd\Imagine();
    $size = new Imagine\Image\Box($width, $height);
    $mode = Imagine\Image\ImageInterface::THUMBNAIL_INSET;
    $resizeimg = $imagine
        ->open($input)
        ->thumbnail($size, $mode);
    $sizeR = $resizeimg->getSize();
    $widthR = $sizeR->getWidth();
    $heightR = $sizeR->getHeight();

    $preserve = $imagine->create($size);
    $startX = $startY = 0;
    if ($widthR < $width) {
        $startX = ($width - $widthR) / 2;
    }
    if ($heightR < $height) {
        $startY = ($height - $heightR) / 2;
    }
    $preserve
        ->paste($resizeimg, new Imagine\Image\Point($startX, $startY))
        ->save($output);
}

And usage according to original question:

<?php
// placed after `save to database` comment
resizeImage(
    $uploaddir . $randomFullFileNamem,
    $uploaddir . $randomFullFileName,
    800, 800
);

Upvotes: 1

Rajdeep Paul
Rajdeep Paul

Reputation: 16963

You can try this approach (tested). It will fit your images into an 800x800 square canvas while maintaining the aspect ratio of your images.

resize_image(): This function will maintain the aspect ratio of your image.

function resize_image($img,$maxwidth,$maxheight) {
    //This function will return the specified dimension(width,height)
    //dimension[0] - width
    //dimension[1] - height

    $dimension = array();
    $imginfo = getimagesize($img);
    $imgwidth = $imginfo[0];
    $imgheight = $imginfo[1];
    if($imgwidth > $maxwidth){
        $ratio = $maxwidth/$imgwidth;
        $newwidth = round($imgwidth*$ratio);
        $newheight = round($imgheight*$ratio);
        if($newheight > $maxheight){
            $ratio = $maxheight/$newheight;
            $dimension[] = round($newwidth*$ratio);
            $dimension[] = round($newheight*$ratio);
            return $dimension;
        }else{
            $dimension[] = $newwidth;
            $dimension[] = $newheight;
            return $dimension;
        }
    }elseif($imgheight > $maxheight){
        $ratio = $maxheight/$imgheight;
        $newwidth = round($imgwidth*$ratio);
        $newheight = round($imgheight*$ratio);
        if($newwidth > $maxwidth){
            $ratio = $maxwidth/$newwidth;
            $dimension[] = round($newwidth*$ratio);
            $dimension[] = round($newheight*$ratio);
            return $dimension;
        }else{
            $dimension[] = $newwidth;
            $dimension[] = $newheight;
            return $dimension;
        }
    }else{
        $dimension[] = $imgwidth;
        $dimension[] = $imgheight;
        return $dimension;
    }
}

And now comes your code,

$product = getProductById($productid);

$filesArray = array();


if (isset($_GET['files']) && $productid > 0) {
    $error = false;
    $files = array();
    $fileName = '';

    $uploaddir = "../images/products/";
    foreach ($_FILES as $file) {
        $ext = pathinfo($file['name'], PATHINFO_EXTENSION);
        $random_name = $widgets->randomFileName();
        $randomFullFileName = $productid .'_'. $random_name . '.' . $ext;

        //copy to location
        //----------------
        //HERE I NEED TO CREATE A 800x800px SQUARE and fit the image into it


        // Create image from file
        $image = null;
        switch(strtolower($file['type']))
        {
            case 'image/jpeg':
                $image = imagecreatefromjpeg($file['tmp_name']);
                break;
            case 'image/png':
                $image = imagecreatefrompng($file['tmp_name']);
                break;
            case 'image/gif':
                $image = imagecreatefromgif($file['tmp_name']);
                break;
            default:
                exit('Unsupported type: '.$file['type']);
        }

        // Get current dimensions
        $old_width  = imagesx($image);
        $old_height = imagesy($image);

        // Get the new dimensions
        $dimension = resize_image($file, 800, 800);
        $new_width  = $dimension[0];
        $new_height = $dimension[1];

        // Create new empty image
        $new = imagecreatetruecolor($new_width, $new_height);

        // Resize old image into new
        imagecopyresampled($new, $image, 0, 0, 0, 0, $new_width, $new_height, $old_width, $old_height);

        // Catch and save the image
        $status = false;
        switch(strtolower($file['type']))
        {
            case 'image/jpeg':
                $status = imagejpeg($new, $uploaddir . $randomFullFileName, 90);
                break;
            case 'image/png':
                $status = imagepng($new, $uploaddir . $randomFullFileName, 0);
                break;
            case 'image/gif':
                $status = imagegif($new, $uploaddir . $randomFullFileName);
                break;
        }

        // Destroy resources
        imagedestroy($image);
        imagedestroy($new);

        //save to database
        if($status){
            $image_id = updateProduct('default_image', 'images/products/'.$randomFullFileName, $productid);

            if ($image_id > 0) {
                echo 'Added new image';
            } else {
                echo 'Error, unable to add. <br> Please try again.';
            }
        }else{
            echo 'Error, unable to add. <br> Please try again.';
        }       

        //----------------
        //if (move_uploaded_file($file['tmp_name'], $uploaddir . $randomFullFileName)) {
        //    //save to database
        //    $image_id = updateProduct('default_image', 'images/products/'.$randomFullFileName, $productid);

        //    if ($image_id > 0) {
        //        echo 'Added new image';
        //    } else {
        //        echo 'Error, unable to add. <br> Please try again.';
        //    }
        //} else {
        //    echo 'Error, unable to add. <br> Please try again.';
        //}

    }
}

Upvotes: 4

Related Questions