Add a retro/vintage effect to images using the HTML5 canvas element

Overview

vintageJS

Add a retro/vintage effect to images using the HTML5 canvas element.

npm npm Greenkeeper badge

Installation

$ npm install vintagejs

How to use

vintagejs is a function that takes a source (URL, ImageElement or CanvasElement) and an effect (object with all the options) and returns a Promise that resolves to a result object.

vintagejs('./path/to/picture.jpg', { brightness: 0.2 })
  .then(res => res.genImage())
  .then(img => document.body.appendChild(img));

The result object provides the following methods to access the modified image data:

// returns the data url of the updated image. Use it to update the source of an existing image
getDataURL(mimeType?: string, quality?: number): string;
// returns the canvas with the updated image. Use it to draw your changes onto another canvas
getCanvas(): HTMLCanvasElement;
// returns a promise that resolves to an HTMLImageElement of the updated image
genImage(mimeType?: string, quality?: number): Promise<HTMLImageElement>;

If not provided, mimeType defaults to image/jpeg and quality defaults to 1.

More Examples

// use an image as source and update image with data url
const srcEl = document.querySelector('img.myImage');
vintagejs(srcEl, { brightness: 0.2 })
  .then(res => {
    srcEl.src = res.getDataURL();
  });

// use a canvas as source and draw result to canvas
const srcEl = document.querySelector('canvas.myCanvas');
const ctx = srcEl.getContext('2d');
vintagejs(srcEl, { brightness: 0.2 })
  .then(res => {
    ctx.drawImage(res.getCanvas(), 0, 0, srcEl.width, srcEl.height);
  });

Effect options

type TEffect = {
  curves: false | TCurve,     // default: false
  screen: false | TRGBAColor, // default: false
  saturation: number,         // float between 0 and 1, default: 1
  vignette: number,           // float between 0 and 1, default: 0
  lighten: number,            // float between 0 and 1, default: 0
  viewfinder: false | string, // string must be URL, default: false
  sepia: boolean,             // default: false
  gray: boolean,              // default: false
  brightness: number,         // float between -1 and 1, default: 0
  contrast: number,           // float between -1 and 1, default: 0
};

// every channel, r=red, g=green, b=blue serves as a look up table for color mappings
type TCurve = {
  r: Array<Uint8> | Uint8ClampedArray, // array of int between 0 and 255, length of array === 256
  g: Array<Uint8> | Uint8ClampedArray, // array of int between 0 and 255, length of array === 256
  b: Array<Uint8> | Uint8ClampedArray, // array of int between 0 and 255, length of array === 256
};

type TRGBAColor = {
  r: Uint8,  // int between 0 and 255
  g: Uint8,  // int between 0 and 255
  b: Uint8,  // int between 0 and 255
  a: number, // float between 0 and 1
};

Examples

const noEffect = {};

const effect_1 = {
  brightness: -0.2,
  contrast: 0.15,
};

const effect_2 = {
  brightness: 0.1,
  vignette: 0.3,
  viewfinder: './film-1.jpg',
  screen: {
    r: 227,
    g: 12,
    b: 169,
    a: 0.15,
  },
};

See examples folder for more examples.

Browser support

Check support for the canvas element canisue.com/canvas.

Higher performance when canvas blend modes are supported caniuse.com/#feat=canvas-blending, but fallbacks are implemented.

License

MIT

Changelog

2.2.0

  • Added true grayscale effect (Thanks @bjornbos for PR #38)

2.1.0

  • Add support for strings (URI or base64 encoded data-uri) as a source

2.0.0

  • Rewrite from ground up
  • Functional API

1.1.5

  • Added "main" field to package.json

1.1.4

  • Added universal module definition (umd) wrapper

1.1.3

  • Added minified versions
  • Fixed same-origin error

1.1.2

  • added AngularJS support thanks to @dpiccone
  • grunt based build script for all versions

1.1.1

  • performance improvements
  • new effect options:
    • brightness
    • contrast

1.1.0

  • Improved core performance

1.0.0

  • Initial release
Comments
  • Vanilla Vintage

    Vanilla Vintage

    What are your thoughts on removing jQuery dependency? Are there any lurking hurdles that would need to be taken into account, or is jQuery used for things like selectors and events?

    (function() {
        myImage.addEventListener('click', (function () {
            vintage(this, {
                vignette: {
                    black: 0.8,
                    white: 0.2
                },
                noise: 20,
                screen: {
                    red: 12,
                    green: 75,
                    blue: 153,
                    strength: 0.3
                },
                desaturate: 0.05
            });
        });
    })();
    
    opened by jakiestfu 8
  • Basic AngularJS support

    Basic AngularJS support

    Hi,

    I am planning to use this wonderful library in an Angular App, so i took the time to define some Angular directives for the plugin.

    Also i discovered a little issue about cross-domain loading of images, still no support on chrome, but it's a known bug, on firefox work flawlessy.

    Hope this can be useful. Thanks, Daniele

    opened by danielepiccone 7
  • Phonegap

    Phonegap

    Hi, I love your project! I`m currently using vinatgejs in a phone gap app. but i takes very long (iphone 4 - 10 secs; iphone 6 - 2 secs) Do you know how i could accelerate it?

    Thanks

    opened by mczernin 4
  • Question: Its possible to apply the filters to an image from the web?

    Question: Its possible to apply the filters to an image from the web?

    I import images url's from panoramio api then i want to apply vintageJS

    and get this error:

    Unable to get image data from canvas because the canvas has been tainted by cross-origin data.

    opened by gamanox 3
  • a question, not really an issue

    a question, not really an issue

    Thank you for this amazing plugin!

    I wanted to ask if there is a parameter I can add in the configuration object to prevent stacking of effects? Also, is there a configuration to remove all applied effects.

    Thanks in advance

    opened by devmilind 3
  • Getting

    Getting "cross-origin data" error when using vintage

    Unable to get image data from canvas because the canvas has been tainted by cross-origin data. Uncaught Error: SECURITY_ERR: DOM Exception 18

    I saw this issue posted on stackoverflow pertaining to localhost, but I am also getting on my staging server running nginx and unicorn.

    anyone know how to resolve?

    i am simply including jquery, the vintagejs library and then calling

    $("img").vintage()

    after all images loaded.

    opened by spherop 3
  • i can׳t change image after i uploaded one

    i can׳t change image after i uploaded one

    Hi, i am trying to change image twice, but when i click on some effect i get the previous image(before i made the changed). i am using through jquery.

    second thing, i have few images that needs to get the effect, but it work only for one image, even if i define it for another variable.

    opened by roysG 2
  • Reset and Apply

    Reset and Apply

    Hi, First of all, thank you for this project. I'm having some problem using "reset()" function (and apply changes). I'm not using jquery, can you provide an example for that ? Thank you :)

    opened by wadjo 2
  • Not so much an issue, more a request

    Not so much an issue, more a request

    opened by firstbasedesign 2
  • Effects from demo page

    Effects from demo page

    Is any source code of demo effects (from http://rendro.github.io/vintageJS/) available for others to use? Or some other resources I could use to generate few filters (other than the one from example.js?

    opened by primoz-k 1
  • Added Grayscale effect

    Added Grayscale effect

    A true grayscale effect is more than just setting the saturation to 0. For more information: https://www.johndcook.com/blog/2009/08/24/algorithms-convert-color-grayscale/

    This PR implements the luminosity method for a better grayscale effect.

    opened by bjornbos 1
  • How does the ViewFinder work ?

    How does the ViewFinder work ?

    Would like to extend the viewFinder feature ... can you explain how it works and what images I have to take ? Do they require any special effect ?

    Thanks a lot!

    opened by nhaberl 1
Releases(2.2.0)
Owner
Robert Fleischmann
Software Engineer @instagram
Robert Fleischmann
A subtle tilt effect for images. The idea is to move and rotate semi-transparent copies with the same background image in order to create a subtle motion or depth effect.

Image Tilt Effect A subtle tilt effect for images. The idea is to move and rotate semi-transparent copies with the same background image in order to c

Codrops 571 Nov 21, 2022
magneticHover lets you trigger hover effect on the element when the cursor is near it, but not over it yet

magneticHover magneticHover lets you trigger hover effect on the element when the cursor is near it, but not over it yet. Examples https://codesandbox

Halo Lab 35 Nov 30, 2022
⌨️ A tiny library for creating a typing effect on specified text element.

⌨️ TinyTyper - a tiny library for creating a typing effect on specified text element. Demo Size (It's really tiny) Minimized: 2.9KB Gziped: 1.1KB Inst

Korney Vasilchenko 175 Sep 29, 2021
Liquideffect - Javascript Library for creating liquid effect on image and RGB effect on mouse direction.

LiquidEffect Javascript Library for creating liquid effect on image and RGB effect on mouse direction. Demo https://liquideffect.netlify.app/ Dependen

Rohail 8 May 6, 2022
A motion hover effect for a background grid of images.

Image Grid Motion Effect A motion hover effect for a background grid of images. Article on Codrops Demo Installation Install dependencies: npm install

Codrops 118 Dec 31, 2022
Javascript library enabling magnifying glass effect on an images

Magnifier.js Javascript library enabling magnifying glass effect on an images. Demo and documentation Features: Zoom in / out functionality using mous

Mark Rolich 808 Dec 18, 2022
Animated haze distortion effect for images and text, with WebGL.

Animated Heat Distortion Effects with WebGL A tutorial on how to use fragment shaders in WebGL to create an animated heat haze distortion effect on im

Lucas Bebber 289 Nov 1, 2022
A tutorial on how to create a thumbnail grid with an expanding image preview similar to the effect seen on Google Images.

Thumbnail Grid with Expanding Preview A tutorial on how to create a thumbnail grid with an expanding image preview similar to the effect seen on Googl

Codrops 353 Jan 4, 2023
A jQuery plugin that displays a thumbnail grid expanding preview similar to the effect seen on Google Images.

jQuery GRIDDER 1.4.2 ======= A jQuery plugin that displays a thumbnail grid expanding preview similar to the effect seen on Google Images. We have all

Orion Gunning 455 Nov 6, 2022
Add a water ripple effect to your background using WebGL.

jQuery Ripples Plugin By the powers of WebGL, add a layer of water to your HTML elements which will ripple by cursor interaction! Important: this plug

Pim Schreurs 976 Dec 30, 2022
:tada: Add a cute click effect to your mouse in your vuepress!

vuepress-plugin-cursor-effects ?? Add a cute click effect to your mouse in your vuepress! Document: moefy-vuepress LiveDemo: notev Install yarn add vu

null 19 Sep 25, 2022
❄️ Add a live frosted glass blur effect over any type of web content, including text.

Frosted Glass ❄️ Add a live frosted glass blur effect over any type of web content, including text. ️️ Demos Install npm install frosted-glass --save

Adrian Carriger 63 Nov 10, 2022
Switch the background-image with using effect.

jQuery.BgSwitcher Switch the background image with using effect. Demo http://rewish.github.io/jquery-bgswitcher/ Usage <div class="box"> <p>Lorem ip

rewish 195 Dec 30, 2022
Recreation of the background scale hover effect seen on the DDD Hotel website using CSS clip paths.

Background Scale Hover Effect Recreation of the background scale hover effect seen on the DDD Hotel menu using CSS clip paths. Article on Codrops Demo

Codrops 98 Dec 6, 2022
The slides in this slideshow wobble as they move. The effect is based on Sergey Valiukh's Dribbble shot and was made using Snap.svg and morphing SVG paths.

Wobbly Slideshow Effect The slides in this slideshow wobble as they move. The effect is based on Sergey Valiukh's Dribbble shot and was made using Sna

Codrops 112 Jul 27, 2022
100% web real-time audio experiment using smartphones as effect controller. (tech: Android Chrome + WebRTC + Web Audio API)

beez 100% web real-time audio experiment using smartphones as effect controller. (tech: Android Chrome + WebRTC + Web Audio API) The concept An Hive i

Gaëtan Renaudeau 34 Dec 16, 2022
A vanishing effect for particles and magic lovers using Threejs, GSAP and custom shaders.

Three.js Experiment - Vanishing Suzanne Demo version Get started First, you need nodejs on your computer to build the assets. Install dependencies: np

Arno Di Nunzio 120 Dec 23, 2022
Lightweight, High Performance Particles in Canvas

Sparticles https://sparticlesjs.dev Lightweight, High Performance Particles in Canvas. For those occasions when you ?? just ?? gotta ?? have ?? sparkl

Simon Goellner 171 Dec 29, 2022