Sometimes a tiled layer, such as Bing Maps, OpenStreetMap, or from WMS services, is not what you need. You may have access to a georeferenced image or know of a server that can return an image for arbitrary extents and resolutions.
In these cases, OpenLayers offers the ol.layer.Image class that allows us to create a layer that is based on an image. For this recipe, we hook up to a WMS service that returns a single image on request for a given bounding box. The source code can be found in ch02/ch02-image-layer/.
This recipe will use the ol.source.ImageWMS source class to connect to the WMS server. However, if you have a static georeferenced image, then you should use ol.source.ImageStatic, which works in much the same way.

To create an image layer, perform the following steps:
div for the map container.extent, which will be used to center the map and restrict the extent variable for our image layer:var extent = [-93941, 6650480, 64589, 6766970];
var map = new ol.Map({
view: new ol.View({
zoom: 10,
center: ol.extent.getCenter(extent)
}),
target: 'js-map',
layers: [
new ol.layer.Tile({
source: new ol.source.Stamen({
layer: 'toner'
})
})
]
});map.addLayer(new ol.layer.Image({
source: new ol.source.ImageWMS({
url: 'http://ogc.bgs.ac.uk/cgi-bin/' +
'BGS_Bedrock_and_Superficial_Geology/wms',
params: {
LAYERS: 'BGS_EN_Bedrock_and_Superficial_Geology'
},
attributions: [
new ol.Attribution({
html: 'Contains <a href="http://bgs.ac.uk">' +
'British Geological Survey</a> ' +
'materials © NERC 2015'
})
]
}),
opacity: 0.7,
extent: extent
}));We decided to make use of a WMS service from the British Geological Survey, which can be utilized to return a single image for specified extents of Great Britain. For the background mapping, we chose to use the Stamen provider with a layer style called toner that will provide context for the WMS image.
var extent = [-93941, 6650480, 64589, 6766970];
We store an arbitrary extent into a variable, namely extent. This extent (using the EPSG:3857 projection) covers the city of London and surrounding areas.
var map = new ol.Map({
view: new ol.View({
zoom: 10,
center: ol.extent.getCenter(extent)
})
});When we create the map instance, the center value of the view is calculated from our custom extent. The ol.extent object provides many helper methods when working with extents, one of which is getCenter. This method expects an ol.Coordinate method (an array of coordinates), which we provide, it and returns the center coordinates for us:
map.addLayer(new ol.layer.Image({
source: new ol.source.ImageWMS({
url: 'http://ogc.bgs.ac.uk/cgi-bin/' +
'BGS_Bedrock_and_Superficial_Geology/wms',
params: {
LAYERS: 'BGS_EN_Bedrock_and_Superficial_Geology'
},
attributions: [
new ol.Attribution({
html: 'Contains <a href="http://bgs.ac.uk">' +
'British Geological Survey</a> ' +
'materials © NERC 2015'
})
]
}),
opacity: 0.7,
extent: extent
}));We create the image layer using the ol.layer.Image class. Using this class will request and return a single image, rather than multiple tile images. On the layer, we set the opacity property to 70% and restrict the extent of the layer by passing in our custom extent to the extent property.
The source property is an instance of ol.source.ImageWMS, which is similar to ol.source.TileWMS in its available properties. We provide the necessary details to successfully retrieve an image from this WMS service, such as the URL, the parameters of the request to include the specific layer that we're interested in, and the attribution to cover our usage.
OpenLayers will accompany our LAYERS parameter by sending some other parameters along with the request as default, such as FORMAT, VERSION, TRANSPARENT, and so on.
As we have restricted the extent of this layer, when you zoom to lower resolutions, this restriction becomes apparent, as demonstrated in the following screenshot:

When examining the returned image in the browser development tools, it weighed over half a megabyte with dimensions (in pixels) of 1556 × 1143. Suffice to say that the time to download and render this image on the map was not instantaneous.
When compared against tile requests that begin building up the map view incrementally, the user may feel a perceived loss of responsiveness with single image layers. It's up to you how to combat this—perhaps a loading bar or spinner as a visual cue of the current progress. Chapter 4, Working with Events, has a topic on implementing a work-in-progress indicator for map layers.