Images

Images are used in various places throughout Homey, such as album art for speakers, camera devices and in Flows.

When an Image is registered, it needs a way of providing Homey with it's data. This can be either:

  • an URL, available from anywhere on the internet
  • a getStream method that fills a stream with the binary data
  • a local path to a static image which is shipped with the App.

Note: Images are limited to 5 MB.

Creating an image

Using an URL

URLs should be used when the image is available from anywhere on the internet.

const myImage = await this.homey.images.createImage();
myImage.setUrl('https://www.example.com/image.png'); // the URL must start with https://

Using a Stream

Streams should be used when downloading an image that cannot be supplied using Image.setUrl. Using image streams involves writing data directly into a Node.js stream. Using streams Requires homey version 2.2.0 or higher.

const fetch = require('node-fetch');

const myImage = await this.homey.images.createImage();

myImage.setStream(async (stream) => {
  const res = await fetch('http://192.168.1.100/image.png');
  if (!res.ok) {
    throw new Error('Invalid Response');
  }

  return res.body.pipe(stream);
});

Using a Path

Paths should be used when the image is locally available.

const myImage = await this.homey.images.createImage();
myImage.setPath('/userdata/image.png');

Using a Buffer [DEPRECATED]

Buffers should be used when downloading an image that cannot be access anywhere in the world.

const fetch = require('node-fetch');

const myImage = await this.homey.images.createImage('png');

myImage.setBuffer(async () => {
  const res = await fetch('http://192.168.1.100/image.png');
  if (!res.ok) {
    throw new Error('Invalid Response');
  }

  return res.buffer();
});

Updating the image

Call Image.update() when the image has been updated, and the front-end will download the image again.

When your image uses a Stream, the method provided in setStream will be called again.

At any time, you can switch between delivery type by calling Image#setPath, Image#setStream or Image#setURL.

Retrieving an image

It is also possible to consume an image in your app, for instance through use of Flow Tokens.

const Homey = require('homey');
const {PassThrough} = require('stream');
const fetch = require('node-fetch');
const FormData = require('form-data');

//uploads an image to imgur and returns a link
async function uploadImage(image) {
  const stream = await image.getStream();

  const form = new FormData();

  form.append('image', stream, {
    contentType: stream.contentType,
    filename: stream.filename,
    name: 'image',
  });

  form.append('description', `This image can also be (temporarily) viewed at: ${image.cloudUrl} and ${image.localUrl}`);

  const response = await fetch("https://api.imgur.com/3/image", {
    method: 'POST',
    //pipe through a passthrough stream, workarround for a node-fetch bug involving form-data streams without content length set.
    body: form.pipe(new PassThrough()),
    headers: {
      ...form.getHeaders(),
      Authorization: 'Client-ID <YOUR_CLIENT_ID>'
    }
  });

  if (!response.ok) {
    throw new Error(response.statusText);
  }

  const { data } = await response.json();
  return data.link;
}