Sharp: Add support for ICO format

Created on 8 Feb 2018  路  7Comments  路  Source: lovell/sharp

Hello,

Any plans to add support for ICO images? Particularly multi bmp or png ico images used for website favicons.

question

Most helpful comment

It's not that hard with to-ico library:

const fsPromises = require('fs').promises
const sharp = require('sharp')
const toIco = require('to-ico')

generateFavicon('favicon.svg', 'favicon.ico')

async function generateFavicon(sourcePath, destPath) {
  const faviconDimensions = [16, 24, 32, 64]
  const metadata = await sharp(sourcePath).metadata()

  // Create buffer for each size
  const resizedBuffers = await Promise.all(faviconDimensions.map(dimension =>
    sharp(sourcePath, { density: dimension / Math.max(metadata.width, metadata.height) * metadata.density })
      .toBuffer()
  ))

  return fsPromises.writeFile(destPath, await toIco(resizedBuffers))
}

If you are not using SVG as an input, you may remove density and use .resize(dimension) in map callback

All 7 comments

Hello, did you see #543?

Hi. I didn't. Are you saying having Imagemagick installed adds support for the BMP and ICO formats?

A globally-installed copy of libvips that has been compiled with support for *magick is required - see https://jcupitt.github.io/libvips/install.html

Got it! I took a look. This is great. Thanks!

It's not that hard with to-ico library:

const fsPromises = require('fs').promises
const sharp = require('sharp')
const toIco = require('to-ico')

generateFavicon('favicon.svg', 'favicon.ico')

async function generateFavicon(sourcePath, destPath) {
  const faviconDimensions = [16, 24, 32, 64]
  const metadata = await sharp(sourcePath).metadata()

  // Create buffer for each size
  const resizedBuffers = await Promise.all(faviconDimensions.map(dimension =>
    sharp(sourcePath, { density: dimension / Math.max(metadata.width, metadata.height) * metadata.density })
      .toBuffer()
  ))

  return fsPromises.writeFile(destPath, await toIco(resizedBuffers))
}

If you are not using SVG as an input, you may remove density and use .resize(dimension) in map callback

The code is not working with the latest release of to-ico anymore. It should be the following:

const fs = require('fs');
const toIco = require('to-ico');

generateFavicon('src/assets/logo.png', 'public/favicon.ico');

function generateFavicon(sourcePath, destPath) {
  const image = fs.readFileSync(sourcePath);

  toIco([image], {
    sizes: [16, 24, 32, 48, 64],
    resize: true
  }).then( result => {
    fs.writeFileSync(destPath, result);
  });
}

You can also use this package if you need to convert a .ico file to .png.

https://www.npmjs.com/package/ico-to-png

And then pass back the png to Sharp to execute your manipulations.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

knoxcard picture knoxcard  路  3Comments

natural-law picture natural-law  路  3Comments

jaekunchoi picture jaekunchoi  路  3Comments

iq-dot picture iq-dot  路  3Comments

terbooter picture terbooter  路  3Comments