Page 1 of 2 Canvas has a filter API that often goes unnoticed because it has been inherited recently from SVG. In this extract from a chapter in my new book on JavaScript Graphics we look at how it works.
Now available as a paperback or ebook from Amazon.
JavaScript Bitmap Graphics With Canvas
Contents
- JavaScript Graphics
- Getting Started With Canvas
- Drawing Paths
Extract: Basic Paths Extract: SVG Paths Extract: Bezier Curves
- Stroke and Fill
Extract: Stroke Properties Extract: Fill and Holes Extract: Gradient & Pattern Fills
- Transformations
Extract: Transformations Extract: Custom Coordinates Extract Graphics State
- Text
Extract: Text, Typography & SVG Extract: Unicode
- Clipping, Compositing and Effects
Extract: Clipping & Basic Compositing
- Generating Bitmaps
Extract: Introduction To Bitmaps Extract : Animation
- WebWorkers & OffscreenCanvas
Extract: Web Workers Extract: OffscreenCanvas
- Bit Manipulation In JavaScript
Extract: Bit Manipulation
- Typed Arrays
Extract: Typed Arrays
- Files, blobs, URLs & Fetch
Extract: Blobs & Files Extract: Read/Writing Local Files Extract: Fetch API **NEW!
- Image Processing
Extract: ImageData Extract:The Filter API
- 3D WebGL
Extract: WebGL 3D
- 2D WebGL
Extract: WebGL Convolutions
<ASIN:B07XJQDS4Z>
<ASIN:1871962579>
<ASIN:1871962560>
In the early part of this book the emphasis was on creating graphics by drawing on the canvas. By contrast the latter part of the book is about loading graphics files into the canvas. Why would you want to do this as opposed to simply loading files into an Image object? If you only want to display the bitmaps then you should use an image object. The advantage of a canvas object is that you can manipulate the pixel values to change what is displayed. This is image processing and it is the subject of this chapter.
Included in book but not in this extract:
- Getting at the Pixels
- A Special Effects Filter
- A Security Problem
The Filter API
SVG has long had a set of filter functions and these are now being migrated to Canvas in the Filter API. Note, however, that not all browsers support the Filter API at the time of writing, in particular Safari and Opera don’t.
The basic idea is that you can set a list of filters on a context which modifies what you draw to it.
The basic filter method is:
ctx.filter = "filter1 ... filterN";
where the filters are any of:
-
none No filter is applied and this has the effect of removing filters.
-
url(url) - a url referencing an SVG filter element, see later.
-
blur(amount) Applies a Gaussian blur to the drawing with amount giving the standard deviation i.e. the extent of the blur. A value of 0 leaves the input unchanged.
-
brightness(percent) A value under 100% darkens the image, while a value over 100% brightens it. A value of 0% will create an image that is completely black, while a value of 100% leaves the input unchanged.
-
contrast(percent) Adjusts the contrast of the drawing. A value of 0% will create a drawing that is completely black. A value of 100% leaves the drawing unchanged.
-
grayscale(percentage) Converts the drawing to grayscale. A value of 100% is completely grayscale. A value of 0% leaves the drawing unchanged.
-
invert(percentage) Inverts the drawing. A value of 100% means complete inversion. A value of 0% leaves the drawing unchanged.
-
opacity(percentage) Applies transparency to the drawing. A value of 0% means completely transparent. A value of 100% leaves the drawing unchanged.
-
saturate(percentage) Saturates the drawing. A value of 0% means completely unsaturated. A value of 100% leaves the drawing unchanged.
-
sepia(percentage) Converts the drawing to sepia. A value of 100% means completely sepia. A value of 0% leaves the drawing unchanged.
-
hue-rotate(angle) Applies a hue rotation on the drawing. A value of 0 degrees leaves the input unchanged.
-
Drop-shadow() This function takes up to five arguments:
offset-x Specifies the horizontal distance of the shadow. offset-y Specifies the vertical distance of the shadow. Blur-radius The larger this value, the bigger the blur, so the shadow becomes bigger and lighter. Color CSS color specification
There isn’t much to say about using these specific filters – they are generally adjusted by trial and error and they either do what you want or they don’t. For example:
async function draw() {
var ctx = document.body.appendChild(createCanvas(400, 400)).
getContext("2d");
var img = new Image();
var url = new URL("jeep.jpg", "http://server/Filter/");
img.src = url;
await imgLoaded(img);
ctx.filter = "grayscale(100%)invert(75%)";
ctx.drawImage(img, 0, 0, 400, 300);
}
produces:
Notice that the range of filters that you can apply is limited but the url filter lets you use any filter that is defined or can be defined using SVG. You can find a complete list of SVG filters in the documentation and to use them you first define the SVG filter as if you were going to use it in an SVG drawing:
<feBlend>
<feColorMatrix>
<feComponentTransfer>
<feComposite>
<feConvolveMatrix>
<feDiffuseLighting>
<feDisplacementMap>
<feDropShadow>
<feFlood>
<feGaussianBlur>
<feImage>
<feMerge>
<feMorphology>
<feOffset>
<feSpecularLighting>
<feTile>
<feTurbulence>
For example to apply the SVG <feGaussianBlur> filter to a canvas:
<svg aria-hidden="true"en-US" style="width: 0; height: 0; overflow: hidden;"
ns="http://www.w3.org/2000/svg">
<filter id="blurMe">
<feGaussianBlur stdDeviation="5"/>
</filter>
</svg>
This has to be included in the body of the page. Notice that it doesn’t display anything. To use it in with Canvas you would simply write:
ctx.filter = "url(#blurMe)";
where the URL is a reference to the id. You could save the SVG in a separate file and use that as the URL.
|