I am trying to draw an uploaded image on a frame image which is a tilted frame image already saved on the server using node canvas.
The issue I am facing right now is the clipping functionality for the uploaded image from top and bottom to show it inside the frame properly adjusted is not working.
The code I am trying right now is:
const responseFileName = `${Date.now()}.png`;
const frameImageMetadata = await sharp(frames[i]).metadata();
const canvas = createCanvas(
frameImageMetadata.width,
frameImageMetadata.height
);
const ctx = canvas.getContext("2d");
ctx.imageSmoothingEnabled = false;
ctx.mozImageSmoothingEnabled = false;
ctx.webkitImageSmoothingEnabled = false;
const [frameImage, customImage] = await Promise.all([
loadImage(frames[i]),
loadImage(userUploadedImage),
]);
const frameWidth = frameImage.width;
const frameHeight = frameImage.height;
ctx.drawImage(frameImage, 0, 0, frameWidth, frameHeight);
// Set the size for the custom image (you may adjust these dimensions)
const customWidth = frameWidth * 0.92; // 80% of frame width
const customHeight = frameHeight * 0.95; // 80% of frame height
const tempCanvas = createCanvas(customWidth, customHeight);
const tempCtx = tempCanvas.getContext("2d");
tempCtx.imageSmoothingEnabled = false;
tempCtx.mozImageSmoothingEnabled = false;
tempCtx.webkitImageSmoothingEnabled = false;
// Draw the custom image
tempCtx.drawImage(customImage, 0, 0, customWidth, customHeight);
// Define the diagonal shape parameters
ctx.rect(50, 20, 200, 120);
ctx.stroke();
tempCtx.clip();
const tempResponseFileName = `${Date.now()}.png`;
const tempGeneratedFile = path.join(
__dirname,
"public",
"generated-images",
tempResponseFileName
);
const tempOutput = fs.createWriteStream(tempGeneratedFile);
const tempStream = tempCanvas.createPNGStream({ compressionLevel: 0 });
await new Promise((resolve, reject) => {
tempStream.pipe(tempOutput);
tempOutput.on("finish", resolve);
tempOutput.on("error", reject);
});
// Draw the clipped custom image
ctx.drawImage(tempCanvas, 51, 25);
const generatedFile = path.join(
__dirname,
"public",
"generated-images",
responseFileName
);
const output = fs.createWriteStream(generatedFile);
const stream = canvas.createPNGStream({ compressionLevel: 0 });
await new Promise((resolve, reject) => {
stream.pipe(output);
output.on("finish", resolve);
output.on("error", reject);
});
images.push(`generated-images/${responseFileName}`);`
The frame image that I am using is:
use
console.log
the code to see ifcustomWidth
andcustomHeight
are being passed to theclip()
function in the correct way.Also
clip()
alone does not have any effect.the image needs to be followed by a new drawing function after you called
tempCtx.clip();
tempCtx.drawImage(customImage, 0, 0, customWidth, customHeight);
try this code that make you redraw after the clip:
since it is difficult to grasp these concept let's try something simpler:
ctx.rect()
, and theclip()
function is called to apply the clipping