You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is a really great tool for checking images.
However, sometimes there are dynamic areas in the actual image which is subject to verification.
So a static expected image fixture won't do the job.
A simple solution would be : before comparing the images draw a black rectangle on specified position on both expected and actual images so any difference would be eliminated.
Another more elegant solution might be : mark the exclusion zones in the expected image in a certain way and the tool would simply ignore them . They can be marked with either maximum opacity alpha:255 or specific color which can serve as ignore color.
Does this sound like a useful feature and what option seems better?
Regards
I did notice a comment about the mask output which looks like this in the PR currently
However have you considered embedding the ignored regions inside the expected image?
For example if you have an expected image with areas which are marked with full opacity or particular color these areas can be excluded from matching.
I was thinking we just use a different color for found changes but within an ignored zone, similar to how AA rendered. That way the diff can still get rendered for those areas where each pixel differs but is ignored.
For the case where a pixeldiff is detected and relates to AA but is within an ignored zone we should still render it as ignored and not as AA.
WDYT? If it sounds good I can add this to my queue to add at some point to take up the PR and refine it
@Venefilyn I'm still not convinced this kind of feature should be built-in — my general philosophy for focused libraries like this is minimalism and simplicity, and exclusion zones can be trivially implemented on the app side (before passing the input to pixelmatch) by nulling the given pixels in both expected and actual image data. See prior discussion in #9
@mourner that is a nice workaround but doesn't highlight changed but ignored pixels which would be nice. It also means iterating over the images once before sending it in and then have pixelmatch do it again. With a lot of images that doesn't sit right with me. Not to mention that if we want to display before and after we have to keep those or save it before modifying and sending in the nulled pixel variants
For us it is a core thing to have excluded areas as we display system CPU usage, memory, networking, and other dynamic properties that mocking out either is a lot of work or doesn't make sense. We do want to see when stuff change but not so much with heavily dynamic charts or network activity
The absolute easiest to allow for custom usage like this might be to split up the main pixelmatch function to make extending easier without having to iterate over the images twice
It also means iterating over the images once before sending it in and then have pixelmatch do it again.
@Venefilyn it might sound not right but it's probably significantly faster than the approach in #153 in practice. The reason is that going linearly through a packed block of memory (a typed array) is very fast and highly optimized by the engines & hardware. But downstream, checking every pixel for "does it fall in one of the given regions" breaks that optimization and is way slower.
Highlighting is nice, but doesn't seem essential for use cases like this, but if performance is your priority, the pre-pass is a way superior approach IMO.
I'm still not convinced this kind of feature should be built-in — my general philosophy for focused libraries like this is minimalism and simplicity, and exclusion zones can be trivially implemented on the app side (before passing the input to pixelmatch) by nulling the given pixels in both expected and actual image data
For what's it worth, this would have a big impact for users of downstream Playwright because Playwright teams do not wish to accept such a change implemented on the app side (microsoft/playwright#41236). So right now, users are stuck with neither the testing framework, nor the underlying library willing to support it :(
@krassowski that might not help though even if implemented — Playwright vendored Pixelmatch so they don't get upstream updates microsoft/playwright#13585
The approach of blanking out the excluded zones before sending it to pixelmatch would work for playwright as well, if not part of playwright itself then as a plugin that adds a new toHaveScreenshot.
But yeah, you do have a point in keeping the core lib clean. Would it be possible to publish two packages? One for pixelmatch itself as the core and another package for extra features like excluded zones
Question for those interested in this feature: would an API that accepts a precomputed ignore mask (e.g. Uint8Array with one item per pixel where ignored pixels are >0) work for you?
It's quite a bit more low level than accepting ignoredRegions bboxes, but would sidestep all my performance concerns while also being much more flexible (e.g. you can define not only rectangles but any shapes over the image area).
That is a brilliantly simple and flexible approach, I dig it. I assume this would also mean supporting both UInt8Array and Uint8ClampedArray
Essentially, this means sending in an image mask that has the same dimensions of the images and black (I'm assuming 0 would be black) means we check and anything else becomes a mask
@Venefilyn it would just mark any pixels that were different but masked with ignoreColor and not count it towards diff count, not evening checking anything else (AA or diff magnitude). I think we can make it any typed array because the format doesn't matter. E.g. draw some shapes on a Canvas, then new Uint32Array(ctx.getImageData(0, 0, w, h).data.buffer) and all drawn pixels would form an ignore mask (a uint32 value would be 0 if RGBA are all 0).
@mourner I spun up a PR in #171. @pavelfeldman@krassowski have you had a chance to look the comments above over or this PR to see if this is something you'd need?
Activity
Venefilyn commentedon Jun 10, 2026
@mourner I was looking at this library as a substitute for our pixel tests in the Cockpit project. The only thing really missing was the masked/excluded/ignored regions so I've modified https://github.com/whtsky/pixelmatch-py/ locally to include this but feels like it is best to implement here first before I ask for it to be added to
pixelmatch-pyLooking at the previous attempt
I did notice a comment about the mask output which looks like this in the PR currently
I was thinking we just use a different color for found changes but within an ignored zone, similar to how AA rendered. That way the diff can still get rendered for those areas where each pixel differs but is ignored.
For the case where a pixeldiff is detected and relates to AA but is within an ignored zone we should still render it as ignored and not as AA.
WDYT? If it sounds good I can add this to my queue to add at some point to take up the PR and refine it
mourner commentedon Jun 10, 2026
@Venefilyn I'm still not convinced this kind of feature should be built-in — my general philosophy for focused libraries like this is minimalism and simplicity, and exclusion zones can be trivially implemented on the app side (before passing the input to pixelmatch) by nulling the given pixels in both expected and actual image data. See prior discussion in #9
Venefilyn commentedon Jun 11, 2026
@mourner that is a nice workaround but doesn't highlight changed but ignored pixels which would be nice. It also means iterating over the images once before sending it in and then have pixelmatch do it again. With a lot of images that doesn't sit right with me. Not to mention that if we want to display before and after we have to keep those or save it before modifying and sending in the nulled pixel variants
For us it is a core thing to have excluded areas as we display system CPU usage, memory, networking, and other dynamic properties that mocking out either is a lot of work or doesn't make sense. We do want to see when stuff change but not so much with heavily dynamic charts or network activity
The absolute easiest to allow for custom usage like this might be to split up the main pixelmatch function to make extending easier without having to iterate over the images twice
mourner commentedon Jun 11, 2026
@Venefilyn it might sound not right but it's probably significantly faster than the approach in #153 in practice. The reason is that going linearly through a packed block of memory (a typed array) is very fast and highly optimized by the engines & hardware. But downstream, checking every pixel for "does it fall in one of the given regions" breaks that optimization and is way slower.
Highlighting is nice, but doesn't seem essential for use cases like this, but if performance is your priority, the pre-pass is a way superior approach IMO.
krassowski commentedon Jun 15, 2026
For what's it worth, this would have a big impact for users of downstream Playwright because Playwright teams do not wish to accept such a change implemented on the app side (microsoft/playwright#41236). So right now, users are stuck with neither the testing framework, nor the underlying library willing to support it :(
mourner commentedon Jun 15, 2026
@krassowski that might not help though even if implemented — Playwright vendored Pixelmatch so they don't get upstream updates microsoft/playwright#13585
Venefilyn commentedon Jun 16, 2026
The approach of blanking out the excluded zones before sending it to pixelmatch would work for playwright as well, if not part of playwright itself then as a plugin that adds a new
toHaveScreenshot.But yeah, you do have a point in keeping the core lib clean. Would it be possible to publish two packages? One for
pixelmatchitself as the core and another package for extra features like excluded zonespixelmatch: Support masked areas
mourner commentedon Jul 8, 2026
Question for those interested in this feature: would an API that accepts a precomputed ignore mask (e.g.
Uint8Arraywith one item per pixel where ignored pixels are >0) work for you?It's quite a bit more low level than accepting
ignoredRegionsbboxes, but would sidestep all my performance concerns while also being much more flexible (e.g. you can define not only rectangles but any shapes over the image area).Venefilyn commentedon Jul 9, 2026
That is a brilliantly simple and flexible approach, I dig it. I assume this would also mean supporting both
UInt8ArrayandUint8ClampedArrayEssentially, this means sending in an image mask that has the same dimensions of the images and black (I'm assuming 0 would be black) means we check and anything else becomes a mask
Would a mask impact anti-aliasing at all?
mourner commentedon Jul 9, 2026
@Venefilyn it would just mark any pixels that were different but masked with ignoreColor and not count it towards diff count, not evening checking anything else (AA or diff magnitude). I think we can make it any typed array because the format doesn't matter. E.g. draw some shapes on a Canvas, then
new Uint32Array(ctx.getImageData(0, 0, w, h).data.buffer)and all drawn pixels would form an ignore mask (a uint32 value would be 0 if RGBA are all 0).Venefilyn commentedon Jul 14, 2026
@pavelfeldman @krassowski WDYT about the above? #163 (comment)
Venefilyn commentedon Sep 7, 2026
@mourner I spun up a PR in #171. @pavelfeldman @krassowski have you had a chance to look the comments above over or this PR to see if this is something you'd need?
feat: Add `options.ignoreMask` of pixels to skip
feat: Add `options.ignoreMask` of pixels to skip
feat: Add `options.ignoreMask` of pixels to skip
feat: Add `options.ignoreMask` of pixels to skip
feat: Add `options.ignoreMask` of pixels to skip
feat: Add `options.ignoreMask` of pixels to skip (#171)