SkillAgentSearch skills...

Downscale

Better image downscale with canvas.

Install / Use

/learn @ytiurin/Downscale

README

Better image downscale with canvas (demo)

This function downscales images in the browser, producing a better quality result, than the traditional CanvasRenderingContext2D.scale() method. It neutralises the "fuzzy" look caused by the native canvas downsampling, when processing relatively large images like photos taken with a smartphone. Check the demo page.

Better image downscale demo

Motivation

While other image resizing libraries are based on complex interpolation algorithms such as Lanczos resampling, image downscaling usually doesn't require that complexity, because there is no interpolation happening (in other words we don't create new pixels).

On the other hand, browsers implement very fast HTMLCanvasElement downsampling, when the pixel from source position is directly transfered to the destination position, loosing all the neighbouring pixels information. The resulting image may often look very noisy.

To resolve this problem, the proposed function does a simple area-average downsampling, producing preferable results with relatively small processing time.

Performance

This function uses the technique, proposed by Paul Rouget in his article about pixel manipulation with Typed Arrays. His method reduces the number of read/write operations to the ArrayBuffer of the ImageData returned by the CanvasRenderingContext2D.getImageData() method. This saves overall processing time when you want to iterate through every pixel of the source image.

Also, the usage of Math.round() method is avoided in favour of Bitwise operators, giving a significant boost in performance in some browsers.

Image cropping

Image cropping is very often used in pair with resizing, but both can be very naturally combined. As we don't need to iterate through pixels in cropped areas, the function does both downscaling and cropping in range of the same processing loop. This saves some memory and processing time.

By default, the source image is cropped in the way, that the center of the source image is transfered to the resulting image.

Rollback to canvas resizing

The function also uses basic canvas resizing method when the scale factor of the resulting image is greater than 0.5x. So the better downscaling happen only when the resulting image is at least 2 times smaller than the initial image. In other cases basic canvas resizing gives better image quality result.

Install

npm install downscale

Syntax

Promise<DOMString> downscale(source, width, height[, options]);

Parameters

<dl> <dt>source</dt> <dd> Defines the source of the image data to downscale. This can either be: <ul> <li> A <a href="https://developer.mozilla.org/en-US/docs/Web/API/File" title="The File interface provides information about files and allows JavaScript in a web page to access their content."><code>File</code></a> object, contained by the <a href="https://developer.mozilla.org/en-US/docs/Web/API/FileList" title="An object of this type is returned by the files property of the HTML <input> element; this lets you access the list of files selected with the <input type=&quot;file&quot;> element. It's also used for a list of files dropped into web content when using the drag and drop API; see the DataTransfer object for details on this usage."><code>FileList</code></a>, returned by the <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement#files_prop" title="The HTMLInputElement interface provides special properties and methods for manipulating the layout and presentation of input elements.">HTMLInputElement.files</a></code> property. </li> <li> A <code><a title="The HTMLVideoElement interface provides special properties and methods for manipulating video objects. It also inherits properties and methods of HTMLMediaElement and HTMLElement." href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement">HTMLImageElement</a></code> with the <code><a title="The image URL. This attribute is mandatory for the <img> element." href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-src">src</a></code> HTML attribute, containing the full URL to the source image. </li> <li> A <a title="The HTMLVideoElement interface provides special properties and methods for manipulating video objects. It also inherits properties and methods of HTMLMediaElement and HTMLElement." href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement"><code>HTMLVideoElement</code></a> in any state. </li> <li> A <a title="DOMString is a UTF-16 String. As JavaScript already uses such strings, DOMString is mapped directly to a String." href="https://developer.mozilla.org/en-US/docs/Web/API/DOMString"><code>DOMString</code></a> representing the URL to the source image. </li> </ul> </dd> <dt>width</dt> <dd>A <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number" title="The Number JavaScript object is a wrapper object allowing you to work with numerical values. A Number object is created using the Number() constructor."><code>Number</code></a> indicating width of the resulting image. If the value is <code>0</code>, the width is adapted to keep the same aspect ratio as in the source image.</dd> <dt>height</dt> <dd>A <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number" title="The Number JavaScript object is a wrapper object allowing you to work with numerical values. A Number object is created using the Number() constructor."><code>Number</code></a> indicating height of the resulting image. If the value is <code>0</code>, the height is adapted to keep the same aspect ratio as in the source image.</dd> <dt>options <sup>(optional)</sup></dt> <dd> An object with properties representing optional function parameters: <ul> <li> <dl> <dt>imageType</dt> <dd>A <a title="DOMString is a UTF-16 String. As JavaScript already uses such strings, DOMString is mapped directly to a String." href="https://developer.mozilla.org/en-US/docs/Web/API/DOMString"><code>DOMString</code></a> indicating image format. Possible values are <code>jpeg</code>, <code>png</code>, <code>webp</code>. The default format type is <code>jpeg</code>.</dd> </dl> </li> <li> <dl> <dt>quality</dt> <dd>A <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number" title="The Number JavaScript object is a wrapper object allowing you to work with numerical values. A Number object is created using the Number() constructor."><code>Number</code></a> between <code>0</cod
View on GitHub
GitHub Stars104
CategoryProject
Updated24d ago
Forks16

Languages

JavaScript

Security Score

100/100

Audited on Mar 5, 2026

No findings