Getting Started
Installation
Install from npm:
npm i @alxcube/lens
To use in node you will need Jimp library and Lens-Jimp adapter:
npm i jimp @alxcube/lens-jimp
Import
Browser
Lens is distributed in ES module format and in UMD format.
If you are using bundler, you can import library components from @alxcube/lens
:
import { distort } from "@alxcube/lens";
If not using bundlers, you can import directly from Lens ES module:
import { distort } from "path/to/lens.js";
Or you can load UMD version, so lens will be available in global namespace as 'lens':
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<script type="text/javascript" src="path/to/lens.umd.cjs"></script>
<script>
console.log(lens.VERSION);
const image = lens.Canvas.createFromUrl("path/to/image.png").then(
(image) => lens.distort(image, "Arc", [90])
);
// ...
</script>
</body>
</html>
Node.js
Lens can be imported in Node as ES module and as CommonJS module:
import { distort } from "@alxcube/lens";
const { distort } = require("@alxcube/lens");
Usage
Hello World
Here is basic example of how you can use lens to distort image using Arc distortion:
import { Canvas, distort, toHTMLCanvasElement } from "@alxcube/lens";
// create image adapter for source image
const image = await Canvas.createFromUrl("path/to/source-image.png");
// distort image
const distortionResult = await distort(image, "Arc", [180]);
// get underlying OffscreenCanvas
const canvas = distortionResult.image.getResource();
// convert OffscreenCanvas to HTMLCanvasElement to be able to insert it in DOM
const canvasElement = toHTMLCanvasElement(canvas);
// display result
document.body.appendChild(canvasElement);
import { Adapter } from "@alxcube/lens-jimp";
import { distort } from "@alxcube/lens";
// create image adapter for source image
const image = await Adapter.createFromFile("path/to/image.png");
// distort image
const distortionResult = await distort(image, "Arc", [180]);
// get underlying Jimp instance
const jimpImage = distortionResult.image.getResource();
// save result
jimpImage.write("path/to/result.png");
Passing image resources directly to distort()
In previous example we used adapter static methods for image adapter creation. But you can pass image resources directly to distort()
function. Internally they will be wrapped in corresponding adapter interface.
In browser, you can pass instance of HTMLCanvasElement
or OffscreenCanvas
to distort()
.
INFO
Underlying resource type of result image matches that of source image. That means, if you pass HTMLCanvasElement
to distort()
, result image getResource()
method will also return instance of HTMLCanvasElement
. And if you pass OffscreenCanvas
, result resource will be OffscreenCanvas
too.
import { distort, preloadHtmlImage } from "@alxcube/lens";
// load image by url
const image: HTMLImageElement = await preloadHtmlImage("path/to/image.png");
// draw image on canvas
const canvas: HTMLCanvasElement = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
canvas.getContext("2d").drawImage(image, 0, 0);
// distort image
const result = await distort(canvas, "Arc", [180]);
To make such approach work in Node, you should import @alxcube/lens-jimp
for side effect. It will register Jimp adapter factory in Lens ImageAdapter
factories pool, and then you will be able to pass Jimp instances to distort()
function. This only need to be done once, so you can put this import somewhere in your app initialization module.
import "@alxcube/lens-jimp"; // import for side effect
import jimp from "jimp";
import { distort } from "@alxcube/lens";
// load image file
const image = await Jimp.read("path/to/image.png");
// distort image
const result = await distort(image, "Arc", [180]);
Distortion Result
The distort()
function returns DistortionResult
interface, which is plain object with following fields:
image
-ImageAdapter
interface object with distorted image.distortion
-ReversePixelMapper
interface instance, which was used for distortion. You can use it for inspecting specific distortion coefficients, calculated internally, or for reusing for similar distortion of other image, sincedistort()
also acceptsReversePixelMapper
instance instead distortion name and distortion arguments.startTimestamp
- timestamp of distortion processing start.endTimestamp
- timestamp of distortion processing end.duration
- duration of distortion process in milliseconds.weightLookupTable
- this property is added only if EWA resampling was used, and contains color weight values, calculated by resample filter. It is unlikely that you ever need this property.
ImageAdapter
in distortion result holds image virtual viewport which is required for correct composition of multiple distorted images, or may be used for further image distortions. If all this stuff is redundant for your use case, you can replace distort()
function to distortUnwrap()
, which accepts same arguments, but returns unwrapped underlying image resource:
import { distortUnwrap } from "@alxcube/lens";
const image = new OffscreenCanvas(100, 100);
// ... draw something on canvas
// distort image and get distorted image canvas
const resultOffscreenCanvas = await distortUnwrap(image, "Arc", [180]);
// this is equal to:
// const { image: resultImage } = await distort(image, "Arc", [180]);
// const resultOffscreenCanvas = await resultImage.getResource();