sharp icon indicating copy to clipboard operation
sharp copied to clipboard

Divide Blend

Open SuggonM opened this issue 1 year ago • 1 comments

Feature request

What are you trying to achieve?

Any one of these two blendmodes/filters:

  • Divide
  • Unpremultiply

Description

Hello, good day. I see there is a good list of image compositing options in the composite method. There is one for add and multiply, but the interface doesn't provide divide out of the box.

Upon further digging around, it seems that both of these are already implemented in the libvps library as native functions: Divide and Unpremultiply. So any possibility for these being accessible from Sharp interface?

In my specific case, I'm trying to reverse the pre-multiplication of a texture's alpha (PMA is a common pattern in modern games). In theory, a divide operation is able to undo it quite easily, so it would be a perfect fit for this job.

(The unpremultiply linked above is even more straightforward, but usage of such a specific function in case of Sharp is rather rare and perhaps obsolete.)

SuggonM avatar Aug 21 '24 12:08 SuggonM

I'm trying to reverse the pre-multiplication of a texture's alpha

Did you see the premultiplied option of the composite operation?

https://sharp.pixelplumbing.com/api-composite

  .composite([
    { input: 'texture.png', premultipled: true }
  ])

Alternatively, if you're providing raw pixel input, there is a premultiplied constructor property.

https://sharp.pixelplumbing.com/api-constructor

sharp(rawPixelInput, { raw: { width, height, channels, premultiplied: true }})...

lovell avatar Aug 24 '24 13:08 lovell

there is a premultiplied constructor property.

I see, it's possible to leverage Sharp's own underlying algorithms 😄

With that, the final unpremultiply function is looking more elegant now!

async function unpremultiply(sharpInst) {

	const sharpData = await sharpInst.raw().toBuffer({ resolveWithObject: true });
	const buffer = sharpData.data;
	const metadata = sharpData.info;

	const canvasData = {
		...metadata,
		background: 'transparent',
		premultiplied: true
	};

	const unpremultiplied = sharp(buffer, { raw: canvasData });

	return unpremultiplied;
}

SuggonM avatar Sep 22 '24 02:09 SuggonM