Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Dominant Colors for Lazy-Loading Images

Dominant Colors for Lazy-Loading Images

Manuel Wieser

May 19, 2016
Tweet

More Decks by Manuel Wieser

Other Decks in Programming

Transcript

  1. Dominant Colors for
    Lazy-Loading Images
    Stahlstadt.js N° 9
    May 19, 2016
    Manuel Wieser
    karriere.at

    View Slide

  2. Manuel Wieser
    Developer @ karriere.at

    @manuelwieser • manu.ninja

    View Slide

  3. View Slide

  4. View Slide

  5. Motivation
    Wait… Why?

    View Slide

  6. View Slide

  7. View Slide

  8. View Slide

  9. data-src="https://pinterest.com/image.jpg"

    alt="Ghost In The Shell">

    View Slide

  10. Color Quantization
    Clustering Pixels, yo!

    View Slide

  11. View Slide

  12. const gm = require('gm');


    gm('test.jpg')
    .resize(1, 1)
    .toBuffer('RGB', (error, buffer) => {

    console.log(buffer.slice(0, 3));

    });

    View Slide

  13. #b06466

    View Slide

  14. Lanczos Filter
    [ˈlaːnt͡soʃ]

    View Slide

  15. const gm = require('gm');


    gm('test.jpg')
    .colors(1)
    .toBuffer('RGB', (error, buffer) => {

    console.log(buffer.slice(0, 3));

    });

    View Slide

  16. #b46668

    View Slide

  17. View Slide

  18. View Slide

  19. let pixels = [];

    let pixel = [];


    for (let value of buffer.values()) {

    if (pixel.length >= 3) {

    pixels.push(pixel);

    pixel = [];

    }

    pixel.push(value);

    }


    km.clusterize(pixels, {k: 1}, (error, result) => {

    result.forEach(cluster => {

    return cluster.centroid.map(val => Math.round(val).toString(16)).join('');

    });

    });

    View Slide

  20. k-means
    Clustering
    Centroids, B*tch!

    View Slide

  21. #b46668

    View Slide

  22. GraphicsMagick

    resize()
    GraphicsMagick

    colors()
    k-means
    Clustering
    GraphicsMagick

    resize()
    GraphicsMagick

    colors()
    k-means
    Clustering
    GraphicsMagick

    resize()
    GraphicsMagick

    colors()
    k-means
    Clustering

    View Slide

  23. #b06466 #b46668 #b46668
    #598d37 #588939 #588939
    #8099c0 #819bc2 #819bc2

    View Slide

  24. View Slide

  25. Data URIs
    data:image/gif;base64,WHARRGARBL

    View Slide

  26. data-src="https://pinterest.com/image.jpg"

    alt="Ghost In The Shell">

    View Slide

  27. GIF89a
    Rocket Science from the ’80s

    View Slide

  28. View Slide

  29. View Slide

  30. View Slide

  31. 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

    data:image/gif;base64,R0lGODlhAQABAIAAAP///
    wAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==

    View Slide

  32. 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

    2C 00 00 00 00 01 00 01 00 00 // Image Descriptor

    02 02 44 01 00 // Image Data

    data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACwAAAAAAQABAAACAkQBAA==

    View Slide

  33. 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')

    .colors(1)

    .toBuffer('RGB', (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'));

    });

    View Slide

  34. Tiny Thumbnails
    Low Quality LQIP

    View Slide

  35. const gm = require('gm');

    gm('test.jpg')

    .resize(3, 3, '!')

    .toBuffer('GIF', (error, buffer) => {

    console.log('data:image/gif;base64,' + 

    buffer.toString('base64'));

    });

    View Slide

  36. View Slide

  37. View Slide

  38. Conclusion
    Oh, the Possibililes!

    View Slide

  39. View Slide

  40. View Slide

  41. View Slide

  42. View Slide

  43. JOIN US
    We Have Cookies … Lots of JIRA Tickets!

    View Slide

  44. Dominant Colors for
    Lazy-Loading Images
    Queslons?
    Manuel Wieser

    @manuelwieser • manu.ninja

    View Slide

  45. Responsive Placeholders
    “My Placeholders Are Square” !

    View Slide

  46. let svg = `viewBox="0 0 ${width} ${height}">`;

    let source = 'data:image/svg+xml;base64,' +
    new Buffer(svg, 'utf8').toString('base64');

    View Slide