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

Animated GIF masking #5508

Merged
merged 2 commits into from
Aug 30, 2022
Merged

Conversation

yifanmai
Copy link
Contributor

@yifanmai yifanmai commented Dec 20, 2021

Resolves #5174

Changes:

  • When the mask method is called on an Image that contains an animated GIF, the mask is applied to all of its frames.
  • Added unit tests for the mask method on static and animated images.

PR Checklist

  • npm run lint passes
  • [Inline documentation] is included / updated
  • [Unit tests] are included / updated

@welcome
Copy link

welcome bot commented Dec 20, 2021

🎉 Thanks for opening this pull request! Please check out our contributing guidelines if you haven't already. And be sure to add yourself to the list of contributors on the readme page!

resolves processing#5174

When the mask method is called on an Image that contains an animated
GIF, the mask is applied to all of its frames.
@Qianqianye Qianqianye requested a review from stalgiag July 13, 2022 02:46
@stalgiag
Copy link
Contributor

@yifanmai thank you for this well-written pull request! Sorry for the delay in reading it but luckily there are no merge conflicts yet.

The functionality looks good and I appreciate your thoughtful unit tests. I was worried that the performance would be terrible but it wasn't as bad as I feared.

The one minor issue that I see is that the first frame painted into the GIF will not be masked due to the way that p5.Image works with frames behind the scenes. I don't think that this PR necessarily needs to account for that as there are workarounds and this fix could come down the road.

I would be happy to merge this as-is but I am not as active in the repo right now so I think it would be good to get an opinion from @jesi-rgb who is working on GIF saving functionality this summer.

For anyone to reference, here is an example hosted on the editor with a build from this PR.

Copy link
Contributor

@stalgiag stalgiag left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comments in discussion.

@yifanmai
Copy link
Contributor Author

yifanmai commented Jul 20, 2022

Thanks for the review! @stalgiag could you assist with adding @jesi-rgb as a reviewer to this PR? I do not have permissions to do so.

Also, I could take a look at the first frame issue later, if you could provide some pointers about that.

@jesi-rgb
Copy link
Member

hey @yifanmai and @stalgiag!! thanks so much for counting on me for this review. while I can definitely review the code and check if something is wrong or at least clashes with what I'm working on, I don't feel quite prepared for this task just yet.

All in all, I'm a beginner in this whole javascript and open source thing, but i'll try my best!

That said, if you guys think there's someone better suited for this task do not hesitate in including them!

this.height
);
}
this.drawingContext.putImageData(prevFrameData, 0, 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this is what @stalgiag was referring to, but would this mean that we leave the gif's current frame in its previous, unmasked state? If so, maybe we need to get the current frame index and draw the newly masked frame instead of drawing prevFrameData

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried drawing the current frame after the masking is done, but this causes the new test on the current frame to fail. This is surprising to me because I expect that if I put the masked frame using putImageData and then fetch the pixels using get, I should get the masked image back. Also, calling img.reset in the test (to draw the first frame) causes the test to pass. Any suggestions as to what might be going on?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you still getting a test failure? I just tried running locally but it seems to work OK!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the failing unit tests were due to #5772 .

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok great! If that was the only issue, I can take another look through today to make sure I haven't forgotten about anything, but then this PR could be good to go!

for (let i = 0; i < img.width; i++) {
for (let j = 0; j < img.height; j++) {
let alpha = i < 5 && j < 5 ? 255 : 0;
assert.strictEqual(img.get(i, j)[3], alpha);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding tests for the existing static image behaviour too, this is great!

@yifanmai
Copy link
Contributor Author

Hi @jesi-rgb, it is OK that you are new; I am also a new contributor to this project! Any feedback from you is appreciated. :)

Copy link
Contributor

@davepagurek davepagurek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay, nice work on this! 🙂

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

Successfully merging this pull request may close these issues.

Masking an animated GIF loaded with loadImage() not working.
4 participants