one of the more fun features of the canvas is the ability to use images. these can be used to do dynamic photo compositing or used as backdrops of graphs etc. it's currently also the only way to add text to them (the specification does not contain any functions to draw text). external images can be used in any format supported by gecko (eg png, gif or jpeg format). other canvas elements on the same page can also be used as the source.
One of the interesting features of canvas is that it can introduce images, which can be used for image synthesis or background production, etc. Currently, only text can be added to images (the standard description does not include the function of drawing text). As long as the images supported by gecko (such as png, gif, jpeg, etc.) can be introduced into canvas, and other canvas elements can also be used as the source of the image.
importing images is basically a two step process:
Introducing an image requires only two simple steps:
let's look at step one first. there are basically four options available:
Let’s take a look at the first step first, there are basically four options:
we can access all images on a page by using either the document.images collection, the document.getelementsbytagname method, or if we know the id attribute of the image, the document.getelementbyid method.
We can get the image in the page (if the id of the image element is known) through the document.images collection, the document.getelementsbytagname method, or the document.getelementbyid method.
just as with normal images we access other canvas elements using either the document.getelementsbytagname method or the document.getelementbyid method. make sure you've drawn something to the source canvas before using it in your target canvas.
Similar to the image in the reference page, use the document.getelementsbytagname or document.getelementbyid methods to obtain other canvas elements. But what you should introduce is the ready canvas.
one of the more practical uses of this would be to use a second canvas element as a thumbnail view of the other larger canvas.
A common application is to make thumbnails for another large canvas.
<Another option is to create new image objects in our script. the main failure of this approach is that if we don't want our script to halt in the middle because it needs to wait for an image to load, we need some form of image preloading.
In addition, we can use scripts to create a new image object, but the main disadvantage of this method is that if we do not want the script to pause because we wait for the image device, we still need to break through preload.
Basically to create a new image object we do this:
We can create images in the following simple way:
var img = new image(); // create new image objectimg.src = 'myimage.png'; // set source path
When this script gets executed, the image starts loading. if loading isn't finished when a drawimage statement gets executed, the script halts until the image is finished loading. if you don't want this to happen, use an onload event handler:
When the script is executed, the image starts loading. If the picture is not loaded when calling drawimage, the script will wait until it is loaded. If you do not want this, you can use the onload event:
var img = new image(); // create new image objectimg.onload = function(){ // execute drawimage statements here}img.src = 'myimage.png'; // set source pathif you're only using one external image this can be a good approach but once you need to track more than one we need to resort to something more cunning. it's beyond the scope of this tutorial to look at image preloading tactics but you can check out javascript image preloader for a complete solution.
If you only use one picture, that's enough. But once more than one image is needed, a more complex processing method is required, but the image preloading strategy is beyond the scope of this tutorial. If you are interested, you can refer to the javascript image preloader.
Another possible way to include images is via the data: url. data urls allow you to completely define an image as a base64 encoded string of characters directly in your code. one advantage of data urls is that the resulting image is available immediately without another round trip to the server. ( another advantage is that it is then possible to encapsulate in one file all of your css, javascript, html, and images, making it more portable to other locations. ) some disadvantages of this method are that your image is not cached, and for larger images the encoded url can become quite long:
We can also reference images through the data: url method. data urls allows a picture to be defined in a string of base64-encoded strings. The advantage is that the image content is available immediately without having to go around the server again. (And another advantage is that it can encapsulate css, javascript, html and images together, which is very convenient to migrate.) The disadvantage is that the images cannot be cached. If the images are large, the embedded url data will be quite long:
var img_src = 'data:image/gif;base64,r0lgodlhcwalaiaaaaaaaaaa3pn/zih5baeaaaaeaalaaaaaaaaaaaaaaaaaaiuha+hkcuo4lmnvindo7qyrixigbyaow==';
once we have a reference to our source image object we can use the drawimage method to render it to the canvas. as we we'll see later the drawimage method is overloaded and has three different variants. in its most basic form it looks like this.
Once the source graph object is obtained, we can render it into canvas using the drawimage method. There are three forms of the drawimage method, and the following is the most basic one.
drawimage (image, x, y)where image is a reference to our image or canvas object. x and y form the coordinate on the target canvas where our image should be placed.
where image is an image or canvas object, and x and y are their starting coordinates in the target canvas.
in the following example i will be using an external image as the backdrop of a small line graph. using backdrops can make your script considerably smaller because we don't need to draw an elaborate background. i'm only using one image here so i use the image object's onload event handler to execute the drawing statements. the drawimage method places the backdrop on the coordinate (0,0) which is the top left corner of the canvas.
In the following example, I use an external image as the background of a linear image. We don’t need to draw a responsible background with the background picture, and save a lot of code. Only one image object is used here, so the draw action is triggered in its onload event response function. The drawimage method places the background image at the upper left corner (0,0) of the canvas.
functiondraw(){
function draw() { var ctx = document.getelementbyid('canvas').getcontext('2d'); var img = new image(); img.onload = function(){ ctx.drawimage(img,0,0); ctx.beginpath(); ctx.moveto(30,96); ctx.lineto(70,66); ctx.lineto(103,76); ctx.lineto(170,15); ctx.stroke(); } img.src = 'images/backdrop.png'; }the second variant of the drawimage method adds two new parameters and it allows us to place scaled images on the canvas.
Another variant of the drawimage method is the addition of two parameters to control the image to scale in canvas.
drawimage (image, x, y, width, height)where width and height is the image's size on the target canvas.
in this example i'm going to use an image as a wallpaper and repeat it several times on the canvas. this is done simply by looping and placing the scaled images at different positions. in the code below the first for loops through the rows the second for loop the columns. the image is scaled one third of its original size which is 50x38 pixels. we'll see how this could also have been achieved, by creating a custom pattern, later in this tutorial.
In this example, I would use an image to spread out in canvas in a repeating manner like the background. It is also very simple to implement, just loop through the zoomed pictures. See the code below. The first layer of for loop is to repeat rows, and the second layer is to repeat columns. The image size is scaled to one third of the original, 50x38 px. This method can be used to achieve the effect of background patterns well, as you will see in the following tutorial.
note : images can become blurry when scaling up or grainy if they're scaled down too much. scaling is probably best not done if you've got some text in it which needs to remain legible.Note: The image may become obscure or blurred due to large scale scaling. If your image has text, it is best not to scale, because after processing that, it is very likely that the text in the image will become unrecognizable.
functiondraw(){
function draw() { var ctx = document.getelementbyid('canvas').getcontext('2d'); var img = new image(); img.onload = function(){ for (i=0;i<4;i++){ for (j=0;j<3;j++){ ctx.drawimage(img,j*50,i*38,50,38); } } } img.src = 'images/rhino.jpg'; }the third and last variant of the drawimage method has eight new parameters. we can use this method to slice parts of a source image and draw them to the canvas.
The third and last variant of the drawimage method has 8 new parameters to control the display of slices.
drawimage (image, sx, sy, swidth, sheight, dx, dy, dwidth, dheight)the first parameter image, just as with the other variants, is either a reference to an image object or a reference to a different canvas element. for the other eight parameters it's best to look at the image on the right. the first four parameters define the location and size of the slice on the source image. the last four parameters define the position and size on the destination canvas.
The first parameter is the same as the others, both are references to one image or another canvas. The other 8 parameters are best referred to the diagram on the right. The first 4 define the slice position and size of the image source, and the last 4 define the target display position and size of the slice.
slicing can be a useful tool when you want to make compositions. you could have all elements in a single image file and use this method to combine a complete drawing. for instance, if you want to make a chart you could have a png image containing all the necessary text in a single file and depending on your data could change the scale of your chart without very much difficulty. another advantage is that you don't need to load every image individually.
Slicing is a powerful tool for image synthesis. Suppose there is an image containing all the elements, then you can use this method to synthesize a complete image. For example, if you want to draw a chart and have a png file with all the necessary text on your hand, you can easily change the final displayed chart according to the actual data needs. Another benefit of this method is that you don't need to load each image separately.
in this example i'm going to use the same rhino as we've seen above, but now i'm going to slice its head out and composite it into a picture frame. the image of the picture frame includes a dropshadow which has been saved as a 24-bit png image. because 24-bit png images include a full 8-bit alpha channel, unlike gif and 8-bit png images, i can place it onto any background and don't have to worry about a matte color.
In this example, I used the rhino image that I had used above, but this time I would make a slice close-up of the rhino head and then synthesize it into a photo frame. The frame has a shadow effect and is an image saved in 24-bit png format. Because the 24-bit png image comes with a full 8-bit alpha channel, unlike gif and 8-bit png, I can put it as a background without worrying about the underlying color.
i took a different approach to the loading of the images than the example above. i just placed the images directly in my html document and used a css rule to hide them from view (display:none). i assigned both images an id attribute to make them easier to select. the script itself is very simple. i first draw the sliced and scaled image on the canvas (first drawimage statement), and then place the frame on top (second drawimage statement).
I load the image in a different way than the one I used above, insert the image directly into the html, and then hide it through css (display:none). I assigned ids for both images, which are convenient for later use. Looking at the script below, it is quite simple. First, slice the rhino head (the first drawimage) and put it on the canvas, and then put a photo frame on it (the second drawimage).
function draw() { var canvas = document.getelementbyid('canvas'); var ctx = canvas.getcontext('2d'); // draw slice ctx.drawimage(document.getelementbyid('source'), 33,71,104,124,21,20,87,104); // draw frame ctx.drawimage(document.getelementbyid('frame'),0,0);}in the final example of this chapter i've made a little art gallery. the gallery consists of a table containing several images. when the page is loaded, for each image in the page a canvas element is inserted and a frame is drawn around it.
in my case, all images have a fixed width and height, and so does the frame that's drawn around it. you could enhance the script so that it uses the image's width and height to make the frame fit perfectly around it.
the code below should be self-explanatory. we loop through the images array and add new canvas elements accordingly. probably the only thing to note, for those not so familiar with the dom, is the use of the insertbefore method. insertbefore is a method of the parent node (a table cell) of the element (the image) before which we want to insert our new node (the canvas element).