Since a couple of years, I am the maintainer of the NodeJS library called
node-gd works or what you can do with it. For that I would suggest to directly visit its documentation page
LibGD, not necessarily related to PHP, is a library written in C for creating and manipulating different kinds of images. The library exists already quite a while: the earliest copyright notice I could find in the code dates back to 1994. Within PHP, the earliest changelog message I could find with regard to libgd dates back to PHP version 4.3.0 stating:
Bundled GD library 2.0.1 with php (ext/gd/libgd) (Rasmus, Jani, Markus, Edin)
In the years I was writing PHP mostly, around 2008-2010, I had also written some hobby projects with the GD functions, so I knew quite well what was possible with it. One of these projects being Maleglitch, which partly consists of a PHP script that does a trial-and-error bending of image data. The code injects arbitrary strings into Jpeg image data multiple times, with the purpose of getting a nice glitched end result.
The origins of
node-gd lay with Taegon Kim, who started to develop
node-gd was extended with more and more functions which are available in libgd, for example functions to apply filters to images.
What I like about libgd, apart from the API that I already knew, was the extremes to which for example JPEG lossy compression could be bent. When saving a JPEG file via libgd with a compression level of zero (losing most image data), you will get a cubist-like image consisting of large pixel blocks of faint colors.
Saving an image with JPEG compression 0, you will get a cubist-like image consisting of large pixel blocks of faint colors.
When I took the maintainance of
node-gd upon me, I first fixed that it was able to build on MacOS. Intrigued by C++, I set off to see whether I was able to implement NAN, the “Native Abstractions for Node.js”. I have no experience and no schooling in C++, so all I did was set up the build tools, dig into NAN’s github page and documentation, modify some code, build it, and analyze what happened. It took me a while, but at some point I got the hang of how NAN, v8 and libgd could work together (more or less).
More than half a year after getting
node-gd to work on MacOS, I did my first commit for the port to using NAN. After getting the hang of it, I decided to expose more of the libgd API via
node-gd. Also, since one of the earlier maintainers had added tests, I decided to add more tests. After that, I ditched a dependency on CoffeeScript because I wanted to have it depend on as few packages as possible.
Time passed, in which I did some additional private projects with
node-gd and I kept maintaining the package. Not many changes were needed, nor were many issues opened or bugs found. This does not mean that
node-gd is production ready, my C++ skills are not advanced enough in order for me to ensure all code works according best practices. I did invest additional spare time in extending the documentation: I read the libgd code to understand how certain things work and tried to add as many code examples as possible.
Last year I noticed v8 had evolved, just like NAN, and deprecation warnings were thrown during build time. I considered it the right moment to fix these issues. The I came to know about the Native Addons API, in short N-API, available in NodeJS since verison 6.x.x. And since I was up to something new, I decided to see if I could port
node-gd to use N-API instead of NAN. But of course, via trial and error, I had not been working with C++ for a while. After a couple of evenings cursing, searching and writing, I had a base version of
node-gd running with N-API ready! Wow, that went faster than I had expected.
I made major changes to the code base, not only did I move to N-API, I also:
- Added about 40 additional tests
- Fixed multiple issues that caused NodeJS to exit due to uncaught exceptions in the C++ code
- Extended the test coverage from NodeJS version 6 up to 12
- Simplified the creation of Animated GIFs
- Added about 20 async operations using the AsyncWorker API
- Let all async tasks return Promises
- Added extra checks to reduce errors thrown after image destroy
- Aligned the directory structure with NPMs preferred layout
These changes lead me to decide to make a new major release, which became v2.0:
node-gd is quite future proof again. I hope some developers out there will start using it, although some much more actively maintained image manipulation packages are currently available for NodeJS too. Feel free to give
node-gd a try, and do not hesitate to open issues on GitHub. I cannot give any guarantee in when those bugs will be fixed, since I do all this in my spare time, but I will do my best.