Why don't we see more interactive and experimental plays with images, even as photos, videos and gifs fill the web? Perhaps working with images on html canvas is way harder than it should be — even a common use case, like loading an image and getting the color values of its pixels, proves to be practically tortuous.
Fret not! Pts'
Img provides some convenient and straightforward functions to help you experiment with images. Let's take a look.
Let's start a minimalistic example: Load an image and display it on canvas. This can be done in 3 lines of code:
const run = Pts.quickStart( "#elemID" ); const img = Img.load( "/assets/demo.jpg" ); run( t => form.image( space.pointer, img ) );
If you need to manually track when the image is loaded, you can either:
loadfunction and use
const img = new Img(); await img.load( "/assets/demo.jpg" )
Once the image is loaded, you can access its properties like width and height and manipulate its data. We will be discussing these advanced use cases next.
When you create an Img instance with its
editable parameter set to
true, it will hold an internal canvas to support image manipulations. It also supports higher pixel-density displays via the
pixelScale parameter. An example:
// Create an editable img with the current space's pixelScale let img = new Img( true, space.pixelScale ); img.load( "/assets/demo.jpg" ); // Alternatively, use the Img.load static function let img2 = Img.load( "/assets/demo.jpg", true, space.pixelScale );
With an editable image, you can now inspect and manipulate it creatively.
pixel function supports a very common use case: specify a pixel position on the image, get its RGBA color values, and do something with it. A wide range of visual possibilities may open up if you use this simple function creatively.
form.imageData( img.crop( bound ) );
Let's try this in a demo:
It's more efficient to draw
ImageData directly on canvas. If needed, you can also export it to a blob using
Img.imageDataToBlob and then load it into an image again.
After the image is loaded, you can access the canvas' rendering context through the property
img.ctx and then create a new
CanvasForm instance with it. For example:
let form; img.load( "demo.jpg" ).then( a => form = new CanvasForm(a.ctx) )
img.filter( "blur(10px) contrast(20%) saturate(0%)" )
To display the edited image, use CanvasForm's
image function but pass
img.canvas (instead of
img itself) in the parameter. As we are only editing an internal canvas, the original image is unchanged until it's explicitly updated. Use
sync to update the original image when needed.
Anticipate screens with different pixel density. You can pass a CanvasSpace's
pixelScale when creating an Img instance. (See example in Cheatsheet below)
Typically, you can't load an image from another domain due to security concerns. But if the image server allows for it and you want to do it, you can set the
crossOrigin parameter to
true when creating an
Img instance. More details here.
Creating, loading, displaying
// Simplest way let img = Img.load( "demo.jpg"); // Load an editable image that matches the screen's resolution // with an optional callback function when the image is loaded. let img = Img.load("demo.png", true, space.pixelScale, onLoad ); // Equivalent but using async/await let img = new Img( true, space.pixelScale ); await img.load("demo.png") // Display an image automatically when it's loaded form.image( [0,0], img ); // Check if image is loaded, then display its canvas in a rect if (img.loaded) form.image( rect, img.canvas );
img.loaded; // true if the image is loaded img.image; // the original image img.canvas; // the internal canvas of an editable Img img.ctx; // the context which can be used to create a CanvasForm
Editing an image
img.crop( rect ) img.resize( 0.5, true ); img.filter( "blur(10px) | contrast(200%)" ); img.pixel( space.pointer ); // Draw on image let imgForm = new CanvasForm( img.ctx ); imgForm.fill( "#f00" ).point( space.pointer, 20 ); // Export as base64 string img.toBase64();