如何在Node.js中使用sharp.js将边框半径添加到复合图像中的图像?

huangapple go评论70阅读模式
英文:

How to add border radius to images in a composite image using sharp.js in Node.js?

问题

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

我的代码:

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

// 虚拟图像列表,真实数据将通过API获取
const imageUrls = Array(25).fill("").map((el, i) => `https://picsum.photos/id/${i}/1280/720`)

// 基本设置
const productWidth = 1080
const productHeight = 1080
const row = 5
const col = 5
const gapSize = 10;

// 图像宽度和高度
const imageWidth = (productWidth - gapSize * (row - 1) - gapSize * 2) / row;
const imageHeight = (productHeight - gapSize * (col - 1) - gapSize * 2) / col;
const borderRadius = 20;

// 用于边框半径的蒙版
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)
    // 初始化画布
    const canvas = sharp({
      create: {
        width: productWidth,
        height: productHeight,
        channels: 4, // RGBA
        background: { r: 255, g: 255, b: 255, alpha: 1 } // 白色背景
      }
    });
    // 绘制图像
    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'
      }
    })
    // 下载最终产品
    canvas.composite(compositeArr)
      .png()
      .toBuffer()
      .then((buffer) => {
        fs.writeFileSync('banner.png', buffer);
      });
  } catch (error) {
    console.log(error)
  }

}

compositeImages()

最终产品:
如何在Node.js中使用sharp.js将边框半径添加到复合图像中的图像?

黑色边缘仍然存在。如何移除?

我将不背答案的方式提供建议或见解以解决此问题。提前感谢您的帮助。

英文:

I am using the sharp library in my Node.js project to composite a grid of images into a single image.
I have successfully created the composite image, but I need to apply a border radius to each of the images in the grid.

my code:

const sharp = require(&#39;sharp&#39;);
const axios = require(&#39;axios&#39;);
const fs = require(&#39;fs&#39;);
//dummy image lists, the real data will be fetched by api 
const imageUrls = Array(25).fill(&quot;&quot;).map((el, i)=&gt; `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(
`&lt;svg&gt;&lt;rect x=&quot;0&quot; y=&quot;0&quot; width=&quot;${imageWidth}&quot; height=&quot;${imageHeight}&quot; rx=&quot;${borderRadius}&quot; ry=&quot;${borderRadius}&quot; /&gt;&lt;/svg&gt;`
);
const imagePromises = imageUrls.map(async (url) =&gt; {
const response = await axios.get(url, { responseType: &#39;arraybuffer&#39; });
const image = sharp(response.data);
if (image) console.log(&#39;downloaded image&#39;)
return image.resize(imageWidth, imageHeight, { fit: &#39;cover&#39; }).composite([{
input: mask,
blend: &#39;dest-in&#39;
}]).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) =&gt; {
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: &#39;atop&#39;
}
})
//download final product
canvas.composite(compositeArr)
.png()
.toBuffer()
.then((buffer: any) =&gt; {
fs.writeFileSync(&#39;banner.png&#39;, buffer);
});
} catch (error) {
console.log(error)
}
}
compositeImages()

The final product:
如何在Node.js中使用sharp.js将边框半径添加到复合图像中的图像?

The black color edge is still here. How to remove?

I would appreciate any suggestions or insights on how to resolve this issue. Thank you in advance.

答案1

得分: 2

Try converting the image to PNG before compositing.

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

Try converting the image to PNG before compositing.

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

I hope this helps.

huangapple
  • 本文由 发表于 2023年6月1日 16:44:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/76380120.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定