Skip to content

Enhancement: ensure metadata.background is compatible with color package for single-channel images #4090

@Zirafnik

Description

@Zirafnik

When using sharp(input).metadata() an object with properties, which includes background is returned.

background: Default background colour, if present, for PNG (bKGD) and GIF images, either an RGB Object or a single greyscale value

It can return RGB Object or greyscale number.

When using sharp(input).flatten() we can pass in an options object which includes the background color property. This option expects an RGB Object or a CSS type color string (e.g. 'white').

[options.background] string | Object "{r: 0, g: 0, b: 0}"

What I did, was use the background color returned by .metadata(), directly as an option in .flatten(). This however, produced an error in cases where the metadata returned a greyscale number, which is not a valid input for flatten background option.

Current workaround is simple: just repeat the greyscale number value for all the RGB Object fields.

const image = sharp(input)

const data = await image.metadata();

// THIS CAN FAIL: when background is greyscale number
const image
    .flatten({background: data.background ?? 'white'}) // include fallback when no background is returned
    .toBuffer();

// WORKAROUND:
const background =
        typeof data.background === 'object'
            ? data.background
            : { r: data.background, g: data.background, b: data.background };

const image
    .flatten({ background }) // need a separate check for fallback (not included here)
    .toBuffer();

However, while the "fix" is simple, it is not the expected behavior and should be adjusted. I propose that the .flatten() background option accepts a greyscale number as possible input.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions