Python wrappers for libgd graphics drawing lib.
Welcome to the py_gd
project.
py-gd aims to provide nice Pythonic wrappers around libgd -- a robust, fast, and simple drawing lib:
Docs here:
https://noaa-orr-erd.github.io/py_gd/
Code here:
For the project at hand we needed fast and simple drawing -- 8-bit color, no anti-aliasing. We also wanted a nice simple API to work with. There are a number of newer drawing libs (AGG, Skia) that produce some pretty results, but are not as simple to use, and are focused on 32 bit fully anti-aliased drawing. If you want the prettiest rendering possible, I encourage you to check those out.
If you want something fast and simple -- py_gd
may be for you.
gdmodule
(gitHub: https://github.com/Solomoriah/gdmodule) is a wrapper
for gd that has been around along time. However:
- It appears to be minimally maintained (last touched 9 years ago as of this writing)
- It is a pretty direct wrapper around the gd old-style-C API
- It is hand-written C extension code -- more or less the state of the art for 1995 when it was first written, but I really don't want to work on that code!
On the other hand:
py_gd
is being actively maintained.py_gd
is a "thick" wrapper -- we're trying to provide a nice object oriented, Pythonic interface.py_gd
uses numpy (and the PEP3118 buffer interface) to allow efficient transfer of data back and forth between Python and gd.py_gd
is written in Cython, which is likely to be more robust and error free and easier to maintain.
However, there is some nice stuff in gdmodule (like including a truetype font) that we want to borrow at some point.
py_gd
is built using Cython: (www.cython.org). Cython allows us to both call into the existing gd C lib, and to also write wrapper code to make a nicer API in an efficient way. You shouldn't need Cython to use py_gd
, but you'll need it if you want to contribute to the wrappers or compile the code yourself.
py_gd
currently requires the numpy package: http://www.numpy.org
numpy is used to allow you to efficiently pass in data structures for things like vertices of large polygons, etc, and can be used to get a copy of the image buffer, and manipulate it in various ways, as well as passing it back to py_gd
.
In order to build py_gd
, the Cython package is also required: http://cython.org/
Most critically, py_gd
requires the libgd
libary, which itself requires a number of other libs, such as libpng
, libjpeg
, etc, etc...
This makes it a challenge to build on any platform other than Linux. Which is why we use the conda-forge system -- it provides lib_gd
for us.
In a word: no.
py_gd
was developed to meet particular needs, and is not the least bit complete. It does, however have enough to be useful (at least to us).
Major Working features:
- 8-bit "paletted" images
- transparent background
- built-in fonts for text
- lines, polygons, arcs
- experimental spline support (not in libgd itself)
- copying between images
- saving as gif, bmp, png, jpeg, and animated gif.
- numpy arrays for input and image buffer exchange.
Major Missing features:
- 32bit "truecolor" support
- loading images from gif, png, etc...
- freetype fonts
- image manipulations: scaling, etc
You sure can -- fork the source, and hack away -- you can actually add features pretty easily by taking a look at what's there -- with just a little C and/or Cython knowledge (not much!) you should be able to get stuff working.
Here's what you need to do:
- Find the function you want to wrap in gd.h
- Copy the prototype to
py_gd.pxd
, and edit it to make it Cython-compatible (copy what's done for the ones already there) - Add a method to the Image class in
py_gd.pyx
-- look for similar methods already, and try to keep the API similar. - Add a test to
test_gd.py
(Or a new test file) that tests your new method - Re-build (
pip install -e ./
- Try out your test...
- Lather, rinse, repeat, 'till it all works
py_gd
depends on libgd which, in turn, depends on libpng, and others -- this makes it a major pain to build yourself. we suggest using conda via miniconda, miniforge, or pixi, and the conda packages found in the conda-forge channel. It should be as easy as:
conda install -c https://conda.anaconda.org/conda-forge py_gd
This currently works on Mac, Windows and Linux
We try to maintain packages on PyPi, but they are only source packages -- they will need to be built to work. This is fairly straightforward on Linux, but a serious challenge on Windows and Mac. NOTE: contributions of wheels would be happily accepted.
py_gd
depends on libgd which, in turn, depends on libpng, and others -- this makes it a major pain to build on Windows.
Folks have had some luck getting it going with the newer Windows clib providers.
py_gd
depends on libgd which, in turn, depends on libpng, and others -- You can use macports or homebrew or roll your own to get these, and then the build should work.
py_gd
depends on libgd, which may be available in your distro's repo (it's used heavily by PHP). However your distro's version may be too old for py_gd
, so you may have to built it yourself.
py_gd
requires libgd version >= 2.3. If your Linux distro has an up to date version, you can probably simply install it (and the development headers) from the system repos. something like:
apt-get install libgd, libgd-dev
or similar yum command (maybe just gd
rather than libgd
If your distro doesn't have a recent version, you'll need to download the source and build it yourself.
(not tested recently)
- Download the source code from GitHub
- Build the tar file from source and install it. The usual:
$ ./configure
$ make
$ make install
dance. This will install into /usr/local/
if you use the defaults. If your system is not yet set up to find libraries in /usr/local/
, then you need to add this line to your bashrc:
export LD_LIBRARY_PATH='/usr/local/lib'
(or set that globally) It needs to be set whenever you are running py_gd
.
Note: If you determine that you lack jpeg support -- yu should be able to install jpeg libs with your distro package mamager, e.g.
- libjpeg-turbo-devel
- libjpeg-turbo
-
Clone the
py_gd
repository to your local machine -
Create a virtualenv or conda environment to scope your python installations to this project (optional)
-
with conda:
conda install --file conda_requirements.txt --file conda_requirements_dev.txt
-
with pip:
- pip install cython numpy pytest
-
cd into the repo
-
run these commands:
$ pip install ./
- pip install pytest and run pytest to see that everything is working:
$ pytest --pyargs py_gd