Default image settings and new focus crop

Posted 16th Feb 2018

#api #bootstrap4 #images

This guide will show how to set some default image settings for variations and also I'll be testing out the new focus crop available from v3.0.89.

If you followed the tutorial about creating images on the fly and cropping then this just follows on from that. What's different here is that I've upgraded to v3.0.89 which features the awesome new focus crop! So we're going to give that a test run but first I want to show how to set some sitewide defaults for your images which can save having an $options array every time you want to create images on the fly. Sometimes it's useful to be able to have fine grained control and you can still add the array of options into an image resize function whenever you want. However, with the new focus crop, I'd personally only just set the image quality sitewide and be done with it.

If you didn't see the tutorial above, then do the following.

Home (hover) > New

Create an 'Image variations' page using the 'basic-page' template. This template has a single image field called 'featuredImage'. If you need a refresher, you can check out details about the images field type. Upload an image in there so we can do some stuff with it in our template file.

The new focus crop
The new focus crop Zoom

We're going to use the same code as the previous tutorial.

/site/templates/basic-page.php

<?php namespace ProcessWire; ?>

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">

  <title>
    <?php
      // print the current page field altTitle value
      // if blank or not present, print title field value
      echo $page->get("altTitle|title");
    ?>
  </title>

  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">

</head>

<body>


  -- OUR IMAGE CODE WILL GO HERE --


  <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity="sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin="anonymous"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin="anonymous"></script>

</body>

</html>

First of all, let's take a look at the 'imageSizerOptions' variable and what the defaults are that are applied to all your images. Replace '-- OUR IMAGE CODE WILL GO HERE --' with:

<?php
  echo "<pre>";
  print_r($config->imageSizerOptions);
  echo "</pre>";
?>

Now there is a better way than this using the Tracy debugger module, but that would be another tutorial to show how to use that. For now, the above code is fine. This outputs:

Array
(
    [upscaling] => 1
    [cropping] => 1
    [autoRotation] => 1
    [interlace] => 
    [sharpening] => soft
    [quality] => 90
    [hidpiQuality] => 60
    [defaultGamma] => 2
)

We can see that a few defaults are already set for us. We can now change them sitewide if required. It may be tempating to just set a bunch of new options like this:

$config->imageSizerOptions = array(
  "upscaling" => true,
  "cropping" => "north",
  "quality" => 50
);

...but this is a bad idea! What happens here is a new array is saved with just three options in it. The other (default) options are wiped out. So you need to merge an array of your custom options with the default ones. What happens here is that if the array in the second argument of the 'array_merge' function has the same keys as ones in the first, they overwrite them. However, the default options will still remain.Take the example above, and now apply this with 'array_merge':

/site/config.php

// default sitewide image options
$config->customImageSizerOptions = array(
  "upscaling" => true,
  "cropping" => "north",
  "quality" => 50
);

// merge custom options and overwrite only modified values, keeping defaults too
$config->imageSizerOptions = array_merge($config->imageSizerOptions, $config->customImageSizerOptions);

Now go back to your page and refresh it:

Array
(
    [upscaling] => 1
    [cropping] => north // changed
    [autoRotation] => 1
    [interlace] => 
    [sharpening] => soft
    [quality] => 50 // changed
    [hidpiQuality] => 60
    [defaultGamma] => 2
)

And that's about it. These new options will be applied sitewide and you haven't wiped out any of the existing defaults.

The new 'Focus' crop

You can remove the code we added to '/site/config/' as we don't want to preconfigure any cropping here, and you can use this code for the 'basic-page' template file. Replace the code block:

<?php
  echo "<pre>";
  print_r($config->imageSizerOptions);
  echo "</pre>";
?>

...with this new code:

<?php
  // if page has single image field called 'featuredImage' and has an
  // image uploaded to it. This alternate syntax 'if' wraps this whole block of PHP/HTML
  if ($page->featuredImage):

    // save some typing...
    $image = $page->featuredImage;

    // for demo purposes, don't leave this in!
    $options = array(
      "forceNew" => true
    );

    // create four images using image resize functions
    $widthOnly = $image->width(150, $options);
    $heightOnly = $image->height(150, $options);
    $square = $image->size(150, 150, $options);
    $rec = $image->size(150, 75, $options);
  }
?>

<div class="container py-5">
  <div class="row">

    <div class="col">
      <img src="<?php echo $widthOnly->url; ?>" />
      <p>
        Changed width only</br>
        Width: <?php echo $widthOnly->width() . "px"; ?></br>
        Height: <?php echo $widthOnly->height() . "px"; ?>
      </p>
    </div>

    <div class="col">
      <img src="<?php echo $heightOnly->url; ?>" />
      <p>
        Changed height only</br>
        Width: <?php echo $heightOnly->width() . "px"; ?></br>
        Height: <?php echo $heightOnly->height() . "px"; ?>
      </p>
    </div>

    <div class="col">
      <img src="<?php echo $square->url; ?>" />
      <p>
        Changed width and height</br>
        Width: <?php echo $square->width() . "px"; ?></br>
        Height: <?php echo $square->height() . "px"; ?>
      </p>
    </div>

    <div class="col">
      <img src="<?php echo $rec->url; ?>" />
      <p>
        Changed width and height</br>
        Width: <?php echo $rec->width() . "px"; ?></br>
        Height: <?php echo $rec->height() . "px"; ?>
      </p>
    </div>

  </div>
</div>

<?php
  // close alternate syntax if statement
  endif;
?>

You'll notice that we're using "forceNew" => true in this code and passing the array to the image resizer functions. We need this to see our changes when we refresh the page but don't forget to remove the $options array when you're happy with the images (and the $options variable from the resize functions). This renders a few variations of the cat image as seen in the previous tutorial:

The cat variations
The cat variations Zoom

Now let's focus to a part of the image way down in the corner to see what happens. Click the 'Focus' link and drag the little circle down to the bottom left.

Focus bottom left
Focus bottom left Zoom

Save this page in the admin, then refresh your rendered page in the browser:

Focus bottom left rendered
Focus bottom left rendered Zoom

Ok, that seemed to work, the cat has moved out the frame and the bottom left is visible. Now let's try and get the cats face in focus, which is probably best.

Focus cat face
Focus cat face Zoom

Save this page in the admin, then refresh your rendered page in the browser:

Focus cat face rendered
Focus cat face rendered Zoom

Purrrrfect :) what an awesome feature!

Feedback & support

I hope you enjoyed this tutorial. You can support pwtuts by following on @pwtuts. You can also donate at paypal.me/swcarrey to help support the site which would be awesome!

Related tutorials / See all

Suggest a tutorial

Please note: I do not store any of this information, it's simply used to send me an email. Your email address is required so I can get clarification on your request if needed.