Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Graphics object used as mask results in image that is half the size of the original graphics object #6793

Closed
4 of 17 tasks
taliacotton opened this issue Feb 4, 2024 · 9 comments

Comments

@taliacotton
Copy link

Most appropriate sub-area of p5.js?

  • Accessibility
  • Color
  • Core/Environment/Rendering
  • Data
  • DOM
  • Events
  • Image
  • IO
  • Math
  • Typography
  • Utilities
  • WebGL
  • Build process
  • Unit testing
  • Internationalization
  • Friendly errors
  • Other (specify if possible)

p5.js version

1.9.0

Web browser and version

Chrome 121.0.6167.139

Operating system

MacOSX

Steps to reproduce this

Steps:

  1. Create a p5.Graphics object the same size as canvas—I've called mine "maskGraphics"
  2. Draw something to the main canvas—in my case it's an image
  3. Use get() to save a the canvas as an image, then clear the canvas.
  4. Draw something to the new Graphics object that will be the mask—in my case it's an ellipse
  5. Use mask() to mask the main image using the newly drawn mask to the mask graphics object.
  6. When you draw both the display image and the mask graphics image, the masked image is half the size as the mask graphics object when they're both drawn at the same size.
Screenshot 2024-02-04 at 2 07 13 PM

My gut is that it might have something to do with the device pixel ratio or the pixel density, but I have no reason to believe that and haven't been able to prove that.

Snippet:

let sketch = function(p) {
  let img, maskGraphics, cnv;


  p.preload = function() {
     img = p.loadImage("https://hips.hearstapps.com/hmg-prod/images/dog-puppy-on-garden-royalty-free-image-1586966191.jpg?crop=1xw:0.74975xh;center,top&resize=1200:*");
  };
  
  p.setup = () => {
      cnv = p.createCanvas(p.windowWidth, p.windowHeight);
      maskGraphics = p.createGraphics(p.windowWidth, p.windowHeight);
  }

  p.draw = () => {
    
        // draw an image to the main canvas
        p.image(img, 0,0,p.width, p.height);

        // save the canvas as an image, then clear the canvas
        let displayImage = p.get();
        p.clear();

        maskGraphics.clear();
        maskGraphics.fill(0);
        // Draw an ellipse to the mask graphics element in the center of the canvas
        maskGraphics.ellipse(p.width/2,p.height/2,300,300)

        // Apply the mask to displayImage
        // Without this, the image will be full size without the circle mask
        displayImage.mask(maskGraphics);

        // Draw the masked image
        // Without this, there will not be the masked image 
        p.image(displayImage, 0, 0, p.width, p.height);

        // Draw the mask circle  as an image to the main cnv to test its position on the canvas
        p.image(maskGraphics, 0, 0, p.width, p.height);
  };
}

new p5(sketch, 'container');
@davepagurek
Copy link
Contributor

Thanks for filing this issue! I think this bug may be the same as #6770 -- @Papershine, maybe you can test this example on your PR to see if it fixes it too?

@taliacotton
Copy link
Author

taliacotton commented Feb 5, 2024

Thank you! Yes, I had actually tested adding pixelDensity(1) prior to contributing the issue, but then the quality of the sketch goes down significantly. If I add pixelDensity(2) it also fixes the issue, but on devices where the device pixel ratio is something else the sketch lags significantly because it's drawing at 2x the size. I tried pixelDensity(window.devicePixelRatio) but that didn't fix the issue.

Is there a solution that solves the misalignment without losing the quality of the sketch?

@taliacotton
Copy link
Author

If it helps to debug, I just switched to version 1.4.1 per #6770, and that worked. However, not ideal for a long-term solution since I'd like to use the most recent version. Let's see if @Papershine's pull request solves it?

@Papershine
Copy link
Contributor

Yep I've tried it with the code in the PR and this is how it looks - this should be what it looks like right?

Screenshot 2024-02-04 at 6 55 38 PM

@taliacotton
Copy link
Author

whee yes! <3

@taliacotton
Copy link
Author

Hey awesome P5 team, do you have any tips for what I should do in the meantime regarding this bug while the pull request is being approved? Clients eager to see things right.

@aferriss
Copy link
Contributor

aferriss commented Feb 8, 2024

Hi! One option to use a shader to do the masking. Not sure if you can use webGL or not, but if you can it's a pretty short shader. Here's a quick example: https://editor.p5js.org/aferriss/sketches/qYWb4P49d

@davepagurek
Copy link
Contributor

Another option, if your mask is shapes that you draw, is to use beginClip/endClip: https://p5js.org/reference/#/p5/beginClip

@taliacotton
Copy link
Author

Awesome, thanks so much Dave. Will look into both of these.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants