Add-on Documentation from JCOGS Design

Advanced TopicsLast updated: 5 November 2022

Image Caching

To improve performance JCOGS Image uses a powerful image caching system to store copies of processed images on the server. Where possible JCOGS Image will re-use a cached copy of processed image rather than re-processing the source each time a template is called.

To be effective a caching system needs to be flexible, efficient and reliable, and this is an area where JCOGS Image performance is significantly better than (e.g.) CE Image. The key enhancements offered by JCOGS Image are:

  • fine-grained control over caching - letting you set caching strategies on a per-image basis
  • support for variable cache-durations in addition to the ‘perpetual’ and ‘none’ options offered by CE image
  • a more reliable association between source image, processing options and cached copy
  • a unified cache - only one cache copy of an image is required - regardless of how many templates it appears within, the same cache copy will be used
  • auto-cache maintenance actively removes redundant cached images from the cache

To work reliably the caching mechanism needs to be able to differentiate between small differences in the image processing options chosen for a source image, it also needs to know the caching lifetime chosen for the image when it was created.  JCOGS Image does all this through the filename given to a processed file - which is a combination of the original image file name, a marker to indicate the cache lifetime chosen for the image, and a cache-key reflecting all of the operations and parameters applied to the image during processing. It is this filename based caching approach makes it possible for cached copies of all processed images to be stored in the same directory, which in turn makes it possible for the same cached image to be used where ever on a site a particular combination of image and manipulations is required.

Time based caching

An innovation offered by JCOGS Image is the option to set expiry times for processed images - if your site uses an image from a remote location that changes periodically but keeps the same URL, this innovation allows you to instruct JCOGS Image to refresh the local processed copy of the remote image on a similar frequency, automatically.

Automatic image cache maintenance

JCOGS Image enables automatic image cache maintenance by default, it can be disabled via the JCOGS Image Control Panel based settings panel. Automatic image cache maintenance is simply a process by which JCOGS Image scans the processed images in the cache folder, and removes any for which the cache life-time specified for the image has been exceeded.

Cooperating with other caching systems

JCOGS Image's caching system attempts to work with other caching systems: it only updates images that are in its cache and whose cache life has expired when it knows that EE is updating the template concerned - so if you store the site templates using a ‘perpetual’ static cache, even if the images in JCOGS Image's cache expire they will not be deleted / recreated until the next time EE updates the relevant templates. Under such circumstances the cache duration settings used for an image will not always have the effect expected.

Usage Notes

JCOGS Image's approach to caching helps it avoid storing multiple versions of the same image simply because the image is used in a different template (as is the case with the path based caching such as used by CE Image), or storing copies of versions of images that are never actually used by the site (as is the case with Image Modifications in EE's File Manager).

Image Formats

The format options available are determined by the abilities of the php image processing library used on the server running the EE instance. JCOGS Image actively monitors the available formats and only makes available formats that are supported: the formats available are listed in the JCOGS Image Control Panel settings page in the drop-down for ‘Default Image Format’ (which also ensures that the Default Image Format is always one that can be processed by the server!).

If you specify an image format in a JCOGS Image tag that is not supported by the server, JCOGS Image will use the Default Image Format to encode the image instead.

For GD2 (the default library used by JCOGS Image) commonly available formats include:

extension

image format

bmp

Windows bitmap format

gif

Graphics Interchange Format

jpeg/jpg

JPEG image format

png

Portable Network Graphics 

webp

Webp 

For an image to be seen in a browser it is also important that the browser viewing the web page also supports the image format chosen. Where possible, when processing an image JCOGS Image actively checks that the current browser is able to display the format chosen; if the browser would not be able to display the image format chosen JCOGS Image substitutes a format that is supported both by the server and the browser (usually JPG).

JCOGS Image also offers limited support for handling SVG files.

The choice of which image formats to use when is a complex discussion area, and outside the scope of this manual to consider.

Transparency

Not all image formats support transparency. Where possible transparency in images is preserved by JCOGS Image during processing, but for transparency to be maintained in a processed image it is also important to make sure that the image is saved in a format that also supports transparency: in particular if you are manipulating a PNG image with transparency and wish the processed image to retain this transparency, make sure you specify an appropriate format either in the save_type= parameter in your tag, or as the Default Image Format.

Please note also that not all filter operations preserve transparency. 

When transparency is removed during a operation, the transparent pixes are replaced by pixels coloured according to whatever colour is chosen as the (default) background colour. 

Lossy vs Lossless

JCOGS Image always attempts to save images using the smallest file size option available for any given format. So for PNG and WebP images which support both lossy and lossless image storage formats, the images are saved using the lossy (compressed) format.

A future update to JCOGS Image will aim to offer both lossy and lossless compression options for these image formats, however it is worth noting that when offered this facility will also depend such support also being made available via the php libraries JCOGS Image uses.  So for example due to a constraint within php support for lossless Webp will require the server to be running php 8.1 or better.

Image Optimisation

A variety of utilities offer options to ‘optimise’ images of some image formats (most notably images of PNG or JPG type). ‘Optimisation’ generate similar looking images to the source, but with a smaller filesize. Promotional literature for the various image optimisation routines available often note that dramatic file sze reductions can be obtained, particularly for PNG images. The saving in file size coming from usually the ommission of ‘redundant' data from the source image. However, to allow maniuplation of an optimised image, these optimisations usually have to be reversed.

JCOGS Image is able to work with most ‘optimised’ images,  but does not save images back to their optimised state.

The tools used by libraries to optimise images typically are not included in standard web server builds, and so it is not easy for JCOGS Image to include ‘optimisation’ steps within its core feature set (though such will be considered in some future update).

If you are using JCOGS Image on a regular server then JCOGS Image will automatically substitute an image format of that the user's browser can view should your site be viewed by a browser not able to handle webp images. If you are using JCOGS Image on a server with a static cache - where JCOGS Image's auto-substitution tools will not work - define your images using the HTML <picture> tag with web as the main image, with a jpg or png alternative image specified in a <source> declaration.

Usage Notes

Webp - better than optimised PNG 

In our limited testing we find that the filesize saving achieved by PNG optimisers while dramatic (up to 50%) is small compared to the saving achieved by moving a PNG to WEBP format (up to 75%). So our recommendation for now is that if minimisation of image filesize is critical to your applictation, consider using webp as the default image format. 

Hooks

JCOGS Image provides three hooks that are functionally equivalent to the hooks offered by CE Image. The hooks offered are:

CE Image HookJCOGS Image HookDescription
ce_img_startjcogs_img_start

Called when image processing starts. 

Accepts no data. 

Returns no data.

ce_img_pre_parsejcogs_img_pre_parse

Called when image processing is complete but before any tagdata from the calling tag-pair is parsed prior to its return to the template. The hook thus allows you to manipulate the image variables before they are returned to the template. 

The following data is passed by the hook when called:
   $tagdata: The un-parsed tagdata.
   $variables: The array of all of the variables that will be parsed before the tagdata is returned to the template.
 

The $tagdata must be returned to the hook when your local processing of it is completed.

ce_img_savedjcogs_img_savedCalled when an image is saved. The hook returns:
   $this->path_final: The local path on the server to the saved image.
   $type: The image type, which will be one of the following: ‘bmp’, ‘gif’, ‘jpg’, ‘jpeg’, 'png', 'webp'

Lazy Loading

Lazy loading is a technique to speed up the loading of image intensive pages: in its simplest form lazy loading prevents the downloading images that are outside the part of the screen currently being viewed by the user.

The simple implementation can lead to multiple issues that present to the user through a degraded experience both visually (for example layout ‘jank’) and functionally (causing problems for users of assistive technologies). 

The best approaches to lazy-loading (and web design in general) adopted the design philosophy of progressive enhancement.  Lazy loading is something that can only happen within browsers that support local processing - i.e. browsers that have javascript support and javascript processing enabled. Even though very few users of a site arrive without javascript support (probably less than 1%) the lazy loading solution is better if it fails gracefully for such users.

JCOGS Image's approach to lazy loading supports progressive enhancement, is efficient, fast and offers strong compatibility with current browsers.

Use of JCOGS Image Lazy loading is triggered by adding the lazy= parameter to a tag, or by enabling it as a system default in the JCOGS Image add-on control panel area.

Starting with a plain tag <img src="my_image.jpg">, the JCOGS Image lazy loading feature does the following:
 

  1. it adds the HTML5 loading="lazy" parameter to <img> tags it creates. This encourages the browser to defers loading the image files defined in the <img> src= and srcset= parameters until they come close to the browser viewport, this works only in browsers that implement HTML5 and have javascript turned on, it is ignored in browsers where this option is not supported;
    <img src="my_image.jpg"loading="lazy">
  2. it replaces the processed image within the <img> tag with a placeholder image created from the processed image; the placeholder images have the same dimensions as the processed image but are either a low-resolution version of that image, or a plain colour field that is keyed to the ‘dominant colour’ of the processed image, and so the placeholder images are represented by much smaller image files than the processed image, and so even if the HTML5 loading='lazy' parameter is ignored the amount of image data downloaded by the browser on initial load is reduced;
    <img src="lqip_my_image.jpg"data-ji-src="my_image.jpg">
  3. it adds an additional ‘fallback’ <img> definition to the page for each image processed that is only visible if javascript is not present or enabled - on the basis that if a browser does not support javascript it might not support advanced image formats, if the save_type for the current image is not jpg a jpg version of the processed image is created so it can be linked to by this noscript image tag;
    <img src="lqip_my_image.jpg" data-ji-src="my_image.jpg"><noscript class="ji__progenhlazyns"><img src="my_image.jpg"  ></noscript>
  4. it adds a CSS rule to the page that hides the <img> tags that have lazy loading changes if javascript is not present;
    <noscript><style>[data-ji-src]{display:none;}</style></noscript>
    <img src="lqip_my_image.jpg" data-ji-src="my_image.jpg"><noscript class="ji__progenhlazyns"><img src="my_image.jpg"  ></noscript>
  5. it adds a small javascript utility to the page which (i.e. if javascript is supported) deletes the ‘no javascript’ images from the page (since if javascript is active they are not needed) and enables a monitor that checks to see if a JCOGS Image lazy loaded image is getting close to the browser viewport. When the image gets close the javascript replaces the src= definition (which is pointing at the placeholder image) with a new version that is pointing at with the full-resolution processed image. This change triggers the browser to download the full-resolution image and display it - so the user mostly only ever sees the full-resolution version.

The method used works and for the most-part is transparent to the user and not dependent upon browser javascript support.

JCOGS Images' lazy-loading system is completely compatible with its responsive image options delivered via the srcset= option.

Usage Notes

Lazy-loading is only applied to <img> tags that are generated by JCOGS Image. 

If you use JCOGS Image to generate output that is not a complete <img> tag (e.g. using a tag-pair configuration to construct an image tag using Image Variables, or including url_only="yes" or output= parameters in a single tag) then the lazy= tag will be ignored.

Migrating from CE Image

JCOGS Image is a modern, supported, effective replacement for CE Image

CE Image is an image manipulation add-on that was created to work with ExpressionEngine 2 and 3. In its day it was a popular add-on and is implemented on many legacy sites. However CE Image is not supported and has not been updated since 19 June 2017 (when version 3.0.1 was released): sites that use it face challenges when updating to newer versions of ExpressionEngine as recoding the templates of these older sites to use alternative solutions is time consuming and difficult.

JCOGS Image is an entirely new add-on written expressly for use on EE5 and EE6 systems which is compatible with the latest features of these modern versions of the CMS. JCOGS Image provides powerful extensions to the Image processing capabilities of EE, supporting more image formats (including webp), a broad range of manipulations and filter options, and useful built in features such as automatic lazy loading. JCOGS Image is also compatible with php8 and actively supported. In addition to these benefits, JCOGS Image also offers a very high degree of tag-level compatibility with CE Image; offering developers a simple to implement but very high quality upgrade path for sites that were developed using CE Image.

Parameter compatibility

Currently JCOGS Image has full parameter level compatibility for 30 of the 36 parameters supported by CE Image (excluding parameters associated with file handling). None of the currently unsupported parameters are ones that are commonly used, and so in the very large majority of use cases JCOGS Image is able to fully replace CE Image.

Some of the missing parameters are unlikely to ever be supported (e.g. the option to create ASCIIart versions of pictures), but others will be included in future updates (for example support for adding text and watermarks was added in version 1.1).  

Variable compatibility

JCOGS Image supports all of the variables that were made available by CE Image, so any code that relies upon this advanced use option will work identically with JCOGS Image.

Filter compatibility

JCOGS Image provides 100% compatibility with CE Image parameter definition syntax for filters, and equivalent filters for 16 of the 22 filters offered by CE Image. Some of the missing filters  - such as sobel edgify - are unlikely to be supported, but most of the missing ones will be added in future updates.

File handling compatibility

JCOGS Image approaches the storing and caching of processed images in a quite different way to CE Image. In practical terms these differences make no difference to operational use of the add-on, but do mean that some of the parametric controls available in CE Image are no longer necessary (or meaningful).

Performance compatibility

In a test profile covering all of the parametric and filter options available JCOGS Image was found to process images more quickly than CE Image on the same set of test operations, and produce smaller image files: across 33 equivalent images the files produced by JCOGS Image used approximately 55% of the space required by the CE Image output.

‘Drop-in’ upgrades

For most sites the very high degree of compatibility between JCOGS Image and CE Image tag parameters mean that updating a template is a straightfoward 3 step process:

  1. Install JCOGS Image add-on on your EE5 or EE6 system.
  2. Open a template in you favourite editor, search for “exp:ce_img” and replace these instances with “exp:jcogs_img”
  3. Save the template, reload the affected page in ExpressionEngine.

That's it. It's pretty easy and (to the best of our knowledge) works!  However if this is too much, we are working on an ‘auto update’ system that will do these steps for you… 

N.B. As would be the case for any update of a site, you are strongly encouraged to keep good backups while you do any major changes in site configuration or software.

Nesting Tags

Most operations that you might want to carry out on an image source can be completed by adding parameters to a single JCOGS Image tag, but sometimes it is useful to apply an transformation to an already transformed image. To support this needs JCOGS Image supports the ‘nesting’ of tags - putting one JCOGS Image tag ‘within’ another, and using the output of the ‘inner' tag as the source image for the operations of the outer tag.

So for example, here is a pair of tags being applied to a single image source: 

{exp:jcogs_img:image 
parse="inward"
border="5|4a2d14"
create_tag='yes'
src="{exp:jcogs_img:single 
    url_only='yes'
     src='{images}' 
     width='300px' 
     border='5'}"
}
{/exp:jcogs_img:image}

The effect of these two ‘nested’ tags is to add two borders to the original image, and to resize the source image so that it is (before the borders are added) 300px wide.

Example of image tag nesting.

 

As the example tag above illustrates, if you plan to ‘nest’ JCOGS Image tags within your templates there are a few of things to remember:

Use parse="inward" to ensure enclosed tags are processed first

EE's template parser normally does a good job of working out the correct sequence to work through the tags within a template, but when the tags are calls to the same add-on/method sometimes this does not work so well. For JCOGS Image, it helps to put the EE parameter parse='inward' into the parameter list for an ‘outer’ tag to ensure that processing of the ‘inner’ tag is completed before the processing of the outer tag begins.

{exp:jcogs_img:image 
parse="inward"
border="5|4a2d14"
create_tag='yes'
src="{exp:jcogs_img:single 
    url_only='yes'
     src='{images}' 
     width='300px' 
     border='5'}"
}
{/exp:jcogs_img:image}

Use different method names and / or tag-pairs to sidestep EE parsing issues

Sometimes the EE template parser can get confused when you have more than one tag that can exist in both single-tag and tag-pair modes.  Consider this example:

{exp:jcogs_img:image src=...}
... some template code ...
{exp:jcogs_img:image src=...}
... some JCOGS Image variables and other content ... 
{/exp:jcogs_img:image}

EE's template parser will get confused about which opening tag the {/exp:jcogs_img:image} closing tag refers to - probably choosing the first tag as the opening one - which will lead to unexpected / unwanted results.  There are two ways to avoid this:

Always use closing tags - this option avoids the confusion, but keep in mind (for CE Image compatbility) tag-pairs intepret some parameters in a different way to single tag (for example the create_tag parameter)

{exp:jcogs_img:image src=...}
{/exp:jcogs_img:image}
... some template code ...
{exp:jcogs_img:image src=...}
... some JCOGS Image variables and other content ... 
{/exp:jcogs_img:image}

Use different JCOGS Image names to avoid the confusion - If you use a different method name for single tags to tag-pairs you can also avoid this parsing confusion. JCOGS Image gives you the choice of three alternative names - image, single, and pair.

{exp:jcogs_img:single src=...}
... some template code ...
{exp:jcogs_img:image src=...}
... some JCOGS Image variables and other content ... 
{/exp:jcogs_img:image}

Usage Notes

Note: if you use the tag-pair form, remember that for this tag to generate any output you either need to specify some template variables between the tag pair, or add the parameter create_tag='yes' to the parameters for the outer tag.

Pass-through attributes and attribute consolidation

JCOGS Image provides powerful options for ‘passing through’ HTML parameters to the finished HTML <img> tag (or other tags if you are using the tag-pair approach to build advanced HTML tags).

Any parameters included within a JCOGS Image tag that are not valid JCOGS Image parameters are collected up and added to the tag output - either as attributes included within a created <img> tag, or as the content of the {attributes} variable.  This allows you to simply add any additional parameters you would like to include in the output <img> tag to those included to control the image processing.

For example:

{exp:jcogs_img:image 
width="300"
class="cats"
data-item='kibble'
src="{images}"
}

will produce a tag of this form:

<img src="..." class="cats" data-item="kibble">

You can also include additional parameters to pass through to the output / attributes variable by: 

  • adding an attributes="" parameter to your tag - whatever is enclosed in this parameter is appended to the attributes variable output and / or included in the generated <img> tag
  • enclosing attribute entries between a pair of JCOGS Image tags when you have also set create_tag="yes"

Special handling for Class and Style attributes

Because you can specify additional attributes in several places it is possible for JCOGS image to find multiple examples of attributes defined within your tag inputs.  For class and style attributes (only) JCOGS Image will collect and consolidate the content from multiple attributes and deliver just one class and one style tag that contains all of the applicable content - it will also attempt to remove duplicate style or class entries if there are any.

Specifying Colours

Several of the parameters used by JCOGS Image require the specification of colours.

JCOGS Image supports use of both hex-code and CSS type rgb() and rgba() colour specification models.

Hex-code format

Originally based on use of a hexadecimal triplet with each pair of digits relating to one of the R, G and B components of the web standard  RGB colour model, the hex-code format has over time expanded to represent colours using three, four, six or eight digit hexadecimal numbers.

JCOGS Image will accept any valid version of the hex-code format in any colour parameter - adding a leading # if one is omitted:

  • Three-digit and four-digit hex codes are converted to six-digit and eight-digit hex codes before processing by duplicating each value - so #rgb → #rrggbb, and #rgba → #rrggbbaa.
  • Eight digit hex codes are converted into six digit hex codes by removing the last two digits, which in turn are converted into an opacity value for the colour being specified.
  • Six digit hex codes are converted into the RGB colour model by expanding the hex value pairs into equivalent integers in range 0-255 to give three integer values (one for R, one for G, one for B).

CSS rgb() and rgba() format

JCOGS Image will accept colours specified in either the rgb() or rgba() formats used within CSS system.

Mix and match…

You can use any combination of valid colour codes to specify colours, JCOGS Image validates any colour specified by attempting to convert it into an rgba() type value, which is then used internally for all operations.

SVG Support

Passthrough Support for SVG

JCOGS Image version 1.2.16 introduces a new feature called SVG Passthrough Support.

The aim of this new feature is to enable SVG images to be functionally included within image workflows. Prior to this version JCOGS Image treated SVG images as an unrecognised format, and either loaded a fallback image or rejected the tag. From verison 1.2.16 onward SVG images are included within the list of permitted media types, and JCOGS Image provides for SVG images a limited (but useful) subset of JCOGS Image's manipulation options:

  • Image sizing
    The desired width / height of processed SVG images can be set using all of the options available to regular images - set dimensions based on minimum or maximum values absolute values or through use of aspect ratios.
  • SVG santitizing
    As noted above SVG images can be created that are the carriers of malicous content. JCOGS Image will automatically scan SVG images it reads for XSS type security issues and remove them: the sanitisation process used is a version of the highly regarded DOMPurify tool used in HTML environments.
  • Image caching
    All of the standard options associated with the JCOGS Image cache are available to processed SVG files - in particular this provides a mechanism for remote image files to be cached on the server along with local image files.

The aim of this level of support is to remove the first obstacle to integrating SVG images more fully into your web design workflow. It is recognised that this is a small (but useful and important) step, but hopefully the first of a series of improvements that will ultimately lead to SVG images having access to most or all of the facilities provided by JCOGS Image.

Unfortunately one facility that is not available currently for SVG images is converting them to other image formats. 

The reasons for this cautious approach are primarily due to the nature of the SVG file format itself, and are largely outside the scope of JCOGS Image itself to fix; however in so far as it is possible to resolve them, JCOGS Design is committed to finding the solutions required.

What are SVG files?

Scaleable Vector Graphics (SVG) is an XML based document format that allows the combination of a 2D vector graphics mark-up language with a simple page description language. SVG files need to be rendered by appropriate rendering systems for them to become visible as pictures. It has been in active development since 1999, but one that only recently has become a format that is widely used. 

Although in some respects SVG represents an extraordinarily powerful approach to image definition, currently most practical uses of the standard appears to be define scalable vector images in a compact and portable format.

The core elements of the format were defined in a W3C standard in 2003 as SVG 1.1 - the current active version; SVG 2 has been in discussion since 2016 but as yet remains a draft proposal.

SVG image files do not directly contain an image - rather they contains instructions from which a rendered image can be constructed. These instructions can range from turtle-graphic style instructions for drawing vector based shapes to the expansion of base64 encoded images (which can be of any image format supported by the rendering browser) to the rendering of images obtained dynamically from remote web locations. In addition, the XML can contain information about transformations to apply to the rendered image - including rotations, applications of filters, dimension changes etc. Further, an SVG file can contain embedded CSS and Javascript instructions, and SIML animation instructions, offering scope for ‘dynamic’ image capabilities. 

The very broad scope of elements that can be included in SVG files opens up a serious risk of malicious use that has lead to some calls for SVG files to be exclueded from (for example) email attachments, in particular SVG files can be vectors for XSS type malware.

Can I use them?

Widespread browser support for rendering some types of SVG images was largely in place by 2013, however SVG is a complicated standard and even by 2022 full support for all features is still not available. The key iOS platform gained the ability to render svg format images within <img> tags only in 2015. 

Support for generating SVG images in popular graphics applications such as Adobe Illustrator is good, but again none currently support the full SVG 1.1 standard.

Implications for JCOGS Image

JCOGS Image is a tool for generating manipulated images for display within web pages and the focus of interest for the add-on is on helping its users work with any image format that can be deployed within a web page. Providing support for SVG has been a priority since the outset.

Unfortunately the complicated SVG 1.1 standard presents some challenges for JCOGS Image (and other applications of a similar nature):

  • The ‘image’ generated by an SVG needs to be rendered before it can be manipulated. 
    To (for example) change the image format of an SVG to (say) webp, JCOGS Image needs to be able to generate a rendering of the image defined by the instructions in the SVG file. For users, this rendering is done by the browser, but rendered image may be affected by attributes of the local environment (for example the local dimensions of the image holder within browser), the platform it is being rendered on, and the local availability of some resources (such as True Type fonts).
     
  • Competent SVG rendering engines that can be deployed within php are not yet available
    Although work to develop SVG rendering and manipulation libraries that can be deployed within php is in progress, there has been limited success and currently native php mechanisms to manipulate SVGs are not available. In the interim php applications have addressed the the SVG rendering issue (where it is done at all) through the use use of external execution units; these external units are effectively limited function web browsers. In practical terms the approach adopted is to send the SVG definition to a remote process which effectively loads the XML in a browser, captures the rendered image generated and returns a acopy of this to the php process. Such rendering solutions are difficult to support, not particularly efficient or scalable, and incomplete (for example they do not flexibly address the environment / platform issue noted above).
     
  • For SVG images, some transformation operations may be better delivered through editing the SVG format directly
    Image resizing, cropping, and most other transformations can be delivered for SVG images  through modifications of the XML specifying the ‘image’, likewise steps like adding borders, reflections, and overlay images and text can be achieved by applying SVG primitives to the XML file.

The consequence of these challenges is that full support of the SVG image formats by JCOGS Image remains a future goal. Until then JCOGS Image offers only limited support for the SVG image format.

Future developments

Work is underway to expand the range of maniuplation options available to include cropping, rotation and flipping: as php support for SVG grows the range of options that will work with SVGs will grow further.