kirgy
kirgy

Reputation: 1607

Crop and resize theory

I need some guidance on the theory behind cropping and resizing images around a focal point, with a bounding box.

In my situation, I have a variety of different image size requirements (100x100, 500x200, 1200x50 for example) at different definitions (1x, 2x, 3x etc.).

The definitions effectively turn 50x50 cropped image into a 100x100 cropped image, thus providing a 2x definition for higher screen definition devices.

I'm provided with a user's uploaded image with an x,y focal point, and a bounding box with two x,y coordinates (topLeft[x,y], bottomRight[x,y]).

What is the theory being turning my user provided image into a variety of images at different sizes and resolutions? Research has led me to find one or the other, but not all of my requirements together.

In my specific environment, I'm using PHP, Laravel and the image Intervention library, although this is somewhat irrelevant due to the nature of this question.

Upvotes: 1

Views: 764

Answers (1)

delboy1978uk
delboy1978uk

Reputation: 12365

Here's an image class I wrote some while back which uses the GD lib.

https://github.com/delboy1978uk/image/blob/master/src/Image.php

I didn't write code for resizing and cropping based on a focal point, but I do have a resizeAndCrop() method that works on the premise that the focal point is in the centre:

public function resizeAndCrop($width,$height)
    {
        $target_ratio = $width / $height;
        $actual_ratio = $this->getWidth() / $this->getHeight();

        if($target_ratio == $actual_ratio){
            // Scale to size
            $this->resize($width,$height);

        } elseif($target_ratio > $actual_ratio) {
            // Resize to width, crop extra height
            $this->resizeToWidth($width);
            $this->crop($width,$height,true);

        } else {
            // Resize to height, crop additional width
            $this->resizeToHeight($height);
            $this->crop($width,$height,true);
        }
    }

here's the crop() method, which you can set a focal point to left, center or right:

/**
 * @param $width
 * @param $height
 * @param string $trim
 */
public function crop($width,$height, $trim = 'center')
{
    $offset_x = 0;
    $offset_y = 0;
    $current_width = $this->getWidth();
    $current_height = $this->getHeight();
    if($trim != 'left')
    {
        if($current_width > $width) {
            $diff = $current_width - $width;
            $offset_x = ($trim == 'center') ? $diff / 2 : $diff; //full diff for trim right
        }
        if($current_height > $height) {
            $diff = $current_height - $height;
            $offset_y = ($trim = 'center') ? $diff / 2 : $diff;
        }
    }
    $new_image = imagecreatetruecolor($width,$height);
    imagecopyresampled($new_image,$this->_image,0,0,$offset_x,$offset_y,$width,$height,$width,$height);
    $this->_image = $new_image;
}

I won't bother explaining imagecopyresampled() since you were just looking for theory behind the cropping, but the docs are here http://php.net/manual/en/function.imagecopyresampled.php

Bear in mind, resizing images using PHP's GD library is memory intensive, depending on the size of the image. I like to use imagemagick, which PHP has a wrapper class called Imagick, worth looking at if you run into trouble.

I hope this helps you, good luck!

Upvotes: 2

Related Questions