I'm trying to display a TIFF image in the ol map. To do this, I have to convert the TIFF to PNG. I'm using geotiffjs to read the metadata and plotty to convert it to canvas and then to PNG.

It works somehow, but the colors are messed up. I got my TIFF file from QGIS (OpenStreetMap), I just selected a random area.

This is how it should look like: enter image description here

And this is the result I get: enter image description here

This is my code so far:

Read metadata from tiff file (I'm doing this in the Back-End)

const tiff = await geotiff.fromArrayBuffer(file.buffer);

const image = await tiff.getImage();
const geoKeys = image.getGeoKeys();
const bands = await image.readRasters();
const width = image.getWidth();
const height = image.getHeight();
const bbox = image.getBoundingBox();

return {
    projection: geoKeys.ProjectedCSTypeGeoKey,
    height: height,
    width: width,
    bbox: bbox,
    bands: bands,
    maxValue: bands[0].reduce((prev:number,next:number) => prev<next ? next : prev),
    minValue: bands[0].reduce((prev: number, next: number) => prev>next ? next : prev),


...get tiffData from server...

const newCanvas = document.createElement('canvas');

const plot = new plotty.plot({
    canvas: newCanvas,
    data: tiffData.bands[0],
    width: tiffData.width,
    height: tiffData.height,
    domain: [tiffData.minValue, tiffData.maxValue],
    clampLow: true,
    clampHigh: true,
    colorScale: 'earth'

const dataURL = newCanvas.toDataURL('image/png');

..add new ImageLayer...

source: new Static({
    url: dataURL,
    imageExtent: tiffData.bbox,

I got my example code from here: https://pbabik.github.io/webraster/

I'm not sure if I need plotty for this, I would prefer to remove this library as I do not really understand what it does exactly. Does anyone know why my colors are wrong or a different solution to display TIFFs in OpenLayers?

  • I would say problem is in colorScale option. Try some other scale.
    – TomazicM
    Aug 3, 2021 at 16:52
  • I know there are some different but I can't figure it out. If I don't set a colorScale my map becomes yellow.
    – BR75
    Aug 3, 2021 at 17:05
  • 1
    If you look at Plotty docs at github.com/santilland/plotty, there are 27 different color scales possible. Did you try some of them?
    – TomazicM
    Aug 3, 2021 at 17:37
  • not yet but I don't undestand why I should set colors if all I want is to get the colors from the original tiff imge
    – BR75
    Aug 3, 2021 at 17:46
  • 2
    You do not need plotty, just copy the rgb data from the geotiff to a canvas and then create a data url codesandbox.io/s/static-image-forked-7435e
    – Mike
    Aug 4, 2021 at 13:16

1 Answer 1


You do not need plotty, just copy the rgb data from the geotiff to a canvas and then create a data url:

let width, height, extent;

  .then(function (response) {
    return response.arrayBuffer();
  .then(function (arrayBuffer) {
    return fromArrayBuffer(arrayBuffer);
  .then(function (tiff) {
    return tiff.getImage();
  .then(function (image) {
    width = image.getWidth();
    height = image.getHeight();
    extent = image.getBoundingBox();
    return image.readRGB();
  .then(function (rgb) {
    const canvas = document.createElement("canvas");
    canvas.width = width;
    canvas.height = height;
    const context = canvas.getContext("2d");
    const data = context.getImageData(0, 0, width, height);
    const rgba = data.data;
    let j = 0;
    for (let i = 0; i < rgb.length; i += 3) {
      rgba[j] = rgb[i];
      rgba[j + 1] = rgb[i + 1];
      rgba[j + 2] = rgb[i + 2];
      rgba[j + 3] = 255;
      j += 4;
    context.putImageData(data, 0, 0);

      new ImageLayer({
        source: new Static({
          url: canvas.toDataURL(),
          projection: "EPSG:27700",
          imageExtent: extent

Working example (using promises instead of await) https://codesandbox.io/s/static-image-forked-7435e

  • I added more OpenLayers relevant code from working example
    – TomazicM
    Aug 5, 2021 at 7:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.