lovell / sharp

High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, AVIF and TIFF images. Uses the libvips library.
https://sharp.pixelplumbing.com
Apache License 2.0
29.11k stars 1.29k forks source link

How can one remove the background of an image by changing its alpha channel? #4064

Closed Gui153 closed 5 months ago

Gui153 commented 6 months ago

Question about an existing feature

What are you trying to achieve?

I am trying to remove the background from a logo by turning the background alpha channel to 0. Currently I am resizing the image into a square. Then create a clone which I turn into gray scale and then black and white. Then I want to use this black and white image to change the alpha channel of the original image based on this output.

When you searched for similar issues, what did you find that might be related?

Nothing

Please provide a minimal, standalone code sample, without other dependencies, that demonstrates this question

// nodebuffer is the image buffer //Size is a variable that ranges from 1 to 1024 const sharp = require("sharp"); const convert = await sharp(nodeBuffer) .resize(Size, Size, { fit: "contain", background: "#FFFFFF", }) .toBuffer();

const mask = await sharp(nodeBuffer) .resize(Size, Size, { fit: "contain", background: "#000000", }) .grayscale() .negate() // Invert black and white regions .toBuffer({ resolveWithObject: true }); //convert to strictly black and white const BlackAndWhite = await sharp(mask.data) .threshold(50) // Adjust threshold value as needed .png() .toBuffer();

fs.writeFileSync("./testGrayScale.png", mask.data); fs.writeFileSync("./testNegate.png", BlackAndWhite);

const resultImage = await originalImage .joinChannel( BlackAndWhite , { raw: { width: Size, height: Size, channels: 1 } }) .png() // Output as PNG to support transparency. .toFile('testMask2.png');

Please provide sample image(s) that help explain this question

original logo https://utfs.io/f/ef6f724b-0fc6-49a7-9586-5a02eeeb90fd-evqvdh.png mask https://utfs.io/f/424e43b3-fffe-44be-8b40-5fa3b17fcc6f-pyzg38.png result red cocacola logo with invisible background

lovell commented 6 months ago

You'll need to ensure that the BlackAndWhite image is single-channel, which can be achieved using toColourspace.

  const BlackAndWhite = await sharp(mask.data)
   .threshold(50) // Adjust threshold value as needed
+  .toColourspace('b-w')
   .png()
   .toBuffer();
lovell commented 5 months ago

I hope this information helped. Please feel free to re-open with more details if further assistance is required.