import sharp from "sharp"; import path from "path"; export default class AlphaComposite { async process(filename, maskFilename, extractedDir) { const image = sharp(path.join(extractedDir, filename)) .removeAlpha() const imageMeta = await image.metadata() const imageBuffer = await image.toBuffer() const mask = await sharp(path.join(extractedDir, maskFilename)) .extractChannel("blue") .resize(imageMeta.width, imageMeta.height) .toBuffer(); return sharp(imageBuffer) .joinChannel(mask) .toBuffer() } async crop(buffer, rect) { const left = rect.y const top = rect.x const width = rect.h const height = rect.w const rotate = rect.rotate === 0 ? -90 : 0 const newImage = await sharp(buffer).rotate(90).extract({ left: left, top: top, width: width, height: height }).resize(width, height).extract({ left: 0, top: 0, width: width, height: height }).toBuffer() return await sharp(newImage).rotate(rotate).toBuffer() } async toBuffer(filename, extractedDir) { const file = path.join(extractedDir, filename) const { data, info } = await sharp(file).raw().toBuffer({ resolveWithObject: true }) const { width, height, channels } = info; const pixelArray = new Uint8ClampedArray(data.buffer); for (let i = 0; i < pixelArray.length; i += 4) { let alpha = pixelArray[i + 3] / 255; pixelArray[i + 0] = pixelArray[i + 0] * alpha pixelArray[i + 1] = pixelArray[i + 1] * alpha pixelArray[i + 2] = pixelArray[i + 2] * alpha } return await sharp(pixelArray, { raw: { width, height, channels } }).png().toBuffer(); } }