Linesofcode
Linesofcode

Reputation: 5891

PHP check & resize image to meet Instagram requirements

The Instagram image ratio requirements are:

Readed here and here. The documentation also says:

(...) Advise the app user to try again with an image that falls withing a 4:5 to 1.91:1 range.

Althought the documentation doesn't say, I know for a fact that publishing a photo with 1:1 ratio works.

So I would like to check if the image uploaded meets the requirements and if not resize to meet them (either by downsizing or upsizing). I'm using Laravel with Image Intervention library.

To check the aspect ratio, I'm using the following code:

public function isRatioValid($img)
{
    $manager = new ImageManager(['driver' => 'imagick']);
    $image = $manager->make($img);
    $width = $image->width();
    $height = $image->height();
    
    for ($i = $height; $i > 1; $i--) 
    {
        if (($width % $i) == 0 && ($height % $i) == 0) 
        {
            $width = $width / $i;
            $height = $height / $i;
        }
    }

    $ratio = "{$width}:{$height}";

    if (!in_array($ratio, ['1:1', '4:5', '1.91:1', '16:9']))
        return false;
        
    return true;
}

Problems:

  1. This code strictly checks for the ratio values it does not entirely meet the Instagram documentation that says "(...) withing a 4:5 to 1.91:1 range". Is this ok?
  2. In case the ratio is not valid, how can I use the Resize functionality to apply the best ratio that fits the Instagram requirements?

Upvotes: 0

Views: 412

Answers (1)

Linesofcode
Linesofcode

Reputation: 5891

Solved.

The code to check the aspect ratio was not correct. To check it properly all we need to do is divide the width for the height and see if it fits the range of Instagram requirements.

function isRatioValid(...)
{
    $width = 400;
    $height = 711;

    // 1:1 - squares
    if ($width == $height)
        return true;
            
    $ratio = round($width / $height, 3);
        
    // Portrait: min 0.8 | max 0.99
    // Landscape: min 1.01 | max 1.91   
    if ($width < $height)
        if ($ratio >= 0.8 && $ratio <= 0.99)
            return true;
            
    if ($width > $height)
        if ($ratio >= 1.01 && $ratio <= 1.91)
            return true;
    
    return false;
}

To resize it, I added 0.10 to either the width (portraits) or height (landscapes) until the aspect ratio was within the range. You should limit the amount of tries so it won't burn the CPU / max execution time.

Upvotes: 1

Related Questions