# [Grav](http://getgrav.org) Automagic Images Plugin

This plugin started out as a fork from the most excellent [Resize Images](https://github.com/fredrikekelund/grav-plugin-resize-images) by Fredrik Ekelund. That seems unmaintained however, and I needed some image functionality in my projects that I felt would be best bundled up in one plugin.

## Currently it does two things:

1. It resizes a page’s images when you save that page in Admin, according to sizes that can be customised in the plugin’s settings.

For example, if you keep the default settings and upload a 4000x3000 example-image.jpg to a page, upon clicking save it will generate the following versions:
- example-image.jpg (640x480)
- example-image@2x.jpg (1000x750)
- example-image@3x.jpg (1500x1125)
- example-image@4x.jpg (2500x1875)
- example-image@5x.jpg (3500x2625)
- example-image@6x.jpg (4000x3000, original)

If you set `remove original` to `on`, the last version will be deleted instead.

In Grav Admin you will see only the smallest file, but in your file system all the larger versions are still in the same page folder. This is a built-in functionality of Grav which relies on the `@2x` naming convention.


2. It adds a `sizes` directive to your images, according to their CSS class.

*This will not do anything if you don’t set any sizes for your image classes, or if your images do not have classes and you do not define sizes for a default class.*

Let’s say for example that you have some images which all have a class `content-pic` that sets them at 100% width for mobile, at 33% width if the viewport is at least 37.5em (600px) wide, and at 25em width as soon as the viewport reaches 75em (1200px). In this case the sizes settings should be:

```yaml
sizesattr:
  -
    class: 'content-pic'
    directive: '(min-width: 75em) 25em, (min-width: 37.5em) 33%, 100vw'
```

In short, whatever you put in that `directive` will show up directly in your html as a `sizes=""` attribute for images with that class.

If *all* your images are the same size, you could also just set a `default` class which gets applied to any images without a class attribute that has a corresponding sizes setting in the plugin. **The `srcset` attribute will be generated by Grav’s built-in functionality from all the available image variants.**

### A note on performance issues
If you use `cropZoom` or similar on an image, this has nothing to do with the plugin. Whatever you upload gets resized *and saved in the page’s folder* according to your sizes settings and the original image ratio. The images that are generated by using `cropZoom` are stored in Grav’s image cache and have to be re-generated whenever that cache is emptied. Since with this plugin you have several versions of each image which **ALL** get cropZoomed, this can take a while and on pages with a lot of images may result in timeout errors on a cache refresh. In that case you can just reload the page until all the images have been generated and cached.

Same goes for pages where you add twenty images with 7 MB each. That will almost certainly result in a Crikey! timeout error in the Admin upon clicking save – but you can just hit reload until all images have been processed. (I have personally done this for pages with *dozens* of large images, it took several minutes for a timeout after 30 seconds on a regular shared hosting server, and all was fine afterwards.)

### Another note on using `cropZoom` and the like
When there are several different-sized versions of an image present, that seems to throw off Grav’s internal calculations and cropZoomed images will end up a *different* size than what you asked for. This is not the plugin’s fault, if you add your own @2x versions of an image without using this plugin you will run into this issue as well. And as far as I can tell, the sizes of the cropZoomed versions in Grav’s cache are all over the place, more wildly so the larger they are. This is a bug in Grav, unfortunately. I recommend checking your own use case, it may not always be a problem but currently it’s often best not to mix optimised images and programmatic reshaping. :-(

## Why not use Grav’s built-in functionality?
In theory, Grav has all the image-handling capabilities I’d personally need ([see the docs on page media](https://learn.getgrav.org/16/content/media)). However, there are three main reasons why I use this plugin:

1. If you have the Imagick module available, this plugin can use it, resulting in better image quality.
2. There are [currently some bugs](https://github.com/getgrav/grav/issues/3146) in the native image handling system that make it inadvisable to mix cropZoom and the like with setting `sizes` (both in Twig and Markdown).
3. When doing projects for clients, I like to keep things as simple as possible for them, which ideally is “upload an image and Grav does the rest”. If an image is used in Markdown (I try to avoid that as well, but it’s not always possible), I don’t want people to have to deal with setting sizes.

So in short, if you want to lovingly handcraft every image on your site, you do not need this plugin. If you want to set up a system where in the end, you upload an image to a page, click save, and then it just works and the result is fairly good, this is the plugin for you.

A note: Images that already have responsive alternatives with the “@2x” naming convention won’t be resized, so you can also do your own image tweaking if you like.

## Configuration

You can customize the set of widths that your images will be resized to. By default they are 640, 1000, 1500, 2500, 3500 pixels in width. Images will never be scaled up, however, so only the widths that are smaller than the original image’s will be used.

For every width, you’re also able to set the JPEG compression quality.  A good rule of thumb is to lower that number at higher widths - the result will still be good!

This plugin won’t convert PNGs to JPEGs, so the quality number only applies to JPEG images.

To generate variations of existing images go into the admin panel and re-save the pages where those images live. Every time a page is saved (whether it’s new or old), this plugin will go through all images (again, whether they are new or old) in that page, check if they have responsive variants and generate new ones if necessary.

## Installation

Installing the Automagic Images plugin can be done in one of three ways: The GPM (Grav Package Manager) installation method lets you quickly install the plugin with a simple terminal command, the manual method lets you do so via a zip file, and the admin method lets you do so via the Admin Plugin.

### GPM Installation (Preferred)

To install the plugin via the [GPM](http://learn.getgrav.org/advanced/grav-gpm), through your system’s terminal (also called the command line), navigate to the root of your Grav-installation, and enter:

    bin/gpm install automagic-images

This will install the Automagic Images plugin into your `/user/plugins`-directory within Grav. Its files can be found under `/your/site/grav/user/plugins/automagic-images`.

### Manual Installation

To install the plugin manually, download the zip-version of this repository and unzip it under `/your/site/grav/user/plugins`. Then rename the folder to `automagic-images`. You can find these files on [GitHub](https://github.com/skinofthesoul/grav-plugin-automagic-images) or via [GetGrav.org](http://getgrav.org/downloads/plugins).

You should now have all the plugin files under

    /your/site/grav/user/plugins/automagic-images

### Admin Plugin

If you use the Admin Plugin, you can install the plugin directly by browsing the `Plugins`-menu and clicking on the `Add` button.

## Many thanks go to
@fredrikekelund – all credit for the actual code that does all the resizing goes to him.
@olevik – copying and adapting his code from Image Srcset to add the `sizes` per CSS class was a lot easier than writing it all by myself, and also I wouldn’t have learned about the excellent [PHP Html Parser](https://github.com/paquettg/php-html-parser) otherwise.

## Plans for the future
Being able to regenerate ALL images with a click would be incredibly nice, but I really don’t know when I might get around to that. Co-maintainers and -developers are welcome! Also adding support for formats other than jpg and png, that seems easier to do and will be next.