blurry

A node module to generate reliable image load effects.

Generate Base64 inline Images. Prepared for lazyloading. Based on configurable SVG Templates. Compatible with Internet Explorer 11 and up.

A Solution with a very small footprint to get your DOM interactive blurry and fast.

# install
npm install --save-dev js.node.blurry
// usage
const Blurry = require('blurry');
const blurry = new Blurry({'file': path.join(__dirname, 'static/img/teapott-preview.jpg'), 'width': 1140, 'height': 640});
<img alt="" src="' + blurry.getUrl() + '">

Base64 inline Image

base64 blured svg/jpeg preview image
Original Preview Image 114x64px resized to 1140x640px within the SVG. The SVG feGaussianBlur filter produce a blurry effect.
In this solution the SVG below is encoded into base64 and directly writen to img src with blurry.getUrl().
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1140px" height="640px" viewBox="1 1 {{width}} {{height}}">
  <image filter="url(#blurWitchProject)" width="100%" height="100%" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAABkAAD/4QNpaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjYtYzEzOCA3OS4xNTk4MjQsIDIwMTYvMDkvMTQtMDE6MDk6MDEgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9Ijg0OEFGODE1NUM1MUQzRTk1OEIxMDA3MkE0QzdGOUZCIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkZBNTMwOTc3NUNDQjExRTg4OEVBRkY2MDI5MjQ4MzFFIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkZBNTMwOTc2NUNDQjExRTg4OEVBRkY2MDI5MjQ4MzFFIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE3IChNYWNpbnRvc2gpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NTViY2Q1YWMtYjU0Mi00OGFhLTkzNjktNzJhMmQ2NzY2N2JhIiBzdFJlZjpkb2N1bWVudElEPSI4NDhBRjgxNTVDNTFEM0U5NThCMTAwNzJBNEM3RjlGQiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pv/tAEhQaG90b3Nob3AgMy4wADhCSU0EBAAAAAAADxwBWgADGyVHHAIAAAIAAgA4QklNBCUAAAAAABD84R+JyLfJeC80YjQHWHfr/9sAhAAIBgYHBgUIBwcHCQkICgwUDQwLCwwZEhMPFB0aHx4dGhwcICQuJyAiLCMcHCg3KSwwMTQ0NB8nOT04MjwuMzQyAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wgARCABAAHIDASIAAhEBAxEB/8QAHAAAAQQDAQAAAAAAAAAAAAAAAAECBAUDBwgG/9oACAEBAAAAANjy5syXE5Ve4FHm67CZOsJHL1e5oJkdtuxl2FjL5qqnCCvz7DtZs6yh88K8Bz8nr7CbY59V0GRRUH5aTd/i6WJHeOERVfB6b5nZIcCAqiewk69yPURQUE//xAAZAQEAAwEBAAAAAAAAAAAAAAAAAQIFBAP/2gAIAQIQAAAArF9iRira8k4nr19IZejaRH//xAAZAQACAwEAAAAAAAAAAAAAAAAAAQIEBQP/2gAIAQMQAAAAiSyogthGXES2udSugWrR5AI//8QANRAAAQMCAwQIAwkBAAAAAAAAAQACAwQRBQYhEjFBURATICJSYXHBB4GRMDJCYoKSobLh8P/aAAgBAQABPwCOQFoB0PAqKS55OCik/wBCikIsL+hTHXWN0DMTwasoni7Z4Xx/ULq3McWPFnNNj6hBq2VsBAAK6uhzsrlQTHYFztM4HkopbAbR04OUUx2gCbO4HmopQfTiOSgk5ou7hWYqcUmZsTg4MqpLfW6G5X7F01WCp5rHunZPFp3FRTX0aPVpUUgtxLf5aoZdRrrwdzUEvy9k+UNiKzXO2pzZikrNxqXAIHsALcUHEbkHGw7pVLUAgC+0PCd4UM4IGu0B+4KKbc6/6h7qKe2mmvDgVTz7iSszZgjwTAqmrcRttbaNvN53BOe6SRz3m7ibk8yh02CsgAmDowqvpcRp2tDgyUCwN06pkpJAydp/K++/0KgxC+u18xvUNcy28eylxqno4HzTTNYxgu5zjoB7rNOZ5sw1oDdplHDpEw/2K3odF1cI+SvxTXai17Kw8Sw/GoKSRsjZJWOHksjMjzpg73PieYGnZL5GbIcfJZ0qn5SzHNhFPIakxta8u8IcLgFR5rrnD7lj6qsxCrxFwNTKXNGrWDRoQarIBX7IK23/APFZayo7MGMRUMDXuFwZX+FqBoMhZKmqnMDYaSHRg/G7c1vzKr62pxXEamvrH9ZUVEhlkd5lMbZAaK32Hp0fD3E6nL0bZGQQ9U83cZG9+RfFLOozHLSYXQh7aSnHWVHnMmxnkg23RxK4Idknosv/xAAdEQABBAMBAQAAAAAAAAAAAAACAAEgIQMRMRAS/9oACAECAQE/APBTc3MbpDTakOIi4sOH4t5ADGVMmaf/xAAdEQACAQUBAQAAAAAAAAAAAAABAgADERIgIRAx/9oACAEDAQE/APLRuHcm0bp1IjOF+yrWy4NnbEdMZt//2Q=="
  />
  <filter id="blurWitchProject" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
    <feGaussianBlur stdDeviation="20" edgeMode="duplicate" />
    <feComponentTransfer>
      <feFuncA type="discrete" tableValues="1 1" />
    </feComponentTransfer>
  </filter>
</svg>

Picture Element with blurry and lazyload

webp/jpeg picture element with four breakpoints and base64 blured svg/jpeg preview image
Blured Preview Image 114x64px in lazyload picture container is displayed until source srcset image has been loaded by the browser.
<picture>
  <source data-srcset="static/img/teapott-ld.webp 1x, static/img/teapott-ld_x2.webp 2x" media="(min-width: 1200px)" type="image/webp">
  <source data-srcset="static/img/teapott-md.webp 1x, static/img/teapott-md_x2.webp 2x" media="(min-width: 992px) and (max-width: 1199px)" type="image/webp">
  <source data-srcset="static/img/teapott-t.webp 1x, static/img/teapott-t_x2.webp 2x" media="(min-width: 768px) and (max-width: 991px)" type="image/webp">
  <source data-srcset="static/img/teapott-m.webp 1x, static/img/teapott-m_x2.webp 2x" media="(max-width: 767px)" type="image/webp">
  <source data-srcset="static/img/teapott-ld.jpg 1x, static/img/teapott-ld_x2.jpg 2x" media="(min-width: 1200px)" type="image/jpeg">
  <source data-srcset="static/img/teapott-md.jpg 1x, static/img/teapott-md_x2.jpg 2x" media="(min-width: 992px) and (max-width: 1199px)" type="image/jpeg">
  <source data-srcset="static/img/teapott-t.jpg 1x, static/img/teapott-t_x2.jpg 2x" media="(min-width: 768px) and (max-width: 991px)" type="image/jpeg">
  <source data-srcset="static/img/teapott-m.jpg 1x, static/img/teapott-m_x2.jpg 2x" media="(max-width: 767px)" type="image/jpeg">
  <img class="lazyload" alt="webp/jpeg picture element with four breakpoints and base64 blured svg/jpeg preview image" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSAiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgd2lkdGg9IjExNDBweCIgaGVpZ2h0PSI2NDBweCIgdmlld0JveD0iMSAxIDExNDAgNjQwIj48aW1hZ2UgZmlsdGVyPSJ1cmwoI2JsdXJXaXRjaFByb2plY3QpIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB4bGluazpocmVmPSJkYXRhOmltYWdlL2pwZWc7YmFzZTY0LC85ai80QUFRU2taSlJnQUJBUUFBQVFBQkFBRC80UUFZUlhocFpnQUFTVWtxQUFnQUFBQUFBQUFBQUFBQUFQL3NBQkZFZFdOcmVRQUJBQVFBQUFCa0FBRC80UU5wYUhSMGNEb3ZMMjV6TG1Ga2IySmxMbU52YlM5NFlYQXZNUzR3THdBOFAzaHdZV05yWlhRZ1ltVm5hVzQ5SXUrN3Z5SWdhV1E5SWxjMVRUQk5jRU5sYUdsSWVuSmxVM3BPVkdONmEyTTVaQ0kvUGlBOGVEcDRiWEJ0WlhSaElIaHRiRzV6T25nOUltRmtiMkpsT201ek9tMWxkR0V2SWlCNE9uaHRjSFJyUFNKQlpHOWlaU0JZVFZBZ1EyOXlaU0ExTGpZdFl6RXpPQ0EzT1M0eE5UazRNalFzSURJd01UWXZNRGt2TVRRdE1ERTZNRGs2TURFZ0lDQWdJQ0FnSUNJK0lEeHlaR1k2VWtSR0lIaHRiRzV6T25Ka1pqMGlhSFIwY0RvdkwzZDNkeTUzTXk1dmNtY3ZNVGs1T1M4d01pOHlNaTF5WkdZdGMzbHVkR0Y0TFc1ekl5SStJRHh5WkdZNlJHVnpZM0pwY0hScGIyNGdjbVJtT21GaWIzVjBQU0lpSUhodGJHNXpPbmh0Y0UxTlBTSm9kSFJ3T2k4dmJuTXVZV1J2WW1VdVkyOXRMM2hoY0M4eExqQXZiVzB2SWlCNGJXeHVjenB6ZEZKbFpqMGlhSFIwY0RvdkwyNXpMbUZrYjJKbExtTnZiUzk0WVhBdk1TNHdMM05VZVhCbEwxSmxjMjkxY21ObFVtVm1JeUlnZUcxc2JuTTZlRzF3UFNKb2RIUndPaTh2Ym5NdVlXUnZZbVV1WTI5dEwzaGhjQzh4TGpBdklpQjRiWEJOVFRwUGNtbG5hVzVoYkVSdlkzVnRaVzUwU1VROUlqZzBPRUZHT0RFMU5VTTFNVVF6UlRrMU9FSXhNREEzTWtFMFF6ZEdPVVpDSWlCNGJYQk5UVHBFYjJOMWJXVnVkRWxFUFNKNGJYQXVaR2xrT2taQk5UTXdPVGMzTlVORFFqRXhSVGc0T0VWQlJrWTJNREk1TWpRNE16RkZJaUI0YlhCTlRUcEpibk4wWVc1alpVbEVQU0o0YlhBdWFXbGtPa1pCTlRNd09UYzJOVU5EUWpFeFJUZzRPRVZCUmtZMk1ESTVNalE0TXpGRklpQjRiWEE2UTNKbFlYUnZjbFJ2YjJ3OUlrRmtiMkpsSUZCb2IzUnZjMmh2Y0NCRFF5QXlNREUzSUNoTllXTnBiblJ2YzJncElqNGdQSGh0Y0UxTk9rUmxjbWwyWldSR2NtOXRJSE4wVW1WbU9tbHVjM1JoYm1ObFNVUTlJbmh0Y0M1cGFXUTZOVFZpWTJRMVlXTXRZalUwTWkwME9HRmhMVGt6TmprdE56SmhNbVEyTnpZMk4ySmhJaUJ6ZEZKbFpqcGtiMk4xYldWdWRFbEVQU0k0TkRoQlJqZ3hOVFZETlRGRU0wVTVOVGhDTVRBd056SkJORU0zUmpsR1FpSXZQaUE4TDNKa1pqcEVaWE5qY21sd2RHbHZiajRnUEM5eVpHWTZVa1JHUGlBOEwzZzZlRzF3YldWMFlUNGdQRDk0Y0dGamEyVjBJR1Z1WkQwaWNpSS9Qdi90QUVoUWFHOTBiM05vYjNBZ015NHdBRGhDU1UwRUJBQUFBQUFBRHh3QldnQURHeVZISEFJQUFBSUFBZ0E0UWtsTkJDVUFBQUFBQUJEODRSK0p5TGZKZUM4MFlqUUhXSGZyLzlzQWhBQUlCZ1lIQmdVSUJ3Y0hDUWtJQ2d3VURRd0xDd3daRWhNUEZCMGFIeDRkR2h3Y0lDUXVKeUFpTENNY0hDZzNLU3d3TVRRME5COG5PVDA0TWp3dU16UXlBUWtKQ1F3TERCZ05EUmd5SVJ3aE1qSXlNakl5TWpJeU1qSXlNakl5TWpJeU1qSXlNakl5TWpJeU1qSXlNakl5TWpJeU1qSXlNakl5TWpJeU1qSXlNakwvd2dBUkNBQkFBSElEQVNJQUFoRUJBeEVCLzhRQUhBQUFBUVFEQVFBQUFBQUFBQUFBQUFBQUFBRUNCQVVEQndnRy85b0FDQUVCQUFBQUFOank1c3lYRTVWZTRGSG02N0NaT3NKSEwxZTVvSmtkdHV4bDJGakw1cXFuQ0N2ejdEdFpzNnloODhLOEJ6OG5yN0NiWTU5VjBHUlJVSDVhVGQvaTZXSkhlT0VSVmZCNmI1blpJY0NBcWlld2s2OXlQVVJRVUUvL3hBQVpBUUVBQXdFQkFBQUFBQUFBQUFBQUFBQUFBUUlGQkFQLzJnQUlBUUlRQUFBQXJGOWlSaXJhOGs0bnIxOUlaZWphUkgvL3hBQVpBUUFDQXdFQUFBQUFBQUFBQUFBQUFBQUFBUUlFQlFQLzJnQUlBUU1RQUFBQWlTeW9ndGhHWEVTMnVkU3VnV3JSNUFJLy84UUFOUkFBQVFNQ0F3UUlBd2tCQUFBQUFBQUFBUUFDQXdRUkJRWWhFakZCVVJBVElDSlNZWEhCQjRHUk1ESkNZb0tTb2JMaDhQL2FBQWdCQVFBQlB3Q09RRm9CMFBBcUtTNTVPQ2lrL3dCQ2lrSXNMK2hUSFhXTjBETVR3YXNvbmk3WjRYeC9VTHEzTWNXUEZuTk5qNmhCcTJWc0JBQUs2dWh6c3JsUVRIWUZ6dE00SGtvcGJBYlIwNE9VVXgyZ0NiTzRIbW9wUWZUaU9TZ2s1b3U3aFdZcWNVbVpzVGc0TXFwTGZXNkc1WDdGMDFXQ3A1ckh1blpQRnAzRlJUWDBhUFZwVVVndHhMZjVhb1pkUnJyd2R6VUV2eTlrK1VOaUt6WE8ycHpaaWtyTnhxWEFJSHNBTGNVSEVia0hHdzdwVkxVQWdDKzBQQ2Q0VU00SUd1MEIrNEtLYmM2LzZoN3FLZTJtbXZEZ1ZUejdpU3N6Wmdqd1RBcW1yY1J0dGJhTnZONTNCT2U2U1J6M203aWJrOHloMDJDc2dBbURvd3F2cGNScDJ0RGd5VUN3TjA2cGtwSkF5ZHAvSysrLzBLZ3hDK3UxOHh2VU5jeTI4ZXlseHFubzRIelRUTll4Z3U1empvQjdyTk9aNXN3MW9EZHBsSERwRXcvMkszb2RGMWNJK1N2eFRYYWkxN0t3OFN3L0dvS1NSc2paSldPSGtzak1qenBnNzNQaWVZR25aTDVHYkljZkpaMHFuNVN6SE5oRlBJYWt4dGE4dThJY0xnRlI1cnJuRDdsajZxc3hDcnhGd05US1hOR3JXRFJvUWFySUJYN0lLMjMvQVBGWmF5bzdNR01SVU1EWHVGd1pYK0ZxQm9NaFpLbXFuTURZYVNIUmcvRzdjMXZ6S3I2MnB4WEVhbXZySDlaVVZFaGxrZDVsTWJaQWFLMzJIcDBmRDNFNm5MMGJaR1FROVU4M2NaRzkrUmZGTE9vekhMU1lYUWg3YVNuSFdWSG5NbXhua2cyM1J4SzRJZGtub3N2L3hBQWRFUUFCQkFNQkFRQUFBQUFBQUFBQUFBQUNBQUVnSVFNUk1SQVMvOW9BQ0FFQ0FRRS9BUEJUYzNNYnBEVGFrT0lpNHNPSDR0NUFER1ZNbWFmL3hBQWRFUUFDQVFVQkFRQUFBQUFBQUFBQUFBQUJBZ0FERVJJZ0lSQXgvOW9BQ0FFREFRRS9BUExSdUhjbTBicDFJak9GK3lyV3k0Tm5iRWRNWnQvLzJRPT0iLz48IS0tIFRoZSBjYWtlIGlzIGEgbGllIC0tPjxmaWx0ZXIgaWQ9ImJsdXJXaXRjaFByb2plY3QiIGZpbHRlclVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIj48ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSIyMCIgZWRnZU1vZGU9ImR1cGxpY2F0ZSIgLz48ZmVDb21wb25lbnRUcmFuc2Zlcj48ZmVGdW5jQSB0eXBlPSJkaXNjcmV0ZSIgdGFibGVWYWx1ZXM9IjEgMSIgLz48L2ZlQ29tcG9uZW50VHJhbnNmZXI+PC9maWx0ZXI+PC9zdmc+">
</picture>

Picture Element with blurry and lazyload VS. without lazyload

Picture Element with blurry and lazyloadPicture Element with blurry and without lazyload

Usage

// Render Blurry as base64 image src
const Blurry = require('blurry')
const blurry = new Blurry({'file': path.join(__dirname, 'static/img/teapott-preview.jpg'), 'width': 1140, 'height': 640});
<img alt="" src="' + blurry.getUrl() + '">
// Construct Blurry with custom template
const blurry = new Blurry({'file': path.join(__dirname, 'static/img/teapott-preview.jpg'), 'width': 1140, 'height': 640, 'template': 'blurry.tmpl'});
<!-- Blurry default template -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="{{width}}px" height="{{height}}px" viewBox="1 1 {{width}} {{height}}">
  <image filter="url(#blurWitchProject)" width="100%" height="100%" xlink:href="{{base64FileUrl}}" />
  <filter id="blurWitchProject" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
    <feGaussianBlur stdDeviation="20" edgeMode="duplicate" />
    <feComponentTransfer>
      <feFuncA type="discrete" tableValues="1 1" />
    </feComponentTransfer>
  </filter>
</svg>
Lazysizes is needed to enable lazyloading. Lazysizes switch also the blurry base64 SVG image to a image defined in srcset within this solution.
IE 11 needs picturefill to enable picture element support.