Skip to content
This repository has been archived by the owner on Aug 12, 2023. It is now read-only.

Custom sizes with different suffix names. #15

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
# v0.3.1
## 13/05/2018

1. [](#bugfix)
* Process resizing if original image width equal defined resized version width

# v0.3.0
## 19/04/2018

1. [](#new)
* Use custom suffix names for pre-generated images

# v0.2.2
## 03/03/2017

Expand Down
85 changes: 34 additions & 51 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,51 +1,34 @@
# [Grav](http://getgrav.org) Resize Images Plugin

**This plugin is still young! If you encounter any issues, please don't hesitate
to [report
them](https://github.com/fredrikekelund/grav-plugin-resize-images/issues).**

> Resize images at upload time in the Grav admin

Grav provides some nifty built-in features for editing images on the fly through
the use of [Gregwar/Image](https://github.com/Gregwar/Image). But there's no
support yet for automatically generating responsive image alternatives at upload
time rather than at request time. This plugin fixes that! It will automatically
resize images that are uploaded through the [Grav
admin](https://github.com/getgrav/grav-plugin-admin) to a set of predetermined
widths. This means improved performance for Grav, and less manual resizing work
for you. Win-win! :tada:

Moreover, this plugin doesn't support just GD, but also Imagick, which means
you'll get higher quality results than with the
[ImageMedium#derivatives](https://learn.getgrav.org/content/media#sizes-with-media-queries)
method that can be used to generate image alternatives in theme templates.

Images that already have responsive alternatives won't be resized.

## 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 PNG's to JPEG's, 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

Download the [ZIP
archive](https://github.com/fredrikekelund/grav-plugin-resize-images/archive/master.zip)
from GitHub and extract it to the `user/plugins` directory in your Grav
installation.

## CLI

I'm aiming to add support for CLI commands to this plugin as well, to make it
easy to generate responsive image alternatives for already uploaded images.
This is a fork of the (Grav Resize Images Plugin)[https://github.com/fredrikekelund/grav-plugin-resize-images] with a slightly different approach.

## Problem solved
Grav doesn't allow url parameters to generate resized images on the fly.

## Goal
The final purpose of the plugin is to have different images sizes generated on page save.
In my case, Grav is only used as an admin panel to generate a json file ready to be consumed by my front-end app (weither it's React, Angular, VueJs). So I wanted to have pre-generated images, with defined size/names (and not @{size}x names, who wasn't making sens), ready to be displayed in my app.
**note** : It isn't really intended to be used within Grav ecosystem as it's already handling smart caching and as lots of built-in fonctionnalities to display media files.

## Usage
Out of the box the plugin is generating sizes : THUMB (300), SMALL (560), MEDIUM (770), LARGE (1024), FULLSCREEN (1400). But sizes and names can be changed/added/removed depending on your needs.

On the front end-side you can now simply use `<img src="myimage-THUMB.ext" />`.

### Extra
It's great to use it in combinaison with the `resolution.min` attribute of your field options (in your `.yaml` file) to make sure the desired generated image size is available. There isn't any official documentation about it, but it's already available in Grav Admin Plugin `v1.7.3`.

For exemple, with the default sizes, if you want to have all sizes available, here is your options :
```yaml
header.custom.image:
type: file
label: "Image"
destination: 'self@'
accept:
- image/*
resolution:
min:
width: 1400
```

### Roadmap
- Try to hook onAdminAfterAddMedia/onAdminAfterDelMedia events for on-the-fly actions instead of waiting for page save event (it's taking a while for saving mutliples images at once)
- Add a `force regenerate all images` button for when changing plugin options (sizes and/or names)
21 changes: 13 additions & 8 deletions blueprints.yaml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
name: Resize Images
version: 0.2.2
description: Generate responsive versions of images as they are uploaded
version: 0.3.1
description: Generate multiple images sizes as they are uploaded
icon: picture-o
author:
name: Fredrik Ekelund
email: [email protected]
homepage: https://github.com/fredrikekelund/grav-plugin-resize-images
keywords: images, responsive, srcset
bugs: https://github.com/fredrikekelund/grav-plugin-resize-images/issues
docs: https://github.com/fredrikekelund/grav-plugin-resize-images/blob/develop/README.md
name: Stéphane Guigné
email: [email protected]
homepage: https://github.com/guins/grav-plugin-resize-images
keywords: images, responsive, srcset, resize, Imagick, GD, javascript, js, front-end, React, Angular, Vue
bugs: https://github.com/guins/grav-plugin-resize-images/issues
docs: https://github.com/guins/grav-plugin-resize-images/blob/master/README.md
license: MIT

form:
Expand Down Expand Up @@ -61,3 +61,8 @@ form:
min: 0
max: 100
default: 82
.name:
type: text
label: Name
placeholder: THUMB
default: ''
91 changes: 73 additions & 18 deletions resize-images.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@
require_once 'adapters/imagick.php';
require_once 'adapters/gd.php';

/**
* TODO :
- Separate create and delete actions
- Try to use onAdminAfterAddMedia/onAdminAfterDelMedia for on-the-fly actions
- Delete images when page is deleted ?
*/

/**
* Class ResizeImagesPlugin
* @package Grav\Plugin
Expand Down Expand Up @@ -112,14 +119,19 @@ public function onAdminSave($event)
}

$this->sizes = (array) $this->config->get('plugins.resize-images.sizes');
$this->adapter = $this->config->get('plugins.resize-images.adapter', 'imagick');
$this->sizesNames = array_map(function($size) {
return $size['name'];
}, $this->sizes);

foreach ($page->media()->images() as $filename => $medium) {
$this->adapter = $this->config->get('plugins.resize-images.adapter', 'imagick');
$mediaCount = count($page->media()->images());
$allImages = $page->media()->images();
foreach ($allImages as $filename => $medium) {
$message = '';
$srcset = $medium->srcset(false);
$sizesNames = implode('|', $this->sizesNames);

if ($srcset != '') {
continue;
}
// $message .= "{$filename} ";

// We can't rely on the path returned from the image's own path
// method, since it points to the directory where the image is saved
Expand All @@ -129,18 +141,65 @@ public function onAdminSave($event)
$source_path = "$page_path/$filename";
$info = pathinfo($source_path);
$count = 0;
$sizeRegexp = "/-({$sizesNames})\.{$info['extension']}$/";
$isResizedFile = preg_match($sizeRegexp, $filename);

// Stop here is it's a resized file
if ( $isResizedFile ) {
$hasOriginalFile = false;
$orginialFileName = preg_replace($sizeRegexp, ".{$info['extension']}", $filename);

// Try to find the original/non-resized file
foreach ($allImages as $subFilename => $subMedium) {
if ( $orginialFileName == $subFilename )
{
$hasOriginalFile = true;
break;
}
}

// If the orignal file is missing then also delete this resized version
if ( !$hasOriginalFile ){
unlink($source_path);
$message .= "$filename - deleted, because original file was missing";
} else {
// $message .= "$filename - skip, it's a resized file";
}

$this->grav['admin']->setMessage($message, 'info');
continue;
}

$hasResizedFiles = false;
$resizedFileRegexp = "/{$info['filename']}-({$sizesNames})\.{$info['extension']}$/";

foreach ($allImages as $subFilename => $subMedium) {
if ( preg_match($resizedFileRegexp, $subFilename) )
{
$hasResizedFiles = true;
break;
}
}

// Stop here if the file already has resized version(s)
if ( $hasResizedFiles ) {
// $message .= "$filename - skip, it already has resized file(s)";
$this->grav['admin']->setMessage($message, 'info');
continue;
}

foreach ($this->sizes as $i => $size) {
if ($size['width'] >= $medium->width) {
if ($size['width'] > $medium->width) {
continue;
}

$count++;
$dest_path = "{$info['dirname']}/{$info['filename']}@{$count}x.{$info['extension']}";
$sizeName = $size['name'] ?: "SIZE{$count}";
$dest_path = "{$info['dirname']}/{$info['filename']}-{$sizeName}.{$info['extension']}";
$width = $size['width'];
$quality = $size['quality'];
$height = ($width / $medium->width) * $medium->height;

$this->resizeImage($source_path, $dest_path, $width, $height, $quality, $medium->width, $medium->height);
}

Expand All @@ -149,22 +208,18 @@ public function onAdminSave($event)
if ($count > 0) {
$original_index = $count + 1;

$message .= " Resized $filename $count times";

if ($remove_original) {
unlink($source_path);
} else {
rename($source_path, "{$info['dirname']}/{$info['filename']}@{$original_index}x.{$info['extension']}");
}

rename("{$info['dirname']}/{$info['filename']}@1x.{$info['extension']}", $source_path);
$message .= ' (and removed the original image)';
}
}

$message = "Resized $filename $count times";

if ($remove_original) {
$message .= ' (and removed the original image)';
if ( $message && $message != '' ) {
$this->grav['admin']->setMessage($message, 'info');
}

$this->grav['admin']->setMessage($message, 'info');
}
}
}
25 changes: 15 additions & 10 deletions resize-images.yaml
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
enabled: '1'
enabled: true
adapter: imagick
remove_original: '0'
remove_original: false
sizes:
-
width: 640
quality: 92
-
width: 1000
width: 300
quality: 90
name: THUMB
-
width: 1500
quality: 87
width: 560
quality: 88
name: SMALL
-
width: 2500
width: 770
quality: 85
name: MEDIUM
-
width: 1024
quality: 82
name: LARGE
-
width: 3500
width: 1400
quality: 82
name: FULLSCREEN