Home > Blockchain >  How to apply filter to an image for instance of P5 in React
How to apply filter to an image for instance of P5 in React

Time:05-17

I'm hoping this is a very straight forward question but I haven't been able to get to the bottom of it. I'm using a react-P5-wrapper to create my P5 canvas in react (https://github.com/slin12/react-p5-wrapper) and I want to apply a filter to an image, which I normally would do in P5 like image.filter(GRAY), however I can't get it to work when P5 is an instance in React.

My sketch function looks like

function sketch(p5) {
        let hair;

        p5.setup = () => {
            p5.createCanvas(600, 600);
            hair = p5.loadImage(~/localpath/hairURL);
        }
      
        p5.draw = () => {
            p5.image(hair, 0, 0);
        };
      }

I would have thought I could do something as easy as p5.image(hair,0,0).filter(p5.GRAY); in my draw function, but that doesn't work. Gives me Uncaught TypeError: Cannot read properties of undefined (reading 'filter')

I could just use p5.filter(p5.GRAY); as a separate line in draw() - which works - however that applies the filter over the whole canvas, whereas I want to just apply it over one of the images. I will have multiple images and want to apply different filters to each one.

p5.image(hair,0 ,0).p5.filter(p5.GRAY) doesn't work either (thought I would try even if it didn't make much sense)

Any help is appreciated! Thanks

CodePudding user response:

I don't think what you are trying to do will be possible with your current approach.

In the documentation for p5.filter(...) it states the function "Applies a filter to the canvas" and there's no indication it can be constrained to an image or area of the canvas.

FYI, p5.image(...) doesn't return anything, so calling any function on the result like p5.image(...).filter(...) will always get the undefined error you are getting.

Edit

Actually the class p5.Image has it's own filter function. So if you call

hair = loadImage(...)
//then
hair.filter(...)

And then later call image(hair, 0, 0), that should work.

CodePudding user response:

I think you've confused the function p5.image(), which draws an image and returns undefined, and the p5.Image class, which is an image and returns an object with methods such as p5.Image.filter(). p5.Image.filter is also a mutating mode setter that returns undefined, so it's not something you'd want to chain anywhere.

Also, the p5 prefix in instance mode only applies to global p5 functions, not methods called on local objects like vectors and images that aren't part of the global p5 API namespace.

Here's the correct usage:

new p5(p => {
  let img1;
  let img2;

  p.preload = () => {
    img1 = p.loadImage("http://placekitten.com/200/200");
    img2 = p.loadImage("http://placekitten.com/200/202");
  };

  p.setup = () => {
    p.createCanvas(700, 410);
    p.background(0);

    img1.filter(p.GRAY);
    p.image(img1, 0, 0);
    
    // should be unfiltered
    p.image(img2, 200, 0);

    p.noLoop();
  };
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.js"></script>

  • Related