9

How can I fetch images from a server?

I've got this bit of code which allows me to draw some images on a canvas.

<html>
  <head>
    <script type="text/javascript">
      function draw(){
        var canvas = document.getElementById('canv');
        var ctx = canvas.getContext('2d');

        for (i=0;i<document.images.length;i++){
          ctx.drawImage(document.images[i],i*150,i*130);
        }
    }
    </script>
  </head>
  <body onload="draw();">
    <canvas id="canv" width="1024" height="1024"></canvas>
    <img src="http://www.google.com/intl/en_ALL/images/logo.gif">
    <img src="http://l.yimg.com/a/i/ww/beta/y3.gif">
    <img src="http://static.ak.fbcdn.net/images/welcome/welcome_page_map.png">
  </body>
</html>

Instead of looping over document.images, i would like to continually fetch images from a server.

for (;;) {
    /* how to fetch myimage??? */
    myimage = fetch???('http://myserver/nextimage.cgi');
    ctx.drawImage(myimage, x, y);
}
Shog9
  • 156,901
  • 35
  • 231
  • 235
Mark Harrison
  • 297,451
  • 125
  • 333
  • 465

6 Answers6

25

Use the built-in JavaScript Image object.

Here is a very simple example of using the Image object:

myimage = new Image();
myimage.src = 'http://myserver/nextimage.cgi';

Here is a more appropriate mechanism for your scenario from the comments on this answer.

Thanks olliej!

It's worth noting that you can't synchronously request a resource, so you should actually do something along the lines of:

myimage = new Image();
myimage.onload = function() {
                     ctx.drawImage(myimage, x, y);
                 }
myimage.src = 'http://myserver/nextimage.cgi';
Community
  • 1
  • 1
Eric Schoonover
  • 47,184
  • 49
  • 157
  • 202
  • 7
    It's worth noting that you can't synchronously request a resource, so you should actually do something along the lines of myimage.onload = function() { ctx.drawImage(myimage, x, y); } myimage.src = 'http://myserver/nextimage.cgi'; – olliej Oct 03 '08 at 03:02
8

If you want to draw an image to a canvas you also need to wait for the image to actually load, so the correct thing to do will be:

myimage = new Image();
myimage.onload = function() {
    context.drawImage(myimage, ...);
}
myimage.src = 'http://myserver/nextimage.cgi';
olliej
  • 35,755
  • 9
  • 58
  • 55
2

To add an image in JavaScript you can do the following:

myimage = new Image()
myimage.src='http://....'

If an image on your page has an ID "image1", you can assign the src of image1 to myimage.src.

Diodeus - James MacFarlane
  • 112,730
  • 33
  • 157
  • 176
1

I have found that using prototypes is very helpful here. If you aren't familiar with them, prototypes are part of objects that allow you to set your own variables and/or methods to them.

Doing something like:

Image.prototype.position = {
    x: 0,
    y: 0
}

Image.prototype.onload = function(){
    context.drawImage(this, this.position.x, this.position.y);
}

allows you to set position and draw to the canvas without too much work.

The "position" variable allows you to move it around on the canvas.
So it's possible to do:

var myImg = new Image();
myImg.position.x = 20;
myImg.position.y = 200;
myImg.src = "http://www.google.com/intl/en_ALL/images/logo.gif";

and the image will automatically draw to the canvas at (20,200).

Prototype works for all HTML and native Javascript objects. So

Array.prototype.sum = function(){
    var _sum = 0.0;
    for (var i=0; i<this.length; i++){
        _sum += parseFloat(this[i]);
    }
    return _sum;
}

gives a new function to all Arrays.

However,

var Bob;
Bob.Prototype.sayHi = function(){
    alert("Hello there.");
}

will not work (for multiple reasons, but i'll just talk about prototypes).
Prototype is a "property" of sorts, which contains all the your properties/methods that you input, and is already in each of the HTML and native Javascript objects (not the ones you make).
Prototypes also allow for easy calling (you can do "myImg.position.x" instead of "myImg.prototype.position.x" ).

Besides, if you are defining you variable, you should do it more like this.

var Bob = function(){
    this.sayHi = function(){
        alert("Hello there.");
    }
}
TheCrzyMan
  • 1,010
  • 1
  • 11
  • 25
0

Using Promises:

class App {
  imageUrl = 'https://img-prod-cms-rt-microsoft-com.akamaized.net/cms/api/am/imageFileData/RE4HZBo'

  constructor(dom) {
    this.start(dom)
  }

  async start(dom) {
    const appEl = dom.createElement('div')
    dom.body.append(appEl)
    
    const imageEl = await this.loadImage(this.imageUrl)
    
    const canvas = dom.createElement('canvas')
    canvas.width = imageEl.width
    canvas.height = imageEl.height
    const ctx = canvas.getContext('2d')
    ctx.drawImage(imageEl, 0, 0)
    
    appEl.append(canvas)
  }
  
  loadImage = async (url) => 
    new Promise((resolve) => {
      const imageEl = new Image()
      imageEl.src = url
      imageEl.onload = () => resolve(imageEl)
    })
}

new App(document)
Ray Foss
  • 3,649
  • 3
  • 30
  • 31
-5

If you are using jQuery you can do:

$.('<img src="http://myserver/nextimage.cgi" />').appendTo('#canv');

You can also add widths and anything else in the img tag.

Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
Darryl Hein
  • 142,451
  • 95
  • 218
  • 261
  • 6
    Canvas doesn't display child elements, it's a programmable bitmap context you can draw to with JS, one of the API functions is drawImage() which takes an Image element/object and draws it into the buffer. It allows you to do nifty things that were previously not possible eg. http://canvaspaint.org/ – olliej Oct 03 '08 at 04:03
  • Now that I understand the question, I would give a different answer. :) – Darryl Hein Oct 06 '08 at 18:24