{"_id":"lwip","_rev":"402350","name":"lwip","description":"Comprehensive, fast, and simple image processing and manipulation","dist-tags":{"latest":"0.0.9"},"maintainers":[{"name":"eyalar","email":"eyalarubas@gmail.com"}],"time":{"modified":"2021-08-04T04:35:14.000Z","created":"2014-07-09T05:16:02.542Z","0.0.9":"2016-05-19T13:41:32.845Z","0.0.8":"2015-10-04T12:49:16.062Z","0.0.7":"2015-06-04T09:39:34.893Z","0.0.6":"2014-12-24T04:38:23.632Z","0.0.5":"2014-10-02T09:28:07.422Z","0.0.4":"2014-09-17T05:59:25.294Z","0.0.3":"2014-09-15T03:57:40.484Z","0.0.2":"2014-09-04T11:27:10.774Z","0.0.1":"2014-07-09T05:16:02.542Z"},"users":{"kael":true,"grahamb":true,"zetay":true,"rethinkflash":true,"sstur":true,"malenki":true,"skarface":true,"weexastudio":true,"aesthetics.data":true,"azaitw":true,"globaltommy":true,"andrew.medvedev":true,"mamalat":true,"devwurm":true,"preco21":true,"detj":true,"foto":true,"insdevmail":true,"huxiaolei":true,"kevinlaunay":true,"roryrjb":true,"euharrison":true,"matiasmarani":true,"zlatip":true,"allain":true,"ferrari":true,"pstoev":true,"jcloutz":true,"rsaa":true,"jorycn":true,"monolithed":true,"justinshea":true,"moinism":true,"vorg":true,"roccomuso":true,"godber":true,"sbrl":true,"bobjohnson23":true,"heineiuo":true,"xiaoyiyu":true,"psbolden":true,"wujr5":true,"abt10":true,"maka":true,"vlad309523":true,"thouky":true,"karzanosman984":true},"author":{"name":"Eyal Arubas","email":"eyalarubas@gmail.com"},"repository":{"type":"git","url":"git+https://github.com/EyalAr/lwip.git"},"versions":{"0.0.9":{"name":"lwip","version":"0.0.9","main":"index.js","dependencies":{"async":"^2.0.0-rc.5","bindings":"^1.2.1","decree":"0.0.6","nan":"^2.3.2"},"scripts":{"install":"node-gyp rebuild","test":"mocha --opts tests/mocha.opts tests","coverage":"istanbul cover ./node_modules/mocha/bin/_mocha -- --opts tests/mocha.opts tests","travis":"istanbul cover --report lcovonly ./node_modules/.bin/_mocha -- --opts tests/mocha.opts --bail tests && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js"},"gypfile":true,"description":"Comprehensive, fast, and simple image processing and manipulation","directories":{"example":"examples"},"devDependencies":{"coveralls":"^2.11.9","istanbul":"^0.4.3","mkdirp":"^0.5.1","mocha":"^2.4.5","mocha-lcov-reporter":"^1.2.0","should":"^8.3.2"},"repository":{"type":"git","url":"git+https://github.com/EyalAr/lwip.git"},"keywords":["image","buffer","manipulate","process","resize","scale","rotate","jpeg","jpg","png","gif","crop","blur","sharpen","batch","flip","mirror","border","padding","hue","saturation","lightness","alpha","transparency","fade","opacity","contain","cover"],"author":{"name":"Eyal Arubas","email":"eyalarubas@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/EyalAr/lwip/issues"},"homepage":"https://github.com/EyalAr/lwip","gitHead":"a65f6086a26c22736eb4d7cfa43c096afad5b5e8","_id":"lwip@0.0.9","_shasum":"28b4169835d27ca29325e75fd1b883ae37b50fcc","_from":".","_npmVersion":"3.8.9","_nodeVersion":"6.2.0","_npmUser":{"name":"eyalar","email":"eyalarubas@gmail.com"},"maintainers":[{"name":"eyalar","email":"eyalarubas@gmail.com"}],"dist":{"shasum":"28b4169835d27ca29325e75fd1b883ae37b50fcc","size":3221457,"noattachment":false,"key":"/lwip/-/lwip-0.0.9.tgz","tarball":"http://registry.cnpm.dingdandao.com/lwip/download/lwip-0.0.9.tgz"},"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/lwip-0.0.9.tgz_1463665288984_0.34990591020323336"},"publish_time":1463665292845,"_cnpm_publish_time":1463665292845,"_hasShrinkwrap":false},"0.0.8":{"name":"lwip","version":"0.0.8","main":"index.js","dependencies":{"async":"~0.9.0","decree":"0.0.6","nan":"~2.0.9"},"scripts":{"install":"node-gyp rebuild","test":"mocha --opts tests/mocha.opts tests","coverage":"istanbul cover ./node_modules/mocha/bin/_mocha -- --opts tests/mocha.opts tests","travis":"istanbul cover --report lcovonly ./node_modules/.bin/_mocha -- --opts tests/mocha.opts --bail tests && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js"},"gypfile":true,"description":"Comprehensive, fast, and simple image processing and manipulation","directories":{"example":"examples"},"devDependencies":{"coveralls":"^2.11.2","istanbul":"^0.3.5","mkdirp":"^0.5.0","mocha":"^2.1.0","mocha-lcov-reporter":"0.0.1","should":"^7.1.0"},"repository":{"type":"git","url":"git+https://github.com/EyalAr/lwip.git"},"keywords":["image","buffer","manipulate","process","resize","scale","rotate","jpeg","jpg","png","gif","crop","blur","sharpen","batch","flip","mirror","border","padding","hue","saturation","lightness","alpha","transparency","fade","opacity","contain","cover"],"author":{"name":"Eyal Arubas","email":"eyalarubas@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/EyalAr/lwip/issues"},"homepage":"https://github.com/EyalAr/lwip","gitHead":"de12601c9ddb2f067461ccb37ac656cc4ae73918","_id":"lwip@0.0.8","_shasum":"4dd632da9487ad9350f8819f56467ce0a0882caf","_from":".","_npmVersion":"2.14.4","_nodeVersion":"4.1.1","_npmUser":{"name":"eyalar","email":"eyalarubas@gmail.com"},"maintainers":[{"name":"eyalar","email":"eyalarubas@gmail.com"}],"dist":{"shasum":"4dd632da9487ad9350f8819f56467ce0a0882caf","size":3221153,"noattachment":false,"key":"/lwip/-/lwip-0.0.8.tgz","tarball":"http://registry.cnpm.dingdandao.com/lwip/download/lwip-0.0.8.tgz"},"publish_time":1443962956062,"_cnpm_publish_time":1443962956062,"_hasShrinkwrap":false},"0.0.7":{"name":"lwip","version":"0.0.7","main":"index.js","dependencies":{"async":"~0.9.0","decree":"0.0.6","nan":"^1.8.4"},"scripts":{"install":"node-gyp rebuild","test":"mocha --opts tests/mocha.opts tests","coverage":"istanbul cover ./node_modules/mocha/bin/_mocha -- --opts tests/mocha.opts tests","travis":"istanbul cover --report lcovonly ./node_modules/.bin/_mocha -- --opts tests/mocha.opts --bail tests && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js"},"gypfile":true,"description":"Comprehensive, fast, and simple image processing and manipulation","directories":{"example":"examples"},"devDependencies":{"coveralls":"^2.11.2","istanbul":"^0.3.5","mkdirp":"^0.5.0","mocha":"^2.1.0","mocha-lcov-reporter":"0.0.1","should":"^4.4.1"},"repository":{"type":"git","url":"https://github.com/EyalAr/lwip.git"},"keywords":["image","buffer","manipulate","process","resize","scale","rotate","jpeg","jpg","png","gif","crop","blur","sharpen","batch","flip","mirror","border","padding","hue","saturation","lightness","alpha","transparency","fade","opacity","contain","cover"],"author":{"name":"Eyal Arubas","email":"eyalarubas@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/EyalAr/lwip/issues"},"homepage":"https://github.com/EyalAr/lwip","gitHead":"e220e53a88bbb21e023b1a723279bddac66c719e","_id":"lwip@0.0.7","_shasum":"5e59dd722879b1331ed924a49edbbe2488c8f903","_from":".","_npmVersion":"1.4.28","_npmUser":{"name":"eyalar","email":"eyalarubas@gmail.com"},"maintainers":[{"name":"eyalar","email":"eyalarubas@gmail.com"}],"dist":{"shasum":"5e59dd722879b1331ed924a49edbbe2488c8f903","size":3197724,"noattachment":false,"key":"/lwip/-/lwip-0.0.7.tgz","tarball":"http://registry.cnpm.dingdandao.com/lwip/download/lwip-0.0.7.tgz"},"publish_time":1433410774893,"_cnpm_publish_time":1433410774893,"_hasShrinkwrap":false},"0.0.6":{"name":"lwip","version":"0.0.6","main":"index.js","dependencies":{"async":"~0.9.0","decree":"0.0.6","nan":"~1.4.1"},"scripts":{"install":"node-gyp rebuild","test":"mocha --opts tests/mocha.opts tests","coverage":"istanbul cover ./node_modules/mocha/bin/_mocha -- --opts tests/mocha.opts tests","travis":"istanbul cover --report lcovonly ./node_modules/.bin/_mocha -- --opts tests/mocha.opts --bail tests && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js"},"gypfile":true,"description":"Comprehensive, fast, and simple image processing and manipulation","directories":{"example":"examples"},"devDependencies":{"coveralls":"^2.11.2","istanbul":"^0.3.5","mkdirp":"^0.5.0","mocha":"^2.1.0","mocha-lcov-reporter":"0.0.1","should":"^4.4.1"},"repository":{"type":"git","url":"https://github.com/EyalAr/lwip.git"},"keywords":["image","buffer","manipulate","process","resize","scale","rotate","jpeg","jpg","png","gif","crop","blur","sharpen","batch","flip","mirror","border","padding","hue","saturation","lightness","alpha","transparency","fade","opacity","contain","cover"],"author":{"name":"Eyal Arubas","email":"eyalarubas@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/EyalAr/lwip/issues"},"homepage":"https://github.com/EyalAr/lwip","_id":"lwip@0.0.6","_shasum":"99ca08156bcfefaba8b3ee8ae35d1be961a6d68b","_from":".","_npmVersion":"1.4.10","_npmUser":{"name":"eyalar","email":"eyalarubas@gmail.com"},"maintainers":[{"name":"eyalar","email":"eyalarubas@gmail.com"}],"dist":{"shasum":"99ca08156bcfefaba8b3ee8ae35d1be961a6d68b","size":3197879,"noattachment":false,"key":"/lwip/-/lwip-0.0.6.tgz","tarball":"http://registry.cnpm.dingdandao.com/lwip/download/lwip-0.0.6.tgz"},"publish_time":1419395903632,"_cnpm_publish_time":1419395903632,"_hasShrinkwrap":false},"0.0.5":{"name":"lwip","version":"0.0.5","main":"index.js","dependencies":{"async":"^0.9.0","decree":"0.0.2","nan":"^1.3.0"},"scripts":{"install":"node-gyp rebuild","test":"mocha --opts tests/mocha.opts tests","coverage":"istanbul cover ./node_modules/mocha/bin/_mocha -- --opts tests/mocha.opts tests","travis":"istanbul cover --report lcovonly ./node_modules/.bin/_mocha -- --opts tests/mocha.opts --bail tests && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js"},"gypfile":true,"description":"Comprehensive, fast, and simple image processing and manipulation","directories":{"example":"examples"},"devDependencies":{"coveralls":"^2.11.1","istanbul":"^0.3.2","mkdirp":"^0.5.0","mocha":"^1.20.1","mocha-lcov-reporter":"0.0.1","should":"^4.0.4"},"repository":{"type":"git","url":"https://github.com/EyalAr/lwip.git"},"keywords":["image","buffer","manipulate","process","resize","scale","rotate","jpeg","jpg","png","crop","blur","sharpen","batch","flip","mirror","border","padding","hue","saturation","lightness","alpha","transparency","fade","opacity"],"author":{"name":"Eyal Arubas","email":"eyalarubas@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/EyalAr/lwip/issues"},"homepage":"https://github.com/EyalAr/lwip","_id":"lwip@0.0.5","_shasum":"2bb69e7e14b63da75d4b916a2f7a982cceece139","_from":".","_npmVersion":"1.4.9","_npmUser":{"name":"eyalar","email":"eyalarubas@gmail.com"},"maintainers":[{"name":"eyalar","email":"eyalarubas@gmail.com"}],"dist":{"shasum":"2bb69e7e14b63da75d4b916a2f7a982cceece139","size":2647528,"noattachment":false,"key":"/lwip/-/lwip-0.0.5.tgz","tarball":"http://registry.cnpm.dingdandao.com/lwip/download/lwip-0.0.5.tgz"},"publish_time":1412242087422,"_cnpm_publish_time":1412242087422,"_hasShrinkwrap":false},"0.0.4":{"name":"lwip","version":"0.0.4","main":"index.js","dependencies":{"async":"^0.9.0","decree":"0.0.2","nan":"^1.3.0"},"scripts":{"install":"node-gyp rebuild","test":"mocha --reporter spec --recursive tests/"},"gypfile":true,"description":"Comprehensive, fast, and simple image processing and manipulation","directories":{"example":"examples"},"devDependencies":{"mkdirp":"^0.5.0","mocha":"^1.20.1","should":"^4.0.4"},"repository":{"type":"git","url":"https://github.com/EyalAr/lwip.git"},"keywords":["image","buffer","manipulate","process","resize","scale","rotate","jpeg","jpg","png","crop","blur","sharpen","batch","flip","mirror","border","padding","hue","saturation","lightness"],"author":{"name":"Eyal Arubas","email":"eyalarubas@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/EyalAr/lwip/issues"},"homepage":"https://github.com/EyalAr/lwip","_id":"lwip@0.0.4","_shasum":"534ed3ba294428f00655eb3ec4d2c7be60701908","_from":".","_npmVersion":"1.4.9","_npmUser":{"name":"eyalar","email":"eyalarubas@gmail.com"},"maintainers":[{"name":"eyalar","email":"eyalarubas@gmail.com"}],"dist":{"shasum":"534ed3ba294428f00655eb3ec4d2c7be60701908","size":2395788,"noattachment":false,"key":"/lwip/-/lwip-0.0.4.tgz","tarball":"http://registry.cnpm.dingdandao.com/lwip/download/lwip-0.0.4.tgz"},"publish_time":1410933565294,"_cnpm_publish_time":1410933565294,"_hasShrinkwrap":false},"0.0.3":{"name":"lwip","version":"0.0.3","main":"index.js","dependencies":{"async":"^0.9.0","decree":"0.0.2","nan":"^1.3.0"},"scripts":{"install":"node-gyp rebuild","test":"mocha --reporter spec --recursive tests/"},"gypfile":true,"description":"Comprehensive, fast, and simple image processing and manipulation","directories":{"example":"examples"},"devDependencies":{"mkdirp":"^0.5.0","mocha":"^1.20.1","should":"^4.0.4"},"repository":{"type":"git","url":"https://github.com/EyalAr/lwip.git"},"keywords":["image","buffer","manipulate","process","resize","scale","rotate","jpeg","jpg","png","crop","blur","sharpen","batch","flip","mirror","border","padding","hue","saturation","lightness"],"author":{"name":"Eyal Arubas","email":"eyalarubas@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/EyalAr/lwip/issues"},"homepage":"https://github.com/EyalAr/lwip","_id":"lwip@0.0.3","_shasum":"6ad4b91318565fd48aa906eddf1a8c1f9d3dcdf7","_from":".","_npmVersion":"1.4.9","_npmUser":{"name":"eyalar","email":"eyalarubas@gmail.com"},"maintainers":[{"name":"eyalar","email":"eyalarubas@gmail.com"}],"dist":{"shasum":"6ad4b91318565fd48aa906eddf1a8c1f9d3dcdf7","size":2395027,"noattachment":false,"key":"/lwip/-/lwip-0.0.3.tgz","tarball":"http://registry.cnpm.dingdandao.com/lwip/download/lwip-0.0.3.tgz"},"publish_time":1410753460484,"_cnpm_publish_time":1410753460484,"_hasShrinkwrap":false},"0.0.2":{"name":"lwip","version":"0.0.2","main":"index.js","dependencies":{"async":"^0.9.0","decree":"0.0.2"},"scripts":{"install":"node-gyp rebuild","test":"mocha --reporter spec --recursive tests/"},"gypfile":true,"description":"Comprehensive, fast, and simple image processing and manipulation","directories":{"example":"examples"},"devDependencies":{"mkdirp":"^0.5.0","mocha":"^1.20.1","should":"^4.0.4"},"repository":{"type":"git","url":"https://github.com/EyalAr/lwip.git"},"keywords":["image","manipulate","process","resize","scale","rotate","jpeg","jpg","png","crop","blur","batch","flip","mirror","border","padding"],"author":{"name":"Eyal Arubas","email":"eyalarubas@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/EyalAr/lwip/issues"},"homepage":"https://github.com/EyalAr/lwip","_id":"lwip@0.0.2","_shasum":"abd4f61b102773a96d0a5c2922b3afec0161f73c","_from":".","_npmVersion":"1.4.10","_npmUser":{"name":"eyalar","email":"eyalarubas@gmail.com"},"maintainers":[{"name":"eyalar","email":"eyalarubas@gmail.com"}],"dist":{"shasum":"abd4f61b102773a96d0a5c2922b3afec0161f73c","size":2388613,"noattachment":false,"key":"/lwip/-/lwip-0.0.2.tgz","tarball":"http://registry.cnpm.dingdandao.com/lwip/download/lwip-0.0.2.tgz"},"publish_time":1409830030774,"_cnpm_publish_time":1409830030774,"_hasShrinkwrap":false},"0.0.1":{"name":"lwip","version":"0.0.1","main":"index.js","dependencies":{"async":"^0.9.0","decree":"0.0.1"},"scripts":{"install":"node-gyp rebuild","test":"mocha --reporter spec --recursive tests/"},"gypfile":true,"description":"Comprehensive, fast, and simple image processing and manipulation","directories":{"example":"examples"},"devDependencies":{"mkdirp":"^0.5.0","mocha":"^1.20.1","should":"^4.0.4"},"repository":{"type":"git","url":"https://github.com/EyalAr/lwip.git"},"keywords":["image","manipulate","process","resize","scale","rotate","jpeg","jpg","crop","blur","batch"],"author":{"name":"Eyal Arubas","email":"eyalarubas@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/EyalAr/lwip/issues"},"homepage":"https://github.com/EyalAr/lwip","_id":"lwip@0.0.1","_shasum":"a53f22846ea8da37f6d2829c371850a7a57f7303","_from":".","_npmVersion":"1.4.10","_npmUser":{"name":"eyalar","email":"eyalarubas@gmail.com"},"maintainers":[{"name":"eyalar","email":"eyalarubas@gmail.com"}],"dist":{"shasum":"a53f22846ea8da37f6d2829c371850a7a57f7303","size":913852,"noattachment":false,"key":"/lwip/-/lwip-0.0.1.tgz","tarball":"http://registry.cnpm.dingdandao.com/lwip/download/lwip-0.0.1.tgz"},"publish_time":1404882962542,"_cnpm_publish_time":1404882962542,"_hasShrinkwrap":false}},"readme":"[![Version](http://img.shields.io/npm/v/lwip.svg)](https://www.npmjs.org/package/lwip)\n[![Build Status](https://api.travis-ci.org/EyalAr/lwip.svg?branch=master)](https://travis-ci.org/EyalAr/lwip)\n[![Build status](https://ci.appveyor.com/api/projects/status/46mk5218x995svhw/branch/master?svg=true)](https://ci.appveyor.com/project/EyalAr/lwip/branch/master)\n[![Coverage Status](https://img.shields.io/coveralls/EyalAr/lwip/master.svg)](https://coveralls.io/r/EyalAr/lwip)\n\n# Light-weight image processor for NodeJS\n\n[![Join the chat at https://gitter.im/EyalAr/lwip](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/EyalAr/lwip?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)\n\n0. [Overview](#overview)\n  0. [Installation](#installation)\n  0. [Usage](#usage)\n  0. [Supported formats](#supported-formats)\n  0. [Colors specification](#colors-specification)\n  0. [Note on transparent images](#note-on-transparent-images)\n0. [API](#api)\n  0. [Open an image from file or buffer](#open-an-image)\n  0. [Create a new blank image](#create-a-new-image)\n  0. [Image operations](#image-operations)\n    0. [Resize](#resize)\n    0. [Scale](#scale)\n    0. [Contain](#contain)\n    0. [Cover](#cover)\n    0. [Rotate](#rotate)\n    0. [Crop](#crop)\n    0. [Blur](#blur)\n    0. [Sharpen](#sharpen)\n    0. [Mirror](#mirror)\n    0. [Flip](#flip)\n    0. [Border](#border)\n    0. [Pad](#pad)\n    0. [Adjust saturation](#saturate)\n    0. Adjust lightness: [lighten](#lighten) / [darken](#darken)\n    0. [Adjust hue](#hue)\n    0. [Fade (adjust transparency)](#fade)\n    0. [Opacify](#opacify)\n    0. [Paste](#paste)\n    0. [Set pixel](#set-pixel)\n    0. [Set metadata](#set-metadata)\n  0. [Getters](#getters)\n    0. [Width](#width)\n    0. [Height](#height)\n    0. [Pixel](#get-pixel)\n    0. [Clone](#clone)\n    0. [Extract / Copy](#extract)\n    0. [Get as a Buffer](#get-as-a-buffer)\n      0. [JPEG](#jpeg)\n      0. [PNG](#png)\n      0. [GIF](#gif)\n    0. [Write to file](#write-to-file)\n    0. [Get metadata](#get-metadata)\n  0. [Batch operations](#batch-operations)\n0. [Copyrights](#copyrights)\n\n## Overview\n\nThis module provides comprehensive, fast, and simple image processing and\nmanipulation capabilities.\n\n**There are no external runtime dependencies**, which means you don't have to\ninstall anything else on your system.\n\n**This module is in active development. [New features](https://github.com/EyalAr/lwip/issues?labels=feature+request&page=1&state=open) are being added.**\n\n[Read the background for the development of this module.](http://eyalarubas.com/image-processing-nodejs.html)\n\n### Installation\n\n`npm install lwip`\n\nOr, clone this repo and `cd lwip && npm install`.\n\nYou can run tests with `npm test`.\n\n**Note:** Installation of this module involves compiling native code.\nIf `npm install lwip` failes, you probably need to setup your system.\n[See instructions](https://github.com/TooTallNate/node-gyp#installation).\nBuilding on Windows with Visual Studio requires version 2013 or higher.\n\n### Usage\n\n**Typical workflow:**\n\n0. Open an image and get an image object.\n0. Manipulate it.\n0. Save to disk / Send image buffer over network / etc.\n\n**Example (batch operations):**\n\n```Javascript\n// obtain an image object:\nrequire('lwip').open('image.jpg', function(err, image){\n\n  // check err...\n  // define a batch of manipulations and save to disk as JPEG:\n  image.batch()\n    .scale(0.75)          // scale to 75%\n    .rotate(45, 'white')  // rotate 45degs clockwise (white fill)\n    .crop(200, 200)       // crop a 200X200 square from center\n    .blur(5)              // Gaussian blur with SD=5\n    .writeFile('output.jpg', function(err){\n      // check err...\n      // done.\n    });\n\n});\n```\n\n**Example (non-batch):**\n\n```Javascript\nvar lwip = require('lwip');\n\n// obtain an image object:\nlwip.open('image.jpg', function(err, image){\n\n  // check err...\n  // manipulate image:\n  image.scale(0.5, function(err, image){\n\n    // check err...\n    // manipulate some more:\n    image.rotate(45, 'white', function(err, image){\n\n      // check err...\n      // encode to jpeg and get a buffer object:\n      image.toBuffer('jpg', function(err, buffer){\n\n        // check err...\n        // save buffer to disk / send over network / etc.\n\n      });\n\n    });\n\n  });\n\n});\n```\n\n### Supported formats\n\n**Decoding (reading):**\n\n- JPEG, 1 & 3 channels (grayscale & RGB).\n- PNG, transparency supported.\n- GIF, transparency supported. Animated GIFs can be read, but only the first\n  frame will be retrieved.\n\n**Encoding (writing):**\n\n- JPEG, 3 channels (RGB).\n- PNG (lossless), 3 channels (RGB) or 4 channels (RGBA).\n- GIF (no animations)\n\nOther formats may also be supported in the future, but are probably less urgent.\nCheck the issues to see [which formats are planned to be supported](https://github.com/EyalAr/lwip/issues?labels=format+request&page=1&state=open).\nOpen an issue if you need support for a format which is not already listed.\n\n### Colors specification\n\nIn LWIP colors are coded as RGBA values (red, green, blue and an alpha channel).\n\nColors are specified in one of three ways:\n\n- As a string. possible values:\n\n  ```Javascript\n  \"black\"    // {r: 0, g: 0, b: 0, a: 100}\n  \"white\"    // {r: 255, g: 255, b: 255, a: 100}\n  \"gray\"     // {r: 128, g: 128, b: 128, a: 100}\n  \"red\"      // {r: 255, g: 0, b: 0, a: 100}\n  \"green\"    // {r: 0, g: 255, b: 0, a: 100}\n  \"blue\"     // {r: 0, g: 0, b: 255, a: 100}\n  \"yellow\"   // {r: 255, g: 255, b: 0, a: 100}\n  \"cyan\"     // {r: 0, g: 255, b: 255, a: 100}\n  \"magenta\"  // {r: 255, g: 0, b: 255, a: 100}\n  ```\n\n- As an array `[R, G, B, A]` where `R`, `G` and `B` are integers between 0 and\n  255 and `A` is an integer between 0 and 100.\n- As an object `{r: R, g: G, b: B, a: A}` where `R`, `G` and `B` are integers\n  between 0 and 255 and `A` is an integer between 0 and 100.\n\n**Note**: The `A` value (alpha channel) is always optional and defaults to\n100 (completely opaque).\n\n### Note on transparent images\n\n0. Transparency is supported through an alpha channel which ranges between 0\n   and 100. 0 is completely transparent and 100 is completely opaque.\n0. Not all formats support transparency. If an image with an alpha channel is\n   encoded with a format which does not support transparency, the alpha channel\n   will be ignored (effectively setting it to 100% for all pixels).\n\n## API\n\nAll operations are done on an `image` object. An `image` object can be obtained\nby:\n\n0. Openning an existing image file or buffer with the [`open`](#open-an-image)\n   method.\n0. Creating a new image object with the [`create`](#create-a-new-image) method.\n0. Cloning an existing image object with the [`image.clone`](#clone) method.\n0. Extracting a sub-image from an existing image object with the\n   [`image.extract`](#extract) method.\n\n### Open an image\n\n`lwip.open(source, type, callback)`\n\n0. `source {String/Buffer}`: The path to the image on disk or an image buffer.\n0. `type {String/Object}`: **Optional** type of the image. If omitted, the type\n   will be inferred from the file extension. If `source` is a buffer, `type`\n   must be specified. If `source` is an encoded image buffer, `type` must be\n   a string of the image type (i.e. `\"jpg\"`). If `source` is a raw pixels buffer\n   `type` must be an object with `type.width` and `type.height` properties.\n0. `callback {Function(err, image)}`\n\n**Note about raw pixels buffers:** `source` may be a buffer of raw pixels. The\nbuffer may contain pixels of 1-4 channels, where:\n\n0. 1 channel is a grayscale image.\n0. 2 channels is a grayscale image with an alpha channel.\n0. 3 channels is an RGB image.\n0. 4 channels is an RGBA image (with an alpha channel).\n\nIn other words, if the image in the buffer has width `W` and height `H`, the\nsize of the buffer can be `W*H`, `2*W*H`, `3*W*H` or `4*W*H`.\n\nThe channel values in the buffer must be stored sequentially. I.e. first all the\nRed values, then all the Green values, etc.\n\n#### Open file example\n\n```Javascript\nvar lwip = require('lwip');\nlwip.open('path/to/image.jpg', function(err, image){\n    // check 'err'. use 'image'.\n    // image.resize(...), etc.\n});\n```\n\n#### Open buffer example\n\n```Javascript\nvar fs = require('fs'),\n    lwip = require('lwip');\n\nfs.readFile('path/to/image.png', function(err, buffer){\n  // check err\n  lwip.open(buffer, 'png', function(err, image){\n      // check 'err'. use 'image'.\n      // image.resize(...), etc.\n  });\n});\n```\n\n### Create a new image\n\n`lwip.create(width, height, color, callback)`\n\n0. `width {Integer>0}`: The width of the new image.\n0. `height {Integer>0}`: The height of the new image.\n0. `color {String / Array / Object}`: **Optional** Color of the canvas. See\n   [colors specification](#colors-specification). Defaults to a transparent\n   canvas `{r:0, g:0, b:0, a:0}`.\n0. `callback {Function(err, image)}`\n\n**Example**:\n\n```Javascript\nvar lwip = require('lwip');\n\nlwip.create(500, 500, 'yellow', function(err, image){\n  // check err\n  // 'image' is a 500X500 solid yellow canvas.\n});\n```\n\n### Image operations\n\n#### Resize\n\n`image.resize(width, height, inter, callback)`\n\n0. `width {Integer}`: Width in pixels.\n0. `height {Integer}`: **Optional** height in pixels. If omitted, `width` will\n   be used.\n0. `inter {String}`: **Optional** interpolation method. Defaults to `\"lanczos\"`.\n   Possible values:\n   - `\"nearest-neighbor\"`\n   - `\"moving-average\"`\n   - `\"linear\"`\n   - `\"grid\"`\n   - `\"cubic\"`\n   - `\"lanczos\"`\n0. `callback {Function(err, image)}`\n\n#### Scale\n\n`image.scale(wRatio, hRatio, inter, callback)`\n\n0. `wRatio {Float}`: Width scale ratio.\n0. `hRatio {Float}`: **Optional** height scale ratio. If omitted, `wRatio` will\n   be used.\n0. `inter {String}`: **Optional** interpolation method. Defaults to `\"lanczos\"`.\n   Possible values:\n   - `\"nearest-neighbor\"`\n   - `\"moving-average\"`\n   - `\"linear\"`\n   - `\"grid\"`\n   - `\"cubic\"`\n   - `\"lanczos\"`\n0. `callback {Function(err, image)}`\n\n#### Contain\n\nContain the image in a colored canvas. The image will be resized to the largest\npossible size such that it's fully contained inside the canvas.\n\n`image.contain(width, height, color, inter, callback)`\n\n0. `width {Integer}`: Canvas' width in pixels.\n0. `height {Integer}`: Canvas' height in pixels.\n0. `color {String / Array / Object}`: **Optional** Color of the canvas. See\n   [colors specification](#colors-specification).\n0. `inter {String}`: **Optional** interpolation method. Defaults to `\"lanczos\"`.\n   Possible values:\n   - `\"nearest-neighbor\"`\n   - `\"moving-average\"`\n   - `\"linear\"`\n   - `\"grid\"`\n   - `\"cubic\"`\n   - `\"lanczos\"`\n0. `callback {Function(err, image)}`\n\n#### Cover\n\nCover a canvas with the image. The image will be resized to the smallest\npossible size such that both its dimensions are bigger than the canvas's\ndimensions. Margins of the image exceeding the canvas will be discarded.\n\n`image.cover(width, height, inter, callback)`\n\n0. `width {Integer}`: Canvas' width in pixels.\n0. `height {Integer}`: Canvas' height in pixels.\n0. `inter {String}`: **Optional** interpolation method. Defaults to `\"lanczos\"`.\n   Possible values:\n   - `\"nearest-neighbor\"`\n   - `\"moving-average\"`\n   - `\"linear\"`\n   - `\"grid\"`\n   - `\"cubic\"`\n   - `\"lanczos\"`\n0. `callback {Function(err, image)}`\n\n#### Rotate\n\n`image.rotate(degs, color, callback)`\n\n0. `degs {Float}`: Clockwise rotation degrees.\n0. `color {String / Array / Object}`: **Optional** Color of the canvas. See\n   [colors specification](#colors-specification).\n0. `callback {Function(err, image)}`\n\n#### Crop\n\n#### Crop with rectangle coordinates\n\n`image.crop(left, top, right, bottom, callback)`\n\n0. `left, top, right, bottom {Integer}`: Coordinates of the crop rectangle.\n0. `callback {Function(err, image)}`\n\n#### Crop a rectangle from center\n\n`image.crop(width, height, callback)`\n\n0. `width, height {Integer}`: Width and height of the rectangle to crop from the\n   center of the image.\n0. `callback {Function(err, image)}`\n\n#### Blur\n\nGaussian blur.\n\n`image.blur(sigma, callback)`\n\n0. `sigma {Float>=0}`: Standard deviation of the Gaussian filter.\n0. `callback {Function(err, image)}`\n\n#### Sharpen\n\nInverse diffusion shapren.\n\n`image.sharpen(amplitude, callback)`\n\n0. `amplitude {Float}`: Sharpening amplitude.\n0. `callback {Function(err, image)}`\n\n#### Mirror\n\nMirror an image along the 'x' axis, 'y' axis or both.\n\n`image.mirror(axes, callback)`\n\n0. `axes {String}`: `'x'`, `'y'` or `'xy'` (case sensitive).\n0. `callback {Function(err, image)}`\n\n#### Flip\n\nAlias of [`mirror`](#mirror).\n\n#### Border\n\nAdd a colored border to the image.\n\n`image.border(width, color, callback)`\n\n0. `width {Integer}`: Border width in pixels.\n0. `color {String / Array / Object}`: **Optional** Color of the border. See\n   [colors specification](#colors-specification).\n0. `callback {Function(err, image)}`\n\n#### Pad\n\nPad image edges with colored pixels.\n\n`image.pad(left, top, right, bottom, color, callback)`\n\n0. `left, top, right, bottom {Integer}`: Number of pixels to add to each edge.\n0. `color {String / Array / Object}`: **Optional** Color of the padding. See\n   [colors specification](#colors-specification).\n0. `callback {Function(err, image)}`\n\n#### Saturate\n\nAdjust image saturation.\n\n`image.saturate(delta, callback)`\n\n0. `delta {Float}`: By how much to increase / decrease the saturation.\n0. `callback {Function(err, image)}`\n\n**Examples**:\n\n0. `image.saturate(0, ...)` will have no effect on the image.\n0. `image.saturate(0.5, ...)` will increase the saturation by 50%.\n0. `image.saturate(-1, ...)` will decrease the saturation by 100%, effectively\n   desaturating the image.\n\n#### Lighten\n\nAdjust image lightness.\n\n`image.lighten(delta, callback)`\n\n0. `delta {Float}`: By how much to increase / decrease the lightness.\n0. `callback {Function(err, image)}`\n\n**Examples**:\n\n0. `image.lighten(0, ...)` will have no effect on the image.\n0. `image.lighten(0.5, ...)` will increase the lightness by 50%.\n0. `image.lighten(-1, ...)` will decrease the lightness by 100%, effectively\n   making the image black.\n\n#### Darken\n\nAdjust image lightness.\n\n`image.darken(delta, callback)`\n\nEquivalent to `image.lighten(-delta, callback)`.\n\n#### Hue\n\nAdjust image hue.\n\n`image.hue(shift, callback)`\n\n0. `shift {Float}`: By how many degrees to shift each pixel's hue.\n0. `callback {Function(err, image)}`\n\n**Examples**:\n\n0. `image.lighten(0, ...)` will have no effect on the image.\n0. `image.lighten(100, ...)` will shift pixels' hue by 100 degrees.\n\n**Note:** The hue is shifted in a circular manner in the range [0,360] for each\npixel individually.\n\n#### Fade\n\nAdjust image transperancy.\n\n`image.fade(delta, callback)`\n\n0. `delta {Float}`: By how much to increase / decrease the transperancy.\n0. `callback {Function(err, image)}`\n\n**Note:** The transparency is adjusted independently for each pixel.\n\n**Examples**:\n\n0. `image.fade(0, ...)` will have no effect on the image.\n0. `image.fade(0.5, ...)` will increase the transparency by 50%.\n0. `image.fade(1, ...)` will make the image completely transparent.\n\n#### Opacify\n\nMake image completely opaque.\n\n`image.opacify(callback)`\n\n0. `callback {Function(err, image)}`\n\n#### Paste\n\nPaste an image on top of this image.\n\n`image.paste(left, top, img, callback)`\n\n0. `left, top {Integer}`: Coordinates of the top-left corner of the pasted\n   image.\n0. `img {Image object}`: The image to paste.\n0. `callback {Function(err, image)}`\n\n**Notes:**\n\n0. If the pasted image exceeds the bounds of the base image, an exception\n   is thrown.\n0. `img` is pasted in the state it was at the time `image.paste( ... )` was\n   called, eventhough `callback` is called asynchronously.\n0. For transparent images, alpha blending is done according to the equations\n   described [here](http://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending).\n0. Extra caution is required when using this method in batch mode, as the images\n   may change by the time this operation is called.\n\n#### Set Pixel\n\nSet the color of a pixel.\n\n`image.setPixel(left, top, color, callback)`\n\n0. `left, top {Integer}`: Coordinates of the pixel from the left-top corner of\n   the image.\n0. `color {String / Array / Object}`: Color of the pixel to set.\n   See [colors specification](#colors-specification).\n0. `callback {Function(err, image)}`\n\n**Notes:**\n\n0. If the coordinates exceed the bounds of the image, an exception is thrown.\n0. Extra caution is required when using this method in batch mode, as the\n  dimensions of the image may change by the time this operation is called.\n\n#### Set metadata\n\nSet the metadata in an image. This is currently only supported for PNG files.\nSets a tEXt chunk with the key `lwip_data` and comment as the given string. If\ncalled with a `null` parameter, removes existing metadata from the image,\nif present.\n\n`image.setMetadata(metadata)`\n\n0. `metadata {String}`: a string of arbitrary length, or null.\n\n### Getters\n\n#### Width\n\n`image.width()` returns the image's width in pixels.\n\n#### Height\n\n`image.height()` returns the image's height in pixels.\n\n#### Get Pixel\n\n`image.getPixel(left, top)` returns the color of the pixel at the `(left, top)`\ncoordinate.\n\n0. `left {Integer>=0}`\n0. `top {Integer>=0}`\n\nColor is returned as an object. See [colors specification](#colors-specification).\n\n#### Clone\n\nClone the image into a new image object.\n\n`image.clone(callback)`\n\n0. `callback {Function(err, newImage)}`\n\n**Example**: See [`examples/clone.js`](examples/clone.js)\n\n**Note**: The image is cloned to the state it was at the time\n`image.clone( ... )` was called, eventhough `callback` is called asynchronously.\n\n```Javascript\nimage.width(); // 500\nimage.clone(function(err, clone){\n    clone.width(); // 500\n});\nimage.resize(100, 100, function(err, image){\n    image.width(); //100\n});\n```\n\n#### Extract\n\nCopy an area of the image into a new image object.\n\n`image.extract(left, top, right, bottom, callback)`\n\n0. `left, top, right, bottom {Integer}`: Coordinates of the area to copy.\n0. `callback {Function(err, newImage)}`\n\n**Example**: See [`examples/extract.js`](examples/extract.js)\n\n**Note**: The sub-image is extracted from the original image in the state it was\nat the time `image.extract( ... )` was called, eventhough `callback` is called\nasynchronously.\n\n#### Get as a Buffer\n\nGet encoded binary image data as a NodeJS\n[Buffer](http://nodejs.org/api/buffer.html).\n\nWhen opening an image, it is decoded and stored in memory as an uncompressed\nimage. All manipulations are done on the uncompressed data in memory. This\nmethod allows to encode the image to one of the specified formats and get the\nencoded data as a NodeJS Buffer object.\n\n`image.toBuffer(format, params, callback)`\n\n0. `format {String}`: Encoding format. Possible values:\n  - `\"jpg\"`\n  - `\"png\"`\n  - `\"gif\"`\n0. `params {Object}`: **Optional** Format-specific parameters (See below).\n0. `callback {Function(err, buffer)}`\n\n**Supported encoding formats:**\n\n##### JPEG\n\nThe `params` object should have the following fields:\n\n- `quality {Integer}`: Defaults to `100`.\n\nNote that when encoding to JPEG the alpha channel is discarded.\n\n##### PNG\n\nThe `params` object should have the following fields:\n\n- `compression {String}`: Defaults to `\"fast\"`. Possible values:\n  - `\"none\"` - No compression. Fastest.\n  - `\"fast\"` - Basic compression. Fast.\n  - `\"high\"` - High compression. Slowest.\n- `interlaced {Boolean}`: Defaults to `false`.\n- `transparency {true/false/'auto'}`: Preserve transparency? Defaults to\n  `'auto'`. Determines if the encoded image will have 3 or 4 channels. If\n  `'auto'`, the image will be encoded with 4 channels if it has transparent\n  components, and 3 channels otherwise.\n\n##### GIF\n\nThe `params` object should have the following fields:\n\n- `colors {Integer}`: Defaults to `256`. Number of colors in the color table\n  (at most). Must be between 2 and 256.\n- `interlaced {Boolean}`: Defaults to `false`.\n- `transparency {true/false/'auto'}`: Preserve transparency? Defaults to\n  `'auto'`. Determines if the encoded image will have 3 or 4 channels. If\n  `'auto'`, the image will be encoded with 4 channels if it has transparent\n  components, and 3 channels otherwise.\n- `threshold {Integer}` - Between 0 and 100. Pixels in a gif image are either\n  fully transparent or fully opaque. This value sets the alpha channel\n  threshold to determine if a pixel is opaque or transparent. If the alpha\n  channel of the pixel is above this threshold, this pixel will be considered\n  as opaque; otherwise it will be transparent.\n\n#### Write to file\n\nWrite encoded binary image data directly to a file.\n\n`image.writeFile(path, format, params, callback)`\n\n0. `path {String}`: Path of file to write.\n0. `format {String}`: **Optional** Encoding format. If omitted, will be inferred\n   from `path` extension. Possible values are specified in\n   [Get as a Buffer](#get-as-a-buffer) section.\n0. `params {Object}`: **Optional** Format-specific parameters.\n0. `callback {Function(err)}`\n\n#### Get Metadata\n\nGet the textual metadata from an image. This is currently only supported for\ntEXt chunks in PNG images, and will get the first tEXt chunk found with the key\n`lwip_data`. If none is found, returns null.\n\n`image.getMetadata()`\n\n### Batch operations\n\nEach of the [image operations](#image-operations) above can be done as part of\na batch of operations. Operations can be queued, and executed as a batch at any\ntime.\n\nEach one of the [image operations](#image-operations) has a batch equivalent\nwhich takes the same arguments, except the callback, which is not needed.\n\nWhen all batch operations had been queued, they can be executed in one of\nseveral methods, as explained below.\n\n#### Obtaining a batch object\n\nIn order to start queueing operations, a batch object first needs to be obtained\nfrom the image.\n\n```Javascript\n// obtain a batch object from the image:\nvar batch = image.batch();\n```\n\n#### Using a batch object\n\nUse the batch object to queue [image operations](#image-operations). Each of the\noperations above has a batch equivalent. Operations can be chained.\n\n**Remember, the batch manipulation methods do not take a callback.**\n\n**Example:**\n\n```Javascript\nbatch.rotate(45, 'white').scale(0.5).blur(5);\n```\n\n#### Executing a batch\n\nThere are several methods which start the execution of a batch. Once a batch\nfinishes an execution, it becomes empty and can be resued to queue additional\noperations.\n\n##### Execute batch and obtain the manipulated image object\n\nWhen all desired operations had been queued, execute the batch with the `exec()`\nmethod. `exec` takes a `callback` argument; `callback` is a function which\nreceives an error object and the manipulated image object:\n\n`batch.exec(callback)`\n\n  - `callback {Function(err, image)}`:\n    - `err`: An error object or `null` when no error.\n    - `image`: An image object of the manipulated image.\n\n```Javascript\nbatch.exec(function(err, image){\n  // check err, use image\n});\n```\n\n##### Execute batch and obtain a Buffer object\n\nBatch objects have a `toBuffer` convenience method.\n\n`batch.toBuffer(format, params, callback)`\n\nSee parameters of [`image.toBuffer()`](#get-as-a-buffer).\n\n##### Execute batch and write to file\n\nBatch objects have a `writeFile` convenience method.\n\n`batch.writeFile(path, format, params, callback)`\n\nSee parameters of [`image.writeFile()`](#write-to-file).\n\n#### Notes on batch operations\n\nAn image can have more than one batch object, but all batch objects modify the\nsame underlying image. This means the order of execution matters.\n\n```Javascript\nvar batch1 = image.batch().rotate('45', 'black');\nvar batch2 = image.batch().border(15, 'black');\n```\n\nThis will rotate the image 45degs and then add a black border:\n\n```Javascript\nbatch1.exec(function(err, image){\n    batch2.exec(function(err, image){\n        // ...\n    });\n});\n```\n\nWhile this will add a black border and then rotate the image 45degs:\n\n```Javascript\nbatch2.exec(function(err, image){\n    batch1.exec(function(err, image){\n        // ...\n    });\n});\n```\n\n## Copyrights\n\nThe native part of this module is compiled from source which uses the following:\n\n- Independent JPEG Group's free JPEG software:\n  - [Website](http://www.ijg.org/)\n  - [Readme](https://github.com/EyalAr/lwip/blob/master/src/lib/jpeg/README)\n- libpng:\n  - [Website](http://www.libpng.org/)\n  - [Readme](https://github.com/EyalAr/lwip/blob/master/src/lib/png/README)\n- zlib:\n  - [Website](http://www.zlib.net/)\n  - [Readme](https://github.com/EyalAr/lwip/blob/master/src/lib/zlib/README)\n- The CImg Library\n  - [Website](http://cimg.sourceforge.net/)\n  - [Readme](https://github.com/EyalAr/lwip/blob/master/src/lib/cimg/README.txt)\n- giflib\n  - [Website](http://giflib.sourceforge.net/)\n  - [Readme](https://github.com/EyalAr/lwip/blob/master/src/lib/gif/README)\n","_attachments":{},"homepage":"https://github.com/EyalAr/lwip","bugs":{"url":"https://github.com/EyalAr/lwip/issues"},"license":"MIT"}