UNPKG

node-libpng

Version:

Unofficial bindings for node to libpng.

742 lines (727 loc) 49.6 kB
<!doctype html> <html class="default no-js"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>node-libpng</title> <meta name="description" content=""> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="assets/css/main.css"> </head> <body> <header> <div class="tsd-page-toolbar"> <div class="container"> <div class="table-wrap"> <div class="table-cell" id="tsd-search" data-index="assets/js/search.js" data-base="."> <div class="field"> <label for="tsd-search-field" class="tsd-widget search no-caption">Search</label> <input id="tsd-search-field" type="text" /> </div> <ul class="results"> <li class="state loading">Preparing search index...</li> <li class="state failure">The search index is not available</li> </ul> <a href="index.html" class="title">node-libpng</a> </div> <div class="table-cell" id="tsd-widgets"> <div id="tsd-filter"> <a href="#" class="tsd-widget options no-caption" data-toggle="options">Options</a> <div class="tsd-filter-group"> <div class="tsd-select" id="tsd-filter-visibility"> <span class="tsd-select-label">All</span> <ul class="tsd-select-list"> <li data-value="public">Public</li> <li data-value="protected">Public/Protected</li> <li data-value="private" class="selected">All</li> </ul> </div> <input type="checkbox" id="tsd-filter-inherited" checked /> <label class="tsd-widget" for="tsd-filter-inherited">Inherited</label> <input type="checkbox" id="tsd-filter-externals" checked /> <label class="tsd-widget" for="tsd-filter-externals">Externals</label> <input type="checkbox" id="tsd-filter-only-exported" /> <label class="tsd-widget" for="tsd-filter-only-exported">Only exported</label> </div> </div> <a href="#" class="tsd-widget menu no-caption" data-toggle="menu">Menu</a> </div> </div> </div> </div> <div class="tsd-page-title"> <div class="container"> <ul class="tsd-breadcrumb"> <li> <a href="globals.html">Globals</a> </li> </ul> <h1> node-libpng</h1> </div> </div> </header> <div class="container container-main"> <div class="row"> <div class="col-8 col-content"> <div class="tsd-panel tsd-typography"> <h1 id="node-libpng">node-libpng</h1> <p><a href="https://www.npmjs.com/package/node-libpng"><img src="https://img.shields.io/npm/v/node-libpng.svg" alt="npm"></a> <a href="https://travis-ci.org/Prior99/node-libpng"><img src="https://travis-ci.org/Prior99/node-libpng.svg?branch=master" alt="Build Status"></a> <a href="https://ci.appveyor.com/project/Prior99/node-libpng/branch/master"><img src="https://ci.appveyor.com/api/projects/status/1dbpcj210jlyv0e1/branch/master?svg=true" alt="Build status"></a> <a href="https://coveralls.io/github/Prior99/node-libpng?branch=master"><img src="https://coveralls.io/repos/github/Prior99/node-libpng/badge.svg?branch=master" alt="Coverage Status"></a></p> <p>Unofficial bindings for node to libpng.</p> <p>Please also refer to the <strong><a href="https://prior99.github.io/node-libpng/docs/index.html">Documentation</a></strong>.</p> <h2 id="table-of-contents">Table of contents</h2> <ul> <li><a href="#node-libpng">node-libpng</a><ul> <li><a href="#table-of-contents">Table of contents</a></li> <li><a href="#supported-environments">Supported environments</a></li> <li><a href="#usage">Usage</a><ul> <li><a href="#reading-decoding">Reading (Decoding)</a><ul> <li><a href="#reading-png-files-using-promises">Reading PNG files using Promises</a></li> <li><a href="#reading-png-files-using-a-callback">Reading PNG files using a callback</a></li> <li><a href="#reading-png-files-synchroneously">Reading PNG files synchroneously</a></li> <li><a href="#decoding-a-buffer">Decoding a buffer</a><ul> <li><a href="#writing-encoding">Writing (Encoding)</a></li> </ul> </li> <li><a href="#writing-png-files-using-promises">Writing PNG files using Promises</a></li> <li><a href="#writing-png-files-using-a-callback">Writing PNG files using a callback</a></li> <li><a href="#writing-png-files-synchroneously">Writing PNG files synchroneously</a></li> <li><a href="#encoding-into-a-buffer">Encoding into a Buffer</a><ul> <li><a href="#accessing-the-pixels">Accessing the pixels</a></li> </ul> </li> <li><a href="#accessing-in-the-images-color-format">Accessing in the image&#39;s color format</a></li> <li><a href="#accessing-in-rgba-format">Accessing in rgba format</a><ul> <li><a href="#modifying-the-image">Modifying the image</a></li> </ul> </li> <li><a href="#cropping">Cropping</a></li> <li><a href="#resizing-the-canvas">Resizing the canvas</a></li> <li><a href="#copying-an-image-into-another-image">Copying an image into another image</a></li> <li><a href="#filling-an-area-with-a-specified-color">Filling an area with a specified color</a></li> <li><a href="#setting-a-single-pixel">Setting a single pixel</a></li> </ul> </li> </ul> </li> <li><a href="#benchmark">Benchmark</a><ul> <li><a href="#read-access-decoding">Read access (Decoding)</a></li> <li><a href="#write-access-encoding">Write access (Encoding)</a></li> <li><a href="#pixel-access">Pixel access</a></li> </ul> </li> <li><a href="#contributing">Contributing</a><ul> <li><a href="#generating-the-libpng-config">Generating the libpng config</a></li> </ul> </li> <li><a href="#contributors">Contributors</a></li> </ul> </li> </ul> <h2 id="supported-environments">Supported environments</h2> <p>This is a native Addon to NodeJS which delivers prebuilt binaries. Only some environments are supported:</p> <table> <thead> <tr> <th>Node Version</th> <th>Windows 64-Bit</th> <th>Windows 32-Bit</th> <th>Linux 64-Bit</th> <th>Linux 32-Bit</th> <th>OSX</th> </tr> </thead> <tbody> <tr> <td>Earlier</td> <td></td> <td></td> <td></td> <td></td> <td></td> </tr> <tr> <td>Node 6 <em>(Abi 48)</em></td> <td></td> <td></td> <td></td> <td></td> <td></td> </tr> <tr> <td>Node 7 <em>(Abi 51)</em></td> <td></td> <td></td> <td></td> <td></td> <td></td> </tr> <tr> <td>Node 8 <em>(Abi 57)</em></td> <td></td> <td></td> <td></td> <td></td> <td></td> </tr> <tr> <td>Node 9 <em>(Abi 59)</em></td> <td></td> <td></td> <td></td> <td></td> <td></td> </tr> <tr> <td>Node 10 <em>(Abi 64)</em></td> <td></td> <td></td> <td></td> <td></td> <td></td> </tr> </tbody> </table> <h2 id="usage">Usage</h2> <h3 id="reading-decoding-">Reading (Decoding)</h3> <p>Multiple ways of reading and decoding PNG encoded images exist:</p> <ul> <li><a href="https://prior99.github.io/node-libpng/docs/globals.html#readpngfile">readPngFile</a> Reads a PNG file and returns a <a href="https://prior99.github.io/node-libpng/docs/classes/pngimage.html">PngImage</a> instance with the decoded data.<ul> <li>The function can take an optional argument for using a node-style callback API. <a href="#reading-png-files-using-a-callback">Example</a></li> <li>The function will return a Promise when not providing a callback. <a href="#reading-png-files-using-promises">Example</a></li> </ul> </li> <li><a href="https://prior99.github.io/node-libpng/docs/globals.html#readpngfilesync">readPngFileSync</a> Will read a PNG file synchroneously and return a <a href="https://prior99.github.io/node-libpng/docs/classes/pngimage.html">PngImage</a> instance with the decoded image. <a href="#reading-png-files-synchroneously">Example</a></li> <li><a href="https://prior99.github.io/node-libpng/docs/globals.html#decode">decode</a> Will decode a Buffer of raw PNG file data and return a <a href="https://prior99.github.io/node-libpng/docs/classes/pngimage.html">PngImage</a> instance. <a href="#decoding-a-buffer">Example</a></li> </ul> <h4 id="reading-png-files-using-promises">Reading PNG files using Promises</h4> <p>In order to use the Promise-based API, simply omit the third argument.</p> <pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { readPngFile } <span class="hljs-keyword">from</span> <span class="hljs-string">"node-libpng"</span>; <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">readMyFile</span>(<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword">const</span> image = <span class="hljs-keyword">await</span> readPngFile(<span class="hljs-string">"path/to/image.png"</span>); <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Reading was successful. The dimensions of the image are <span class="hljs-subst">${image.width}</span>x<span class="hljs-subst">${image.height}</span>.`</span>); } </code></pre> <p>If an error occured while reading the file or decoding the buffer, the Promise which <code>writePngFile</code> returns will reject with the error.</p> <h4 id="reading-png-files-using-a-callback">Reading PNG files using a callback</h4> <p>In order to use the callback-based API, simply provide a callback as the third argument.</p> <pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { readPngFile } <span class="hljs-keyword">from</span> <span class="hljs-string">"node-libpng"</span>; <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">readMyFile</span>(<span class="hljs-params"></span>) </span>{ readPngFile(<span class="hljs-string">"path/to/image.png"</span>, <span class="hljs-function">(<span class="hljs-params">error, image</span>) =&gt;</span> { <span class="hljs-keyword">if</span> (error !== <span class="hljs-literal">null</span>) { <span class="hljs-comment">// <span class="hljs-doctag">TODO:</span> Check what `error` contains.</span> } <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Reading was successful. The dimensions of the image are <span class="hljs-subst">${image.width}</span>x<span class="hljs-subst">${image.height}</span>.`</span>); }); } </code></pre> <p>If an error occured while reading the file or decoding the buffer, it will be passed as the first argument to the callback. Otherwise <code>null</code> will be passed. The <a href="https://prior99.github.io/node-libpng/docs/classes/pngimage.html">PngImage</a> instance will be passed as the second argument. If an error occured, it will be <code>undefined</code>.</p> <h4 id="reading-png-files-synchroneously">Reading PNG files synchroneously</h4> <p>It is possible to read the image from the disk in a blocking way, using Node&#39;s <code>readFileSync</code>:</p> <pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { readPngFileSync } <span class="hljs-keyword">from</span> <span class="hljs-string">"node-libpng"</span>; <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">readMyFile</span>(<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword">const</span> image = readPngFileSync(<span class="hljs-string">"path/to/image.png"</span>); <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Reading was successful. The dimensions of the image are <span class="hljs-subst">${image.width}</span>x<span class="hljs-subst">${image.height}</span>.`</span>); } </code></pre> <p>If an error occured while reading the file or decoding the buffer, it will be <code>throw</code>n.</p> <h4 id="decoding-a-buffer">Decoding a buffer</h4> <p>Buffers can be decoded directly into a <a href="https://prior99.github.io/node-libpng/docs/classes/pngimage.html">PngImage</a> instance:</p> <pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { decode } <span class="hljs-keyword">from</span> <span class="hljs-string">"node-libpng"</span>; <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">decodeMyBuffer</span>(<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword">const</span> buffer = ...; <span class="hljs-comment">// Some buffer containing the raw PNG file's data.</span> <span class="hljs-keyword">const</span> image = decode(buffer); <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Decoding was successful. The dimensions of the image are <span class="hljs-subst">${image.width}</span>x<span class="hljs-subst">${image.height}</span>.`</span>); } </code></pre> <p>If an error occured while decoding the buffer, it will be <code>throw</code>n. The decoding happens synchroneously.</p> <h3 id="writing-encoding-">Writing (Encoding)</h3> <p>Multiple ways for encoding and writing raw image data exist:</p> <ul> <li><a href="https://prior99.github.io/node-libpng/docs/globals.html#writepngfile">writePngFile</a> Writes the raw data into a PNG file using Promises or a callback.<ul> <li>The function can take an optional argument for using a node-style callback API. <a href="#writing-png-files-using-a-callback">Example</a></li> <li>The function will return a Promise when not providing a callback. <a href="#writing-png-files-using-promises">Example</a></li> </ul> </li> <li><a href="https://prior99.github.io/node-libpng/docs/globals.html#writepngfilesync">writePngFileSync</a> Writes the raw data into a PNG file synchroneously. <a href="#writing-png-files-synchroneously">Example</a></li> <li><a href="https://prior99.github.io/node-libpng/docs/globals.html#encode">encode</a> Encodes the raw data into a Buffer containing the PNG file&#39;s data. <a href="#encoding-into-a-buffer">Example</a></li> <li><a href="https://prior99.github.io/node-libpng/docs/classes/pngimage.html">PngImage</a> contains methods for encoding and writing modified image data:<ul> <li><a href="https://prior99.github.io/node-libpng/docs/classes/pngimage.html#encode">PngImage.encode</a> The same as calling the free function <a href="">encode</a> with <code>PngImage.data</code>.</li> <li><a href="https://prior99.github.io/node-libpng/docs/classes/pngimage.html#write">PngImage.write</a> The same as calling the free function <a href="">writePngFile</a> with <code>PngImage.data</code>.</li> <li><a href="https://prior99.github.io/node-libpng/docs/classes/pngimage.html#writesync">PngImage.writeSync</a> The same as calling the free function <a href="">writePngFileSync</a> with <code>PngImage.data</code>.</li> </ul> </li> </ul> <h4 id="writing-png-files-using-promises">Writing PNG files using Promises</h4> <p>In order to use the Promise-based API, simply omit the 4th argument.</p> <pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { writePngFile } <span class="hljs-keyword">from</span> <span class="hljs-string">"node-libpng"</span>; <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">writeMyFile</span>(<span class="hljs-params"></span>) </span>{ <span class="hljs-comment">// Let's write a 100x60 pixel PNG file.</span> <span class="hljs-keyword">const</span> imageData = Buffer.alloc(<span class="hljs-number">100</span> * <span class="hljs-number">60</span> * <span class="hljs-number">3</span>); <span class="hljs-comment">// <span class="hljs-doctag">TODO:</span> Manipulate the image data somehow.</span> <span class="hljs-keyword">const</span> options = { width: <span class="hljs-number">100</span>, height: <span class="hljs-number">60</span> }; <span class="hljs-keyword">await</span> writePngFile(<span class="hljs-string">"path/to/image.png"</span>, imageData, options); <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"File successfully written."</span>); } </code></pre> <p>In this example, a 100x60 pixel image will be encoded and written to disk. Based on the length of the buffer and the provided dimensions the presence of an alpha channel will be automatically calculated.</p> <p>It is possible to omit either <code>width</code> or <code>height</code> from the options.</p> <p>If an error occured while writing the file or encoding the buffer, the Promise which <code>writePngFile</code> returns will reject with the error.</p> <h4 id="writing-png-files-using-a-callback">Writing PNG files using a callback</h4> <p>In order to use the callback-based API, provide a callback as the 4th argument.</p> <pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { writePngFile } <span class="hljs-keyword">from</span> <span class="hljs-string">"node-libpng"</span>; <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">writeMyFile</span>(<span class="hljs-params"></span>) </span>{ <span class="hljs-comment">// Let's write a 100x60 pixel PNG file.</span> <span class="hljs-keyword">const</span> imageData = Buffer.alloc(<span class="hljs-number">100</span> * <span class="hljs-number">60</span> * <span class="hljs-number">3</span>); <span class="hljs-comment">// <span class="hljs-doctag">TODO:</span> Manipulate the image data somehow.</span> <span class="hljs-keyword">const</span> options = { width: <span class="hljs-number">100</span>, height: <span class="hljs-number">60</span> }; <span class="hljs-keyword">await</span> writePngFile(<span class="hljs-string">"path/to/image.png"</span>, imageData, options, <span class="hljs-function">(<span class="hljs-params">error</span>) =&gt;</span> { <span class="hljs-keyword">if</span> (error !== <span class="hljs-literal">null</span>) { <span class="hljs-comment">// <span class="hljs-doctag">TODO:</span> Check what `error` contains.</span> } <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"File successfully written."</span>); }); } </code></pre> <p>In this example, a 100x60 pixel image will be encoded and written to disk. Based on the length of the buffer and the provided dimensions the presence of an alpha channel will be automatically calculated.</p> <p>It is possible to omit either <code>width</code> or <code>height</code> from the options.</p> <p>If an error occured while writing the file or encoding the buffer, it will be passed as the first and only argument in the callback. Otherwise <code>null</code> will be passed.</p> <h4 id="writing-png-files-synchroneously">Writing PNG files synchroneously</h4> <p>It is possible to write the image to disk in a blocking way, using Node&#39;s <code>writeFileSync</code>:</p> <pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { writePngFileSync } <span class="hljs-keyword">from</span> <span class="hljs-string">"node-libpng"</span>; <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">writeMyFile</span>(<span class="hljs-params"></span>) </span>{ <span class="hljs-comment">// Let's write a 100x60 pixel PNG file.</span> <span class="hljs-keyword">const</span> imageData = Buffer.alloc(<span class="hljs-number">100</span> * <span class="hljs-number">60</span> * <span class="hljs-number">3</span>); <span class="hljs-comment">// <span class="hljs-doctag">TODO:</span> Manipulate the image data somehow.</span> <span class="hljs-keyword">const</span> options = { width: <span class="hljs-number">100</span>, height: <span class="hljs-number">60</span> }; writePngFileSync(<span class="hljs-string">"path/to/image.png"</span>, imageData, options); <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"File successfully written."</span>); } </code></pre> <p>In this example, a 100x60 pixel image will be encoded and written to disk. Based on the length of the buffer and the provided dimensions the presence of an alpha channel will be automatically calculated.</p> <p>It is possible to omit either <code>width</code> or <code>height</code> from the options.</p> <p>If an error occured while writing the file or encoding the buffer, it will be <code>throw</code>n.</p> <h4 id="encoding-into-a-buffer">Encoding into a Buffer</h4> <p>Buffers can be encoded directly from a buffer containing the raw pixel data:</p> <pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { encode } <span class="hljs-keyword">from</span> <span class="hljs-string">"node-libpng"</span>; <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">encodeMyBuffer</span>(<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword">const</span> buffer = ...; <span class="hljs-comment">// Some buffer containing the raw pixel data.</span> <span class="hljs-keyword">const</span> options = { width: <span class="hljs-number">100</span>, height: <span class="hljs-number">100</span> }; <span class="hljs-keyword">const</span> encodedPngData = encode(buffer); <span class="hljs-comment">// The Buffer `encodedPngData` now contains the raw PNG-encoded data.</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"File successfully encoded."</span>); } </code></pre> <p>Based on the length of the buffer and the provided dimensions the presence of an alpha channel will be automatically calculated. If an error occured while encoding the buffer, it will be <code>throw</code>n. The encoding happens synchroneously.</p> <h3 id="accessing-the-pixels">Accessing the pixels</h3> <p>PNG specifies five different types of colors:</p> <ul> <li><a href="https://prior99.github.io/node-libpng/docs/enums/colortype.html#gray_scale">Gray Scale</a></li> <li><a href="https://prior99.github.io/node-libpng/docs/enums/colortype.html#gray_scale_alpha">Gray Scale with Alpha channel</a></li> <li><a href="https://prior99.github.io/node-libpng/docs/enums/colortype.html#palette">Palette (Indexed)</a></li> <li><a href="https://prior99.github.io/node-libpng/docs/enums/colortype.html#rgb">RGB</a></li> <li><a href="https://prior99.github.io/node-libpng/docs/enums/colortype.html#rgba">RGB with Alpha channel</a></li> </ul> <p>In the <a href="https://prior99.github.io/node-libpng/docs/classes/pngimage.html#data">PngImage.data</a> buffer the colors are stored the way they were encoded in the PNG image. This library provides utilities for accessing the pixels in both the native format as well as rgba format.</p> <h4 id="accessing-in-the-image-s-color-format">Accessing in the image&#39;s color format</h4> <p>In order to retrieve the color in the image&#39;s native format at a given position <a href="https://prior99.github.io/node-libpng/docs/classes/pngimage.html#at">PngImage.at</a> can be used.</p> <h5 id="example-for-a-gray-scale-image">Example for a gray scale image</h5> <pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { readPngFileSync } <span class="hljs-keyword">from</span> <span class="hljs-string">"node-libpng"</span>; <span class="hljs-keyword">const</span> image = readPngFileSync(<span class="hljs-string">"path/to/grayscale-image.png"</span>); <span class="hljs-keyword">const</span> color = image.at(<span class="hljs-number">10</span>, <span class="hljs-number">10</span>); <span class="hljs-keyword">const</span> colorType = image.colorType; <span class="hljs-comment">// Will log: "The color type of the image is gray-scale. Pixel at 10,10 is of color 168."</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`The color type of the image is <span class="hljs-subst">${colorType}</span>. Pixel at 10,10 is of color <span class="hljs-subst">${color.join(", ")}</span>.`</span>); </code></pre> <h5 id="example-for-a-rgb-image-">Example for a rgb image:</h5> <pre><code class="lang-typescript"><span class="hljs-keyword">const</span> image = readPngFileSync(<span class="hljs-string">"path/to/rgb-image.png"</span>); <span class="hljs-keyword">const</span> color = image.at(<span class="hljs-number">10</span>, <span class="hljs-number">10</span>); <span class="hljs-keyword">const</span> colorType = image.colorType; <span class="hljs-comment">// Will log: "The color type of the image is rgb. Pixel at 10,10 is of color 100, 150, 200."</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`The color type of the image is <span class="hljs-subst">${colorType}</span>. Pixel at 10,10 is of color <span class="hljs-subst">${color.join(", ")}</span>.`</span>); </code></pre> <p>Dealing with all of these different color formats can be quite irritating. A set of conversion utilities as for example a utility for converting any color format to rgba (<a href="https://prior99.github.io/node-libpng/docs/globals.html#converttorgba">convertToRGBA</a>) exist.</p> <p><a href="#accessing-in-rgba-format">It is also possible to do this automatically</a>.</p> <h4 id="accessing-in-rgba-format">Accessing in rgba format</h4> <p>A method for retrieving the automatically converted color exists: <a href="https://prior99.github.io/node-libpng/docs/classes/pngimage.html#rgbaat">PngImage.rgbaAt</a>.</p> <p>It will convert any color into rgba format. Unlike <a href="https://www.npmjs.com/package/pngjs#pngjs">other implementations</a>, all color formats are supported.</p> <pre><code class="lang-typescript"><span class="hljs-keyword">const</span> image = readPngFileSync(<span class="hljs-string">"path/to/any-color-format-image.png"</span>); <span class="hljs-keyword">const</span> color = image.rgbaAt(<span class="hljs-number">10</span>, <span class="hljs-number">10</span>); <span class="hljs-keyword">const</span> colorType = image.colorType; <span class="hljs-comment">// Will log: "The color type of the image is palette. Pixel at 10,10 is of color 100, 150, 200, 255."</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`The color type of the image is <span class="hljs-subst">${colorType}</span>. Pixel at 10,10 is of color <span class="hljs-subst">${color.join(", ")}</span>.`</span>); </code></pre> <h3 id="modifying-the-image">Modifying the image</h3> <p>Several basic utilities for modifying an image exist.</p> <h4 id="cropping">Cropping</h4> <p>A simple utility for cropping an image to a sub-rectangle exists: <a href="https://prior99.github.io/node-libpng/docs/classes/pngimage.html#crop">PngImage.crop</a>. It&#39;s a simplified version of <a href="https://prior99.github.io/node-libpng/docs/classes/pngimage.html#resizecanvas">PngImage.resizeCanvas</a>.</p> <p>It will reduce the image in-place to the specified rectangle:</p> <pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { readPngFileSync, rect } <span class="hljs-keyword">from</span> <span class="hljs-string">"node-libpng"</span>; <span class="hljs-keyword">const</span> image = readPngFileSync(<span class="hljs-string">"path/to/image.png"</span>); image.crop(rect(<span class="hljs-number">10</span>, <span class="hljs-number">10</span>, <span class="hljs-number">100</span>, <span class="hljs-number">100</span>)); <span class="hljs-comment">// Will log: "New dimensions: 100x100".</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`New dimensions: <span class="hljs-subst">${image.width}</span>x<span class="hljs-subst">${image.height}</span>.`</span>); </code></pre> <h4 id="resizing-the-canvas">Resizing the canvas</h4> <p>Use <a href="https://prior99.github.io/node-libpng/docs/classes/pngimage.html#resizecanvas">PngImage.resizeCanvas</a> for advanced cropping operations.</p> <p>Take a look at <a href="https://prior99.github.io/node-libpng/docs/interfaces/resizecanvasarguments.html">ResizeCanvasArguments</a>.</p> <p>It takes a configuration object which makes it possible to provide:</p> <ul> <li>An offset to the top left (a padding).</li> <li>A fill color for uncovered regions.</li> <li>A subrectangle of the image to use.</li> <li>The new dimensions for the image.</li> </ul> <p>In the following example, a 10 pixel margin is applied to the top and to the left and a 50x50 pixel area is copied from the image at offset 20,20. The image is resized to 100x100, so a 40 pixel margin will exist to the right and to the bottom. The background is filled in red:</p> <pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { readPngFileSync, rect, xy, colorRGB } <span class="hljs-keyword">from</span> <span class="hljs-string">"node-libpng"</span>; <span class="hljs-keyword">const</span> image = readPngFileSync(<span class="hljs-string">"path/to/image.png"</span>); image.resizeCanvas({ offset: xy(<span class="hljs-number">10</span>, <span class="hljs-number">10</span>), clip: rect(<span class="hljs-number">20</span>, <span class="hljs-number">20</span>, <span class="hljs-number">50</span>, <span class="hljs-number">50</span>), dimensions: xy(<span class="hljs-number">100</span>, <span class="hljs-number">100</span>), fillColor: colorRGB(<span class="hljs-number">255</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>), }); <span class="hljs-comment">// Will log: "New dimensions: 100x100".</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`New dimensions: <span class="hljs-subst">${image.width}</span>x<span class="hljs-subst">${image.height}</span>.`</span>); </code></pre> <h4 id="copying-an-image-into-another-image">Copying an image into another image</h4> <p>Use <a href="https://prior99.github.io/node-libpng/docs/classes/pngimage.html#copyfrom">PngImage.copyFrom</a> to copy an area of one image into another one:</p> <pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { readPngFileSync, xy, rect } <span class="hljs-keyword">from</span> <span class="hljs-string">"node-libpng"</span>; <span class="hljs-keyword">const</span> source = readPngFileSync(<span class="hljs-string">"path/to/source-image.png"</span>); <span class="hljs-keyword">const</span> target = readPngFileSync(<span class="hljs-string">"path/to/target-image.png"</span>); target.copyFrom(source, xy(<span class="hljs-number">10</span>, <span class="hljs-number">10</span>), rect(<span class="hljs-number">100</span>, <span class="hljs-number">100</span>, <span class="hljs-number">50</span>, <span class="hljs-number">50</span>)); </code></pre> <p>The above example will copy a 50x50 rectangle from the source image at position 100,100 to the target image at position 10,10. The offset and the subrectangle can be omitted to copy the whole source image to the top left corner of the target image.</p> <h4 id="filling-an-area-with-a-specified-color">Filling an area with a specified color</h4> <p>Use <a href="https://prior99.github.io/node-libpng/docs/classes/pngimage.html#fill">PngImage.fill</a> to fill an area with a specified color:</p> <pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { readPngFileSync, colorRGB, rect } <span class="hljs-keyword">from</span> <span class="hljs-string">"node-libpng"</span>; <span class="hljs-keyword">const</span> image = readPngFileSync(<span class="hljs-string">"path/to/source-image.png"</span>); <span class="hljs-comment">// Change a 100x100 pixel area at offset 10,10 to red:</span> image.fill(colorRGB(<span class="hljs-number">255</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>), rect(<span class="hljs-number">10</span>, <span class="hljs-number">10</span>, <span class="hljs-number">100</span>, <span class="hljs-number">100</span>)); </code></pre> <h4 id="setting-a-single-pixel">Setting a single pixel</h4> <p>With <a href="https://prior99.github.io/node-libpng/docs/classes/pngimage.html#set">PngImage.set</a> an individual pixel&#39;s color can be changed:</p> <pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { readPngFileSync, colorRGB, xy } <span class="hljs-keyword">from</span> <span class="hljs-string">"node-libpng"</span>; <span class="hljs-keyword">const</span> image = readPngFileSync(<span class="hljs-string">"path/to/source-image.png"</span>); <span class="hljs-comment">// Change the pixel at 10,10 to red:</span> image.set(colorRGB(<span class="hljs-number">255</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>), xy(<span class="hljs-number">10</span>, <span class="hljs-number">10</span>)); </code></pre> <h2 id="benchmark">Benchmark</h2> <p>As it is a native addon, <strong>node-libpng</strong> is much faster than libraries like <a href="https://www.npmjs.com/package/pngjs">pngjs</a>:</p> <h3 id="read-access-decoding-">Read access (Decoding)</h3> <p>The chart below shows the comparison of decoding an image between <a href="https://www.npmjs.com/package/pngjs">pngjs</a> (sync api) and <strong>node-libpng</strong>. The time to fully decode a 4096x4096 image is measured (Higher is better).</p> <p><img src="images/benchmark-read.png" alt="read benchmark"></p> <p><em>(The x-axis scale shows the amount of fully decoded images per second.)</em></p> <h3 id="write-access-encoding-">Write access (Encoding)</h3> <p>The chart below shows the comparison of encoding an image between <a href="https://www.npmjs.com/package/pngjs">pngjs</a> (sync api) and <strong>node-libpng</strong>. The time to fully encode a 4096x4096 image is measured (Higher is better).</p> <p><img src="images/benchmark-encode.png" alt="access benchmark"></p> <p><em>(The x-axis scale shows the amount of fully encoded images per second.)</em></p> <h3 id="pixel-access">Pixel Access</h3> <p>The chart below shows the comparison of accessing all pixels in a decoded image between <a href="https://www.npmjs.com/package/pngjs">pngjs</a> and <strong>node-libpng</strong>. The time to fully access every pixel in the raw data is measured (Higher is better).</p> <p><img src="images/benchmark-access.png" alt="access benchmark"></p> <p><em>(The x-axis scale shows the amount of fully accessed images per second.)</em></p> <h2 id="contributing">Contributing</h2> <p>Yarn is used instead of npm, so make sure it is installed, probably: <code>npm install -g yarn</code>.</p> <p>Generally, it should be enough to just run:</p> <pre><code><span class="hljs-attribute">make</span> </code></pre><p>which will install all node dependencies, compile the dependencies and C++ code, compile typescript, execute all test, lint the sources and build the docs.</p> <h3 id="generating-the-libpng-config">Generating the libpng config</h3> <p>Libpng requires an OS specific configuration headerfile <code>pnglibconf.h</code>. This can be generated by executing:</p> <pre><code>git submodule update <span class="hljs-params">--init</span> <span class="hljs-params">--recursive</span> <span class="hljs-keyword">cd</span> deps/libpng mkdir build <span class="hljs-keyword">cd</span> build cmake <span class="hljs-string">..</span> make cp pnglibconf.h <span class="hljs-string">../../config/linux/</span> </code></pre><h2 id="contributors">Contributors</h2> <ul> <li>Frederick Gnodtke</li> </ul> </div> </div> <div class="col-4 col-menu menu-sticky-wrap menu-highlight"> <nav class="tsd-navigation primary"> <ul> <li class="globals "> <a href="globals.html"><em>Globals</em></a> </li> </ul> </nav> <nav class="tsd-navigation secondary menu-sticky"> <ul class="before-current"> <li class=" tsd-kind-enum"> <a href="enums/colortype.html" class="tsd-kind-icon">Color<wbr>Type</a> </li> <li class=" tsd-kind-enum"> <a href="enums/interlacetype.html" class="tsd-kind-icon">Interlace<wbr>Type</a> </li> <li class=" tsd-kind-class"> <a href="classes/pngimage.html" class="tsd-kind-icon">Png<wbr>Image</a> </li> <li class=" tsd-kind-interface"> <a href="interfaces/encodeoptions.html" class="tsd-kind-icon">Encode<wbr>Options</a> </li> <li class=" tsd-kind-interface"> <a href="interfaces/resizecanvasarguments.html" class="tsd-kind-icon">Resize<wbr>Canvas<wbr>Arguments</a> </li> <li class=" tsd-kind-type-alias"> <a href="globals.html#colorany" class="tsd-kind-icon">Color<wbr>Any</a> </li> <li class=" tsd-kind-type-alias"> <a href="globals.html#colorgrayscale" class="tsd-kind-icon">Color<wbr>Gray<wbr>Scale</a> </li> <li class=" tsd-kind-type-alias"> <a href="globals.html#colorgrayscalealpha" class="tsd-kind-icon">Color<wbr>Gray<wbr>Scale<wbr>Alpha</a> </li> <li class=" tsd-kind-type-alias"> <a href="globals.html#colornoalpha" class="tsd-kind-icon">Color<wbr>NoAlpha</a> </li> <li class=" tsd-kind-type-alias"> <a href="globals.html#colorpalette" class="tsd-kind-icon">Color<wbr>Palette</a> </li> <li class=" tsd-kind-type-alias"> <a href="globals.html#colorrgb" class="tsd-kind-icon">ColorRGB</a> </li> <li class=" tsd-kind-type-alias"> <a href="globals.html#colorrgba" class="tsd-kind-icon">ColorRGBA</a> </li> <li class=" tsd-kind-type-alias"> <a href="globals.html#palette" class="tsd-kind-icon">Palette</a> </li> <li class=" tsd-kind-type-alias"> <a href="globals.html#readpngfilecallback" class="tsd-kind-icon">Read<wbr>Png<wbr>File<wbr>Callback</a> </li> <li class=" tsd-kind-type-alias"> <a href="globals.html#rect" class="tsd-kind-icon">Rect</a> </li> <li class=" tsd-kind-type-alias"> <a href="globals.html#writepngfilecallback" class="tsd-kind-icon">Write<wbr>Png<wbr>File<wbr>Callback</a> </li> <li class=" tsd-kind-type-alias"> <a href="globals.html#xy" class="tsd-kind-icon">XY</a> </li> <li class=" tsd-kind-variable"> <a href="globals.html#__native_pngimage" class="tsd-kind-icon">__native_<wbr><wbr>Png<wbr>Image</a> </li> <li class=" tsd-kind-variable"> <a href="globals.html#__native_copy" class="tsd-kind-icon">__native_<wbr>copy</a> </li> <li class=" tsd-kind-variable"> <a href="globals.html#__native_encode" class="tsd-kind-icon">__native_<wbr>encode</a> </li> <li class=" tsd-kind-variable"> <a href="globals.html#__native_fill" class="tsd-kind-icon">__native_<wbr>fill</a> </li> <li class=" tsd-kind-variable"> <a href="globals.html#__native_ispng" class="tsd-kind-icon">__native_<wbr>is<wbr>Png</a> </li> <li class=" tsd-kind-variable"> <a href="globals.html#__native_resize" class="tsd-kind-icon">__native_<wbr>resize</a> </li> <li class=" tsd-kind-function"> <a href="globals.html#colorgrayscale" class="tsd-kind-icon">color<wbr>Gray<wbr>Scale</a> </li> <li class=" tsd-kind-function"> <a href="globals.html#colorgrayscalealpha" class="tsd-kind-icon">color<wbr>Gray<wbr>Scale<wbr>Alpha</a> </li> <li class=" tsd-kind-function"> <a href="globals.html#colorpalette" class="tsd-kind-icon">color<wbr>Palette</a> </li> <li class=" tsd-kind-function"> <a href="globals.html#colorrgb" class="tsd-kind-icon">colorRGB</a> </li> <li class=" tsd-kind-function"> <a href="globals.html#colorrgba" class="tsd-kind-icon">colorRGBA</a> </li> <li class=" tsd-kind-function"> <a href="globals.html#colortypetocolorchecker" class="tsd-kind-icon">color<wbr>Type<wbr>ToColor<wbr>Checker</a> </li> <li class=" tsd-kind-function"> <a href="globals.html#convertgrayscalealphatorgba" class="tsd-kind-icon">convert<wbr>Gray<wbr>Scale<wbr>Alpha<wbr>ToRGBA</a> </li> <li class=" tsd-kind-function"> <a href="globals.html#convertgrayscaletorgba" class="tsd-kind-icon">convert<wbr>Gray<wbr>Scale<wbr>ToRGBA</a> </li> <li class=" tsd-kind-function"> <a href="globals.html#convertnativebackgroundcolor" class="tsd-kind-icon">convert<wbr>Native<wbr>Background<wbr>Color</a> </li> <li class=" tsd-kind-function tsd-is-not-exported"> <a href="globals.html#convertnativepalette" class="tsd-kind-icon">convert<wbr>Native<wbr>Palette</a> </li> <li class=" tsd-kind-function"> <a href="globals.html#convertnativetime" class="tsd-kind-icon">convert<wbr>Native<wbr>Time</a> </li> <li class=" tsd-kind-function"> <a href="globals.html#convertpalettetorgba" class="tsd-kind-icon">convert<wbr>Palette<wbr>ToRGBA</a> </li> <li class=" tsd-kind-function"> <a href="globals.html#convertrgbtorgba" class="tsd-kind-icon">convertRGBToRGBA</a> </li> <li class=" tsd-kind-function"> <a href="globals.html#converttorgba" class="tsd-kind-icon">convert<wbr>ToRGBA</a> </li> <li class=" tsd-kind-function"> <a href="globals.html#decode" class="tsd-kind-icon">decode</a> </li> <li class=" tsd-kind-function"> <a href="globals.html#defaultbackgroundcolor" class="tsd-kind-icon">default<wbr>Background<wbr>Color</a> </li> <li class=" tsd-kind-function"> <a href="globals.html#encode" class="tsd-kind-icon">encode</a> </li> <li class=" tsd-kind-function"> <a href="globals.html#expecteverypixel" class="tsd-kind-icon">expect<wbr>Every<wbr>Pixel</a> </li> <li class=" tsd-kind-function"> <a href="globals.html#expectredbluegradient" class="tsd-kind-icon">expect<wbr>Red<wbr>Blue<wbr>Gradient</a> </li> <li class=" tsd-kind-function"> <a href="globals.html#iscolorgrayscale" class="tsd-kind-icon">is<wbr>Color<wbr>Gray<wbr>Scale</a> </li> <li class=" tsd-kind-function"> <a href="globals.html#iscolorgrayscalealpha" class="tsd-kind-icon">is<wbr>Color<wbr>Gray<wbr>Scale<wbr>Alpha</a> </li> <li class=" tsd-kind-function"> <a href="globals.html#iscolorpalette" class="tsd-kind-icon">is<wbr>Color<wbr>Palette</a> </li> <li class=" tsd-kind-function"> <a href="globals.html#iscolorrgb" class="tsd-kind-icon">is<wbr>ColorRGB</a> </li> <li class=" tsd-kind-function"> <a href="globals.html#iscolorrgba" class="tsd-kind-icon">is<wbr>ColorRGBA</a> </li> <li class=" tsd-kind-function"> <a href="globals.html#ispng" class="tsd-kind-icon">is<wbr>Png</a> </li> <li class=" tsd-kind-function"> <a href="globals.html#isrect" class="tsd-kind-icon">is<wbr>Rect</a> </li> <li class=" tsd-kind-function"> <a href="globals.html#isxy" class="tsd-kind-icon">isXY</a> </li> <li class=" tsd-kind-function"> <a href="globals.html#readpngfile" class="tsd-kind-icon">read<wbr>Png<wbr>File</a> </li> <li class=" tsd-kind-function"> <a href="globals.html#readpngfilesync" class="tsd-kind-icon">read<wbr>Png<wbr>File<wbr>Sync</a> </li> <li class=" tsd-kind-function"> <a href="globals.html#rect" class="tsd-kind-icon">rect</a> </li> <li class=" tsd-kind-function"> <a href="globals.html#writepngfile" class="tsd-kind-icon">write<wbr>Png<wbr>File</a> </li> <li class=" tsd-kind-function"> <a href="globals.html#writepngfilesync" class="tsd-kind-icon">write<wbr>Png<wbr>File<wbr>Sync</a> </li> <li class=" tsd-kind-function"> <a href="globals.html#xy" class="tsd-kind-icon">xy</a> </li> </ul> </nav> </div> </div> </div> <footer class="with-border-bottom"> <div class="container"> <h2>Legend</h2> <div class="tsd-legend-group"> <ul class="tsd-legend"> <li class="tsd-kind-module"><span class="tsd-kind-icon">Module</span></li> <li class="tsd-kind-object-literal"><span class="tsd-kind-icon">Object literal</span></li> <li class="tsd-kind-variable"><span class="tsd-kind-icon">Variable</span></li> <li class="tsd-kind-function"><span class="tsd-kind-icon">Function</span></li> <li class="tsd-kind-function tsd-has-type-parameter"><span class="tsd-kind-icon">Function with type parameter</span></li> <li class="tsd-kind-index-signature"><span class="tsd-kind-icon">Index signature</span></li> <li class="tsd-kind-type-alias"><span class="tsd-kind-icon">Type alias</span></li> </ul> <ul class="tsd-legend"> <li class="tsd-kind-enum"><span class="tsd-kind-icon">Enumeration</span></li> <li class="tsd-kind-enum-member"><span class="tsd-kind-icon">Enumeration member</span></li> <li class="tsd-kind-property tsd-parent-kind-enum"><span class="tsd-kind-icon">Property</span></li> <li class="tsd-kind-method tsd-parent-kind-enum"><span class="tsd-kind-icon">Method</span></li> </ul> <ul class="tsd-legend"> <li class="tsd-kind-interface"><span class="tsd-kind-icon">Interface</span></li> <li class="tsd-kind-interface tsd-has-type-parameter"><span class="tsd-kind-icon">Interface with type parameter</span></li> <li class="tsd-kind-constructor tsd-parent-kind-interface"><span class="tsd-kind-icon">Constructor</span></li> <li class="tsd-kind-property tsd-parent-kind-interface"><span class="tsd-kind-icon">Property</span></li> <li class="tsd-kind-method tsd-parent-kind-interface"><span class="tsd-kind-icon">Method</span></li> <li class="tsd-kind-index-signature tsd-parent-kind-interface"><span class="tsd-kind-icon">Index signature</span></li> </ul> <ul class="tsd-legend"> <li class="tsd-kind-class"><span class="tsd-kind-icon">Class</span></li> <li class="tsd-kind-class tsd-has-type-parameter"><span class="tsd-kind-icon">Class with type parameter</span></li> <li class="tsd-kind-constructor tsd-parent-kind-class"><span class="tsd-kind-icon">Constructor</span></li> <li class="tsd-kind-property tsd-parent-kind-class"><span class="tsd-kind-icon">Property</span></li> <li class="tsd-kind-method tsd-parent-kind-class"><span class="tsd-kind-icon">Method</span></li> <li class="tsd-kind-accessor tsd-parent-kind-class"><span class="tsd-kind-icon">Accessor</span></li> <li class="tsd-kind-index-signature tsd-parent-kind-class"><span class="tsd-kind-icon">Index signature</span></li> </ul> <ul class="tsd-legend"> <li class="tsd-kind-constructor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited constructor</span></li> <li class="tsd-kind-property tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited property</span></li> <li class="tsd-kind-method tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited method</span></li> <li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited accessor</span></li> </ul> <ul class="tsd-legend"> <li class="tsd-kind-property tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected property</span></li> <li class="tsd-kind-method tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected method</span></li> <li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected accessor</span></li> </ul> <ul class="tsd-legend"> <li class="tsd-kind-property tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private property</span></li> <li class="tsd-kind-method tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private method</span></li> <li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private accessor</span></li> </ul> <ul class="tsd-legend"> <li class="tsd-kind-property tsd-parent-kind-class tsd-is-static"><span class="tsd-kind-icon">Static property</span></li> <li class="tsd-kind-call-signature tsd-parent-kind-class tsd-is-static"><span class="tsd-kind-icon">Static method</span></li> </ul> </div> </div> </footer> <div class="container tsd-generator"> <p>Generated using <a href="http://typedoc.org/" target="_blank">TypeDoc</a></p> </div> <div class="overlay"></div> <script src="assets/js/main.js"></script> <script>if (location.protocol == 'file:') document.write('<script src="assets/js/search.js"><' + '/script>');</script> </body> </html>