progressive_enchancement.js
const gm = require('gm');
gm('test.jpg')
.resize(250, 250)
.colors(1)
.toBuffer('RGB', function (error, buffer) {
console.log(buffer.slice(0, 3));
});
node.js: gm npm package
PHP: gmagic/imagick
<?php
$image = new Imagick('test.jpg'));
$image->resizeImage(250, 250, Imagick::FILTER_GAUSSIAN, 1);
$image->quantizeImage(1, Imagick::COLORSPACE_RGB, 0, false, false);
$image->setFormat('RGB');
echo substr(bin2hex($image), 0, 6);
Base64-encoded data URI
47 49 46 38 39 61 // Header
01 00 01 00 80 00 00 // Logical Screen Descriptor
FF FF FF 00 00 00 // Global Color Table
21 F9 04 00 00 00 00 00 // Graphics Control Extension
2C 00 00 00 00 01 00 01 00 00 // Image Descriptor
02 02 44 01 00 // Image Data
3B // Trailer
47 49 46 38 39 61 // Header
01 00 01 00 80 01 00 // Logical Screen Descriptor
FF FF FF 00 00 00 // Global Color Table
2C 00 00 00 00 01 00 01 00 00 // Image Descriptor
02 02 44 01 00 // Image Data
Выпиливаем лишнее
GIF 1x1 из Photoshop
data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACAA==
var gm = require('gm');
var header = new Buffer('474946383961', 'hex');
var logicalScreenDescriptor = new Buffer('01000100800100', 'hex');
var imageDescriptor = new Buffer('2c000000000100010000', 'hex');
var imageData = new Buffer('0202440100', 'hex');
gm('test.jpg')
.resize(250, 250)
.colors(1)
.toBuffer('RGB', function (error, buffer) {
var gif = [
header,
logicalScreenDescriptor,
buffer.slice(0, 3),
new Buffer([0, 0, 0]),
imageDescriptor,
imageData
];
console.log('data:image/gif;base64,' + Buffer.concat(gif).toString('base64'));
});
Мини-превьюшки
var gm = require('gm');
gm('test.jpg')
.resize(3, 3)
.toBuffer('GIF', function (error, buffer) {
console.log('data:image/gif;base64,' + buffer.toString('base64'));
});
GIF 3x3
$image_width = intval( preg_match( '/width="(\d+)"/', $image, $match_width ) ? $match_width[1] : 1 );
$image_height = intval( preg_match( '/height="(\d+)"/', $image, $match_height ) ? $match_height[1] : 1 );
$image_aspect_ratio = round( ( $image_height / $image_width ) * 100, 3 );
return sprintf('<div class="wrapper" style="padding-top: %s%%;">%s</div>', $image_aspect_ratio, $image );
Враппер с бэка с background image: наша GIF
Filter: blur(...)
https://manu.ninja/dominant-colors-for-lazy-loading-images/
https://jmperezperez.com/medium-image-progressive-loading-placeholder/
http://www.tylerdeitz.com/lazy-progressive-enhancement/
Материалы: