Unable to perform CSS image-rendering on p5 canvas in the browser

First, sorry for my English and I’ll try to explain.
I’m trying to display pixelated image on p5 canvas in the browser by providing the canvas element in style.css with image-rendering property. I found code below by Belen Albeza to guide me. After many attempts, I’m able to replicate the result, which is showing pixelated image on Javascript canvas but cannot replicate on p5 canvas in the browser. Note: I had attempted this on Microsoft Edge, Chrome and Chromium (Raspberry Pi).

This is my code with image provided: p5.js Web Editor | Show pixelated image on canvas (p5js.org)

Note: Use local server / live server to load image because most browser does not allow to simply load an image.
After you run it, you should be able to see the top image displayed properly in pixelated form which it was using Javascript canvas. And the bottom one was not displayed properly in pixelated form which it was using p5 canvas. So conclusion, I want to able to use image-rendering property on p5 canvas element to show pixelated image in the browser.

Thanks,
Will
(I’m trying!)

1 Like

I would have to read more of the p5.js implementation to explain why but it looks like however it draws images, it does not respect that CSS setting. However, you could achieve this yourself like so:

const scaleFactor = 3;
let catImg;

function preload() {
  catImg = loadImage('cat.png');
}

function setup() {
  createCanvas(catImg.width * scaleFactor, catImg.height * scaleFactor);
  // this isn't critical, there's just no point in doing high DPI
  // rendering for pixel aligned squares.
  pixelDensity(1);
  background(255);
  noLoop();
  noStroke();
}

function draw() {
  for (let x = 0; x < catImg.width; x++) {
    for (let y = 0; y < catImg.height; y++) {
      const c = catImg.get(x, y);
      fill(c);
      square(x * scaleFactor, y * scaleFactor, scaleFactor);
    }
  }
}

Note: this will be slow if you are animating things so you would want to draw this scaled version of the image to a p5.Graphics object which you can then use with the image() function.

https://editor.p5js.org/Kumu-Paul/sketches/DDC5z8nko

1 Like

Thanks KumuPaul for your post.

I would have to read more of the p5.js implementation to explain why but it looks like however it draws images, it does not respect that CSS setting.

Yes please do so. I did also look into p5.js to maybe tweak a bit of things, but nope because the code is advance for me as I still look at myself as novice or intermediate person in JS.

And thanks for your guide and code. Before this, I did too thinking of making my own image scaling code but after a while I found out that I can skip it by implementing just the CSS setting to let the browser do the “extra work” for me. Well guess in the meantime, I just have to use the scaling code. But I still hoping the CSS setting could work to give us another option.

Thanks,
Will

Ok, I figured it out. The problem is that p5.js creates a separate canvas object & 2d graphics object to contain the image data when loadImage() is called, and I guess the image-rendering rules don’t apply when using a canvas as the source. However, the image() function can also support a p5.Element object that has a elt of type Image:

const scaleFactor = 1;
let catImg;

function preload() {
  // This isn't going to delay setup like a normal loadXXX() call would
  let img = new Image();
  img.onload = () => {
    catImg = new p5.Element(img);
    catImg.width = img.width;
    catImg.height = img.height;
    redraw();
  };
  img.src = 'cat.png';
}

function setup() {
  createCanvas(catImg.width * scaleFactor, catImg.height * scaleFactor);
  // this isn't critical, there's just no point in doing high DPI
  // rendering for pixel aligned squares.
  pixelDensity(1);
  background(255);
  noLoop();
  noStroke();
}

function draw() {
  if (catImg) {
    image(catImg, 0, 0);
  }
}

https://editor.p5js.org/Kumu-Paul/sketches/W9S62O8D6

3 Likes

Thanks again KumuPaul for your post.

I tried your code. It works very well. It just not as I anticipated of how it should be. I will try to understand what you meant about the separate canvas object stuff.

And now we got an alternative method to display/render image on p5 canvas in the browser. Thanks to KumuPaul :sunglasses:.

Thanks,
Will
(Continue my journey)