如何使用Node.js中的sharp.js为合成图像中的图像添加边框半径?

oknrviil  于 2023-06-22  发布在  Node.js
关注(0)|答案(1)|浏览(148)

我在Node.js项目中使用sharp库将一个网格图像合成为单个图像。我已经成功地创建了合成图像,但我需要对网格中的每个图像应用边界半径。
我的代码:

const sharp = require('sharp');
const axios = require('axios');
const fs = require('fs');

//dummy image lists, the real data will be fetched by api 
const imageUrls = Array(25).fill("").map((el, i)=> `https://picsum.photos/id/${i}/1280/720`)

//basic setting
const productWidth = 1080
const productHeight = 1080
const row = 5
const col = 5
const gapSize = 10;

//length - padding * 2 - gap * row
const imageWidth = (productWidth - gapSize * (row - 1) - gapSize * 2) / row;
const imageHeight = (productHeight - gapSize * (col - 1) - gapSize * 2) / col;
const borderRadius = 20;

//for border radius
const mask = Buffer.from(
  `<svg><rect x="0" y="0" width="${imageWidth}" height="${imageHeight}" rx="${borderRadius}" ry="${borderRadius}" /></svg>`
);

const imagePromises = imageUrls.map(async (url) => {
  const response = await axios.get(url, { responseType: 'arraybuffer' });
  const image = sharp(response.data);

  if (image) console.log('downloaded image')

  return image.resize(imageWidth, imageHeight, { fit: 'cover' }).composite([{
    input: mask,
    blend: 'dest-in'
  }]).toBuffer();
});

async function compositeImages() {
  try {
    const images = await Promise.all(imagePromises)
    //init canvas
    const canvas = sharp({
      create: {
        width: productWidth,
        height: productHeight,
        channels: 4, // RGBA
        background: { r: 255, g: 255, b: 255, alpha: 1 } // white background
      }
    });
    //draw images
    const compositeArr = images.map((buffer, index) => {
      const colValue = index % col
      const rowValue = Math.floor(index / col)
      const x = gapSize + colValue * (imageWidth + gapSize)
      const y = gapSize + rowValue * (imageHeight + gapSize)
      return {
        input: buffer,
        left: x,
        top: y,
        blend: 'atop'
      }
    })
    //download final product
    canvas.composite(compositeArr)
      .png()
      .toBuffer()
      .then((buffer: any) => {
        fs.writeFileSync('banner.png', buffer);
      });
  } catch (error) {
    console.log(error)
  }

}

compositeImages()

最终产品:

黑色的边缘还在这里。如何删除?
我将感谢任何关于如何解决这个问题的建议或见解。先谢谢你。

thtygnil

thtygnil1#

尝试在合成之前将图像转换为PNG。

return image.resize(imageWidth, imageHeight, { fit: 'cover' }).png().composite([{
    input: mask,
    blend: 'dest-in'
  }]).toBuffer();

希望这能帮上忙。

相关问题