Skip to content

Instantly share code, notes, and snippets.

@david-batranu
Last active September 21, 2017 14:44
Show Gist options
  • Select an option

  • Save david-batranu/fc9d877e2fd0e8bfdc39c93924b4b6b3 to your computer and use it in GitHub Desktop.

Select an option

Save david-batranu/fc9d877e2fd0e8bfdc39c93924b4b6b3 to your computer and use it in GitHub Desktop.
progressive-image-loader-helper
// Progressive images
window.loadProgressive = (function(){
function fetchAndUpdateTarget(target, url, doneClass) {
var img = new Image();
img.onload = function() {
if (target.tagName === 'IMG') {
target.src = url;
}
else {
target.style.backgroundImage = "url(" + url + ")";
}
}
img.src = url;
}
function run(target) {
var bigURL = target.getAttribute('data-bigURL');
return bigURL ? fetchAndUpdateTarget(target, bigURL) : null;
}
return run;
})();
// either leave this in or ...
window.addEventListener('load', function(){
var SELECTOR = '[data-role="progressive-image"]';
var targets = document.querySelectorAll(SELECTOR);
[].slice.call(targets).forEach(loadProgressive);
})
// ... include the script as the last thing in the page and do
// var SELECTOR = '[data-role="progressive-image"]';
// var targets = document.querySelectorAll(SELECTOR);
// [].slice.call(targets).forEach(loadProgressive);
// OR, call window.loadProgressive(elem) as desired.
#! /usr/bin/env python
import io
import sys
import base64
from urllib.parse import quote
from PIL import Image
REDUCE_TO = 0.05
SVG_BLUR = """
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="{width}" height="{height}"
viewBox="0 0 {width} {height}">
<filter
id="blur"
filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB">
<feGaussianBlur stdDeviation="20 20" edgeMode="duplicate" />
<feComponentTransfer>
<feFuncA type="discrete" tableValues="1 1" />
</feComponentTransfer>
</filter>
<image filter="url(#blur)"
xlink:href="{b64_url}"
x="0" y="0"
height="100%" width="100%"/>
</svg>
"""
def to_b64(thumb):
return base64.b64encode(thumb.getvalue()).decode('utf-8')
def get_thumb(image):
dim = tuple(map(lambda dim: dim * REDUCE_TO, (image.width, image.height)))
out = io.BytesIO()
image.thumbnail(dim)
image.save(out, 'PNG')
return out
def run(image):
# shring the image
thumb = get_thumb(image.copy())
# convert to data url
b64_url = 'data:image/png;base64,{}'.format(to_b64(thumb))
# create svg at original dimensions, using the shrinked image data url
svg = SVG_BLUR.format(
width=image.width,
height=image.height,
b64_url=b64_url
).strip()
return 'data:image/svg+xml;charset=utf-8,{}'.format(quote(svg))
def console(filename):
""" Pass in an image filename. The output will be an encoded svg data url.
Use the given url as such:
<html><head>
<style>
.progressive-image {
background-size: cover;
background-image: url(DATA_URL);
}
</style></head>
<body>
<div class="progressive-image"
data-bigURL="URL_TO_BIG_IMAGE"
data-role="progressive-image"></div>
<script>
window.loadProgressive = (function(){
function fetchAndUpdateTarget(target, url, doneClass) {
var img = new Image();
if (target.tagName === 'IMG') {
target.src = url;
}
else {
target.style.backgroundImage = "url(" + url + ")";
}
img.src = url;
}
function run(target) {
var bigURL = target.getAttribute('data-bigURL');
return bigURL ? fetchAndUpdateTarget(target, bigURL) : null;
}
return run;
})();
window.addEventListener('DOMContentLoaded', function(){
var SELECTOR = '[data-role="progressive-image"]';
var targets = document.querySelectorAll(SELECTOR);
[].slice.call(targets).forEach(loadProgressive);
})
</script>
</body>
</html>
"""
return run(Image.open(filename))
if __name__ == '__main__':
if len(sys.argv) > 1:
print(console(sys.argv[1]))
else:
print(console.__doc__)
@david-batranu
Copy link
Copy Markdown
Author

@david-batranu
Copy link
Copy Markdown
Author

Requires Python 3 and Pillow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment