Наложить на пустую картинку 10 картинок с определенной координатой для каждой node js sharp

Рейтинг: 0Ответов: 1Опубликовано: 11.07.2023

Имеется пустая картинка(белый цвет) размером условно 400x400, имеются 10 картинок. Нужно наложить на пустую картинку 10 картинок с определенным названием и расположением, использовал такой код

const sharp = require('sharp');

compositeImages();

async function compositeImages() {
    try {
      await sharp("./images/white.png")
        .composite([
          {
            input: "./images/kot.png",
            top: 0,
            left: 0,
          }
        ])
        .toFile("cats.png");
    } catch (error) {
      console.log(error);
    }
}

но он накладывает только одну картинку, глупо же будет писать 10 таких функций и вызывать их 10 раз

Ответы

▲ 0

Котиков не бывает мало

введите сюда описание изображения

Вот, пример как использовать composite:

// @ts-check
const sharp = require('sharp');

/** Размер генерируемой картинки */
const BACKGROUND_SIZE = 400;
/** Количество фоток в "строке" */
const ELEMENTS_COUNT = 5;
/** Расстояние между фотками в строке */
const OFFSET = 5;
/** Размер одной фотки */
const ELEMENT_SIZE = Math.trunc((BACKGROUND_SIZE - OFFSET) / ELEMENTS_COUNT) - OFFSET;
/** Общее количество фоток (для запроса api.thecatapi.com) */
const BLOCKS_COUNT = ELEMENTS_COUNT * Math.ceil(BACKGROUND_SIZE / ELEMENT_SIZE);

/** Получение котиков */
fetchCatImages(BLOCKS_COUNT)
  .then((res) => {
    /** Изменение размеров котиков */
    return Promise.all(
      res.map(
        (x) => sharp(x).resize({ width: ELEMENT_SIZE, height: ELEMENT_SIZE }).toBuffer()
      )
    );
  }).then((blocks) => {
    /** Создаём задник */
    const image = sharp({
      create: {
        width: BACKGROUND_SIZE,
        height: BACKGROUND_SIZE,
        background: '#f0f0f0',
        channels: 3
      }
    });

    /** Укладываем котиков плиткой */
    image.composite(blocks.map((buf, idx) => ({
      input: buf,
      top: OFFSET + (Math.trunc(idx / ELEMENTS_COUNT) * (ELEMENT_SIZE + OFFSET)),
      left: OFFSET + (idx % ELEMENTS_COUNT * (ELEMENT_SIZE + OFFSET))
    })));
    return image.toFile('./result.png');
  })
  .catch(console.error)
  .finally(() => process.exit(0));

/**
 * Получение котиков через api.thecatapi.com
 * @param {number} quantity 
 * @returns {Promise<Buffer[]>}
 */
async function fetchCatImages(quantity) {
  /** @type {string[]} */
  let urls = [];
  while (urls.length < quantity) {
    const res = await fetch('https://api.thecatapi.com/v1/images/search?limit=10');
    const data = await res.json();
    urls.push(...data.map((x) => x.url));
  }
  urls = urls.slice(0, quantity);

  const items = await Promise.all(urls.map((x) => fetch(x)));
  const buffers = await Promise.all(items.map((x) => x.arrayBuffer()));

  const result = buffers.map((x) => Buffer.from(x));
  return result;
}

И ещё котики

введите сюда описание изображения