JavaScript Canvas - Introduction To Bitmaps
Written by Ian Elliot   
Monday, 29 June 2020
Article Index
JavaScript Canvas - Introduction To Bitmaps
Async Loading
Drawing an Image

Drawing an Image

The first of the Canvas bitmap operations that we need to look at is the drawImage method, which draws a bitmap onto a canvas. What is interesting about this method is not so much that it provides a link between a bitmap and the canvas object, but the range of bitmap sources that can be used.

The source for a bitmap can either be a bitmap object, another canvas object or a video object. Notice that if you are using a canvas object as the source of the bitmap you have to have actually drawn something on it first and you have to use the canvas object not the drawing context - see later for an example. If you use a video object then the current frame is rendered to the canvas.

To start with the simplest example, you can take any standard Image object and draw it to the canvas. You can derive your image object from the DOM or create it directly within JavaScript. For example, suppose the page contains an image in img then you can then display it on the canvas, with the 2D drawing context stored in ctx using:

ctx.drawImage(img,10, 10);

The drawImage method takes a number of different parameters, but:

drawImage(image,x,y)

simply draws as much of the image as can fit on the canvas with its top left corner at x,y:

jeep2
The complete program is:

async function getImage(url) {
    var img = new Image();
    img.src = url;
    await imgLoaded(img);
    var ctx = document.body.appendChild(
createCanvas(600, 600)). getContext("2d"); ctx.drawImage(img,10, 10); } var img1 = getImage("jeep.jpg")

and makes use of imgLoaded given in the previous section.

If you want to scale the image then use the alternative form of the drawImage method:

drawImage(image,x,y,w,h);

where w and h specify the width and height that the image is scaled to.

For example:

ctx.drawImage(img,10,10,300,300);

jeep3
The problem here is that you might well distort the bitmap by scaling it unequally in the x and y directions. The solution is to use the object's img.width and img.height properties:

ctx.drawImage(img,10,10,img.width/4,img.height/4);

Notice that if you don't specify a width and height when you create the image then these are set to the naturalWidth and naturalHeight properties.

jeep4

The final form of the drawImage method gives you complete control over the way the image is drawn:

drawImage(image,sx,sy,sw,sh,dx,dy,dw,dh)

This looks complicated, but it simply specifies the location of a source and a destination rectangle. The source rectangle has its top left corner at sx,sy and is sw wide and sh high. The destination rectangle has its top left corner at dx,dy and is dw wide and dh high. The drawImage copies pixels in the source rectangle to the destination rectangle, performing any scaling that is needed. For example, to display the area of the bitmap cropped and scaled to show the jeep you would use:

ctx.drawImage(img,900,600,img.width/1.5,img.height/1.5,
0,0,img.width/8,img.height/8);

jeep5
Notice that both the source and destination rectangles are scaled versions of the full image size. If you want to avoid distortion, this is the usual method.

Finally you can use all three versions of the drawImage method with another canvas object as the source of the bitmap. For example:

ctx2.drawImage(ctx.canvas,0,0);

will draw the contents of canvas onto the drawing context ctx2 of another canvas object.

You can also draw a canvas object onto itself. For example:

ctx.drawImage(ctx.canvas,0,0.200,200);

will copy the contents of the canvas object back onto itself in a 200 by 200 rectangle if ctx is the drawing context of the canvas object. Notice that the source bitmap is copied before it is drawn back to the canvas so there are no strange interactions between source and destination.

So to summarize:

There are three drawImage methods:

  • drawImage(image,dx,dy)
  • drawImage(image,dx,dy,dw,dh)
  • drawImage(image,sx,sy,sw,sh,dx,dy,dw,dh)

 where image is either a canvas, video or an image object derived either from the DOM or constructed in JavaScript, and sx,sy,sw,sh define the source rectangle and dx,dy,dw,dh define the destination rectangle.

In chapter but not in this extract:

  • ImageBitmap
  • Animation
  • Draw or BitBlt?
  • The Problem of Speed
  • Position, Speed & Acceleration
  • Using BitBlt
  • Raw Animation

Summary

  • The fundamental way of getting bitmaps into a web page is to use the <img> tag or the Image object.

  • Loading an image is always asynchronous. There is no way to pause and wait for an image to load, no matter how hard you try.

  • The only way to handle asynchronous image loading is to use the onload event handler.

  • A more modern approach is to wrap the event handler in a function that returns a Promise. The function can then be used with async/await to make the asynchronous operation look perfectly like a synchronous load.

  • Once you have an image loaded, you can use the drawImage method to draw the pixels to a canvas.

  • ImageBitmap is the new and faster way to source a bitmap for a canvas.

  • Animation can be achieved by repeated drawing of the animated object or by drawing a bitmap into a new location – BitBlt. In most cases blitting is faster.

  • You can arrange to take into account the time between frames to determine how far an object should have moved.

  • Animation is often best organized around the idea of a sprite, a shape with position, velocity and acceleration.

  • Sprites are perfect for implementation using object-oriented methods. Doing this loses about 1/3 of the speed you can achieve using a non-object-oriented, direct implementation.

 

Now available as a paperback or ebook from Amazon.

JavaScript Bitmap Graphics
With Canvas

largecover360

 

Contents

  1. JavaScript Graphics
  2. Getting Started With Canvas
  3. Drawing Paths
      Extract: Basic Paths
      Extract: SVG Paths
      Extract: Bezier Curves
  4. Stroke and Fill
      Extract: Stroke Properties 
      Extract: Fill and Holes
      Extract: Gradient & Pattern Fills
  5. Transformations
      Extract: Transformations
      Extract: Custom Coordinates 
      Extract  Graphics State
  6. Text
      Extract: Text, Typography & SVG 
      Extract: Unicode
  7. Clipping, Compositing and Effects
      Extract: Clipping & Basic Compositing
  8. Generating Bitmaps
      Extract:  Introduction To Bitmaps
      Extract :  Animation 
  9. WebWorkers & OffscreenCanvas
      Extract: Web Workers
      Extract: OffscreenCanvas
  10. Bit Manipulation In JavaScript
      Extract: Bit Manipulation
  11. Typed Arrays
      Extract: Typed Arrays 
  12. Files, blobs, URLs & Fetch
      Extract: Blobs & Files
      Extract: Read/Writing Local Files
      Extract: Fetch API **NEW!
  13. Image Processing
      Extract: ImageData
      Extract:The Filter API
  14. 3D WebGL
      Extract: WebGL 3D
  15. 2D WebGL
    Extract: WebGL Convolutions

<ASIN:B07XJQDS4Z>

<ASIN:1871962579>

<ASIN:1871962560>

To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.

espbook

 

Comments




or email your comment to: comments@i-programmer.info



Last Updated ( Monday, 29 June 2020 )