py_gd
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:
https://github.com/libgd/libgd/
Why gd?
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.
Why a new python wrapper for gd?
gdmodule (gitHub: https://github.com/Solomoriah/gdmodule) is a wrapper
for gd that has been around along time. However:
- It appears to be unmaintained (last touched 12 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_gdis being actively maintained.py_gdis a "thick" wrapper -- we're trying to provide a nice object oriented, Pythonic interface.py_gduses numpy (and the PEP3118 buffer interface) to allow efficient transfer of data back and forth between Python and gd.py_gdis 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.
How is py_gd built?
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.
Dependencies:
Run Time
At run time, py_gd currently requires the numpy package: http://www.numpy.org, but nothing else.
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.
Build Time
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...
See the Install section for more info
Is py_gd a complete wrapper around gd?
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
- cubic 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... (not hard to add, just haven't needed it)
- freetype fonts
- image manipulations: scaling, etc
Can I contribute?
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
Install
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
pip installing
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: we are working on pre-built wheels for all major platforms -- stay tuned!
Contributions to the effort would be happily accepted: see:
https://github.com/NOAA-ORR-ERD/py_gd/issues/34
For progress.
Building
Windows
py_gd depends on libgd which, in turn, depends on libpng, and others -- this makes it a major pain to build on Windows.
So far, folks have had the most luck with using the vcpkg system.
https://vcpkg.io/en/index.html
libgd is on there, and theoretically can simply be installed::
vcpkg install libgd
Once vcpkg is setup up properly -- I am no expert on this -- let us know if it works for you, and if you needed to do anything special.
OS-X
py_gd depends on libgd which, in turn, depends on libpng, and others -- You can use macports or homebrew or vcpkg to roll your own to get these, and then the build should work.
We have not tested this ourselves -- let us know what works for you.
Linux
py_gd depends on libgd, which may be available in your distro's repo (it's used heavily by PHP).
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
Once the library and headers are installed to "normal" locations, the py_gd build system should find them
Building py_gd
get the source:
You can get the source:
-
From PyPI:
-
From a release on GitHub:
-
By cloning the
py_gdrepository to your local machine
It's a good idea to create a venv, virtualenv or conda environment to scope your python installations to this project.
Install the requirements
-
with conda:
conda install --file conda_requirements.txt --file conda_requirements_dev.txt
-
with pip:
- pip install cython numpy pytest
-
cd into the repo
Build and Install
Run these commands:
$ python -m pip install .
If you want to work on the source, you'll want an "editable" install:
$ python -m pip install -e .
testing
The tests require pytest -- if you haven't used the conda_requirements_dev.txt, you will need to install it:
$ python -m pip install pytest
or
$ conda install pytest
Then run the tests:
$ pytest --pyargs py_gd
That will ensure the installed tests run.
or
$ pytest py_gd/test
That will run the tests in the source -- helpful if you want to debug or add tests.
The tests output a number of images -- these are checked against stored checksums for the tests.
But if anything doesn't match, a test may fail. You can look in test_images_output dir in the test dir.
Release files for py-gd 2.3.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| py_gd-2.3.3.tar.gz | 565.2 kB | Details |
Release files / py_gd-2.3.3.tar.gz
| Download URL | py_gd-2.3.3.tar.gz |
|---|---|
| Size | 565.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e8e7377162c9b9cda7b068d6352dcfd4be13a7747a8e746d9651406756346c7c
|
|
BLAKE2b-256 checksum How to use checksums |
8bf5fa6deadface6eb61069b01370230ab00deda807d647789432283ace39fe2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.10.17
|