Anamalous pixels added after sending image via http

64 views Asked by At

I have a function which generates a certain image and adds a anamolous 1px wide white line at x=0 spanning across the height of the image. I am manually snipping it away using canvas and i can confirm the image looks ok and without the extra pixels manually on the filesystem.E Even though writeFileSync is blocking i have added a 5 second delay to be "safe" but after rendering this new image on my html the anamolous 1px wide line is back and i am flabbergasted on how it came back. My best guestimate right now is during the transport from the backend to the frontend.

server,js

 const slide = SlideNumbers[data.cert]; 
  await certGenerator(data);
  await new Promise((resolve) => setTimeout(resolve, 10000));
  if (slide <= 16) {
    console.log("Clipping 1px");
    const canvas = createCanvas(651, 887);
    var ctx = canvas.getContext("2d");

    const image = await loadImage(`./certs/output${slide - 1}.png`);
    ctx.drawImage(image, 0, 0);
    ctx.clearRect(0, 0, 1, 887); //snipping away 1 pixel wide line
    fs.writeFileSync(`./certs/output${slide - 1}.png`, canvas.toBuffer());
  }
  await new Promise((resolve) => setTimeout(resolve, 5000));
  res
    .status(200)
    .sendFile(path.resolve(__dirname, `../certs/output${slide - 1}.png`));

and here is the html

   fetch("/update", {
                        method: "POST",
                        headers: {
                          "Content-Type": "application/json",
                        },
                        body: JSON.stringify(data),
                      })
                        .then((response) => response.blob())
                        .then((imageBlob) => {
                          // Create a URL for the image blob
                          var imageUrl = URL.createObjectURL(imageBlob);
                          // Create an <img> element
                          var imgElement = document.createElement("img");
                          console.log(imageUrl);

                          // Set the source of the image to the generated image
                          imgElement.src = imageUrl;

                          // Append the image element to the "imageContainer" div
                          document
                            .getElementById("imageContainer")
                            .appendChild(imgElement);
                        })
                        .catch((error) => {
                          console.error("Error:", error);
                        });
1

There are 1 answers

2
traktor On BEST ANSWER

ctx.clearRect(0, 0, 1, 887) doesn't reduce the size of the canvas, so try creating a smaller canvas in the first place, and draw the image to the canvas without copying the unwanted line. Something like

if (slide <= 16) {
    console.log("Clipping 1px");
    const canvas = createCanvas(650, 887); // 1px less in the x direction
    var ctx = canvas.getContext("2d");

    const image = await loadImage(`./certs/output${slide - 1}.png`);
    //snipping away 1 pixel wide line:
    ctx.drawImage(image, 1, 0, 650, 887, 0, 0, 650, 887 );
    
    fs.writeFileSync(`./certs/output${slide - 1}.png`, canvas.toBuffer());
  }

Documentation for the drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) form of the call is available on MDN

If the server side implementation of drawImage is non conformant you may need to copy pixels from a 651 wide canvas to a separate 650 px wide one that you create.