Massive opinionated opinion ahead: I like libraries that don't invent new types but just build around established ones. I think it's great that it uses numpy arrays and doesn't venture to (essentially) wrap an array of some kind and reinvent the wheel.
I always regret writing those lines when I come back to them anyway. Any time I try to refactor them I throw something out of order or drop a function.
I didn't want to reply to not sound too opinionated (ironically) but I agree. Chains feel cool when you write them down but don't always scale and lead to mistakes as Sileni points out.
BTW, as an addition to my original comment, a good example of reinventing types are the litany of C++ libraries that do NOT use the STL but reinvent half of it.
What is the alternative besides chaining, devise a new variable name for every operation? I understand that daisy chaining can be error prone, but the alternative is so difficult to maintain in long chains.
The other commenter pointed out the "inplace" version, but in the event I can't get away with that (or don't want to for some reason), I tend to throw in some numbering scheme on my original variable, and at the end replace the original variable or move to a "result_object" sort of name.
I think this is an edge case that is always going to feel inelegant, so whatever makes it easiest to load into my head wins out.
Given than a numpy array could contain lots of different kinds of data, how do you tell whether you're passing something image-like? Seems like even a thin wrapper could prevent some stupid mistakes.
Something I would miss as a user is interoperability. There should be ways to read from/export to numpy arrays, pytables, PIL, OpenCV, ImageMagick, basically all the mentioned and widespread libraries so far.
Not as fast as PIL but has reasonable optimizations like performing convolution in two passes, caching filter weights from row to row, and using numba decorations.
It's not quite apples to apples because Snowy offers a variety of filters, does everything in fp64, and is purely written in Python.
Well done! Some commenters have compared this to ImageMagick. I would equate this to comparing love2d [1] to SDL. If you want a user-friendly API for quick image manipulation, use Snowy. If Snowy doesn't give you the level of control you need, use something like ImageMagick or vips.
Would you mind defining a primary use case for this as opposed to PIL, ImageMagick or OpenCV? For the purposes of saving a description with the website.