Coder Social home page Coder Social logo

aggdraw's Introduction

This is the sandbox area for the pytroll project, an international cooperation 
on a future distributed real-time processing system for Meteorological Satellite
Data.



------------------------------------
December 2010

Lars Ørum Rasmussen, Esben Sigård Nielsen, Kristian Rune Larsen, 
Martin Raspaud, Anna Geidne, Adam Dybbroe.

Danish Meteorological Institute (DMI)
Swedish Meteorological and Hydrological Institute (SMHI)

aggdraw's People

Contributors

a-hurst avatar adenyes avatar benburrill avatar bricetebbs avatar djhoese avatar dov avatar ejeschke avatar jakul avatar jaraco avatar micahcochran avatar mraspaud avatar odidev avatar sebastic avatar stuaxo avatar tobynanced2d avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

aggdraw's Issues

Trouble installing on ubuntu 16.04

I used this command, in bash, to install aggdraw for the entire system.

sudo -H pip3 install aggdraw

The complete output follows:

Collecting aggdraw
  Downloading https://files.pythonhosted.org/packages/42/33/2f6ba9ed2199181d1f2a6b346396134f98ff69a308f732acb36605bbc0b0/aggdraw-1.3.6.tar.gz (269kB)
100% |████████████████████████████████| 276kB 7.5MB/s 
Building wheels for collected packages: aggdraw
  Running setup.py bdist_wheel for aggdraw ... error
  Complete output from command /usr/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-install-fyrbgiq4/aggdraw/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" bdist_wheel -d /tmp/pip-wheel-tnafb16k --python-tag cp35:
  Trying freetype-config to find freetype library...
  Using ctypes to find freetype library...
  === freetype found: '/tmp/pip-install-fyrbgiq4'
  running bdist_wheel
  running build
  running build_ext
  building 'aggdraw' extension
  creating build
  creating build/temp.linux-x86_64-3.5
  creating build/temp.linux-x86_64-3.5/agg2
  creating build/temp.linux-x86_64-3.5/agg2/src
  creating build/temp.linux-x86_64-3.5/agg2/font_freetype
  x86_64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -DVERSION=1.3.6 -DHAVE_FREETYPE2 -Iagg2/include -Iagg2/font_freetype -I/tmp/pip-install-fyrbgiq4/include -I/tmp/pip-install-fyrbgiq4/include/freetype -I/tmp/pip-install-fyrbgiq4/include/freetype2 -I/usr/include/python3.5m -c aggdraw.cxx -o build/temp.linux-x86_64-3.5/aggdraw.o
  cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
  In file included from aggdraw.cxx:84:0:
  agg2/font_freetype/agg_font_freetype.h:23:22: fatal error: ft2build.h: No such file or directory
  compilation terminated.
  error: command 'x86_64-linux-gnu-gcc' failed with exit status 1

  ----------------------------------------
  Failed building wheel for aggdraw
  Running setup.py clean for aggdraw
Failed to build aggdraw
Installing collected packages: aggdraw
  Running setup.py install for aggdraw ... error
    Complete output from command /usr/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-install-fyrbgiq4/aggdraw/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-record-hv7_mve1/install-record.txt --single-version-externally-managed --compile:
    Trying freetype-config to find freetype library...
    Using ctypes to find freetype library...
    === freetype found: '/tmp/pip-install-fyrbgiq4'
    running install
    running build
    running build_ext
    building 'aggdraw' extension
    creating build
    creating build/temp.linux-x86_64-3.5
    creating build/temp.linux-x86_64-3.5/agg2
    creating build/temp.linux-x86_64-3.5/agg2/src
    creating build/temp.linux-x86_64-3.5/agg2/font_freetype
    x86_64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -DVERSION=1.3.6 -DHAVE_FREETYPE2 -Iagg2/include -Iagg2/font_freetype -I/tmp/pip-install-fyrbgiq4/include -I/tmp/pip-install-fyrbgiq4/include/freetype -I/tmp/pip-install-fyrbgiq4/include/freetype2 -I/usr/include/python3.5m -c aggdraw.cxx -o build/temp.linux-x86_64-3.5/aggdraw.o
    cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
    In file included from aggdraw.cxx:84:0:
    agg2/font_freetype/agg_font_freetype.h:23:22: fatal error: ft2build.h: No such file or directory
    compilation terminated.
    error: command 'x86_64-linux-gnu-gcc' failed with exit status 1

    ----------------------------------------
Command "/usr/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-install-fyrbgiq4/aggdraw/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-record-hv7_mve1/install-record.txt --single-version-externally-managed --compile" failed with error code 1 in /tmp/pip-install-fyrbgiq4/aggdraw/`

I found that I have 3 files named ft2build.h, but all are within other software's directories (docker and fsl) where pip would have no business looking. Do I need to install freetype source files before installing aggdraw? If so, can this be made an explicity dependency in aggdraw so it just works? Thanks for any help in getting this working the "right" way.

Had to set CFLAGS="-fpermissive" to build

Installing from pip dies, unless I set -fpermissive first

export CFLAGS="-fpermissive"

Not sure if these are real issues it is flagging in agg on 64 bit or can be safely ignored..

Here is what it the log when trying to install without -fpermissive:

$ pip install aggdraw --allow-external aggdraw --allow-unverified aggdraw
Downloading/unpacking aggdraw
  aggdraw is potentially insecure and unverifiable.
  Downloading aggdraw-1.1-20051010.zip (382kB): 382kB downloaded
  Running setup.py (path:/mnt/data/home/stu/.virtualenvs/t4/build/aggdraw/setup.py) egg_info for package aggdraw
    === freetype support disabled

Installing collected packages: aggdraw
  Running setup.py install for aggdraw
    === freetype support disabled
    building 'aggdraw' extension
    x86_64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Iagg2/include -I/usr/include/python2.7 -c aggdraw.cxx -o build/temp.linux-x86_64-2.7/aggdraw.o
    cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
    In file included from agg2/include/agg_vertex_sequence.h:23:0,
                     from agg2/include/agg_vcgen_contour.h:20,
                     from agg2/include/agg_conv_contour.h:23,
                     from aggdraw.cxx:53:
    agg2/include/agg_array.h: In member function ‘agg::int8u* agg::pod_allocator::allocate(unsigned int, unsigned int)’:
    agg2/include/agg_array.h:523:63: error: cast from ‘agg::int8u* {aka unsigned char*}’ to ‘unsigned int’ loses precision [-fpermissive]
                         unsigned align = (alignment - unsigned(ptr) % alignment) % alignment;
                                                                   ^
    aggdraw.cxx: In function ‘PyObject* draw_new(PyObject*, PyObject*)’:
    aggdraw.cxx:504:71: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
             PyObject* buffer = PyObject_CallMethod(image, "tostring", NULL);
                                                                           ^
    aggdraw.cxx:530:67: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
             self->draw = new draw_adaptor<agg::pixfmt_gray8>(self, "L");
                                                                       ^
    aggdraw.cxx:533:69: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
             self->draw = new draw_adaptor<agg::pixfmt_rgb24>(self, "RGB");
                                                                         ^
    aggdraw.cxx:536:69: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
             self->draw = new draw_adaptor<agg::pixfmt_bgr24>(self, "BGR");
                                                                         ^
    aggdraw.cxx:539:71: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
             self->draw = new draw_adaptor<agg::pixfmt_rgba32>(self, "RGBA");
                                                                           ^
    aggdraw.cxx: In function ‘agg::rgba8 getcolor(PyObject*, int)’:
    aggdraw.cxx:639:72: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
             result = PyObject_CallFunction(aggdraw_getcolor_obj, "O", color);
                                                                            ^
    aggdraw.cxx: In function ‘PyObject* draw_flush(DrawObject*, PyObject*)’:
    aggdraw.cxx:1059:72: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
         result = PyObject_CallMethod(self->image, "fromstring", "N", buffer);
                                                                            ^
    aggdraw.cxx:1059:72: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
    aggdraw.cxx: In function ‘void draw_dealloc(DrawObject*)’:
    aggdraw.cxx:1114:18: warning: deleting object of abstract class type ‘draw_adaptor_base’ which has non-virtual destructor will cause undefined behaviour [-Wdelete-non-virtual-dtor]
         delete self->draw;
                      ^
    aggdraw.cxx: In function ‘PyObject* pen_new(PyObject*, PyObject*, PyObject*)’:
    aggdraw.cxx:1133:65: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
         static char* kwlist[] = { "color", "width", "opacity", NULL };
                                                                     ^
    aggdraw.cxx:1133:65: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
    aggdraw.cxx:1133:65: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
    aggdraw.cxx: In function ‘PyObject* brush_new(PyObject*, PyObject*, PyObject*)’:
    aggdraw.cxx:1164:56: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
         static char* kwlist[] = { "color", "opacity", NULL };
                                                            ^
    aggdraw.cxx:1164:56: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
    aggdraw.cxx: In function ‘PyObject* font_new(PyObject*, PyObject*, PyObject*)’:
    aggdraw.cxx:1195:72: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
         static char* kwlist[] = { "color", "file", "size", "opacity", NULL };
                                                                            ^
    aggdraw.cxx:1195:72: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
    aggdraw.cxx:1195:72: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
    aggdraw.cxx:1195:72: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
    aggdraw.cxx: At global scope:
    aggdraw.cxx:169:21: warning: ‘FontType’ defined but not used [-Wunused-variable]
     static PyTypeObject FontType = {
                         ^
    error: command 'x86_64-linux-gnu-gcc' failed with exit status 1
    Complete output from command /mnt/data/home/stu/.virtualenvs/t4/bin/python -c "import setuptools, tokenize;__file__='/mnt/data/home/stu/.virtualenvs/t4/build/aggdraw/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" install --record /tmp/pip-QPxA_0-record/install-record.txt --single-version-externally-managed --compile --install-headers /mnt/data/home/stu/.virtualenvs/t4/include/site/python2.7:
    === freetype support disabled

running install

running build

running build_ext

building 'aggdraw' extension

creating build

creating build/temp.linux-x86_64-2.7

creating build/temp.linux-x86_64-2.7/agg2

creating build/temp.linux-x86_64-2.7/agg2/src

x86_64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Iagg2/include -I/usr/include/python2.7 -c aggdraw.cxx -o build/temp.linux-x86_64-2.7/aggdraw.o

cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++

In file included from agg2/include/agg_vertex_sequence.h:23:0,

                 from agg2/include/agg_vcgen_contour.h:20,

                 from agg2/include/agg_conv_contour.h:23,

                 from aggdraw.cxx:53:

agg2/include/agg_array.h: In member function ‘agg::int8u* agg::pod_allocator::allocate(unsigned int, unsigned int)’:

agg2/include/agg_array.h:523:63: error: cast from ‘agg::int8u* {aka unsigned char*}’ to ‘unsigned int’ loses precision [-fpermissive]

                     unsigned align = (alignment - unsigned(ptr) % alignment) % alignment;

                                                               ^

aggdraw.cxx: In function ‘PyObject* draw_new(PyObject*, PyObject*)’:

aggdraw.cxx:504:71: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]

         PyObject* buffer = PyObject_CallMethod(image, "tostring", NULL);

                                                                       ^

aggdraw.cxx:530:67: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]

         self->draw = new draw_adaptor<agg::pixfmt_gray8>(self, "L");

                                                                   ^

aggdraw.cxx:533:69: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]

         self->draw = new draw_adaptor<agg::pixfmt_rgb24>(self, "RGB");

                                                                     ^

aggdraw.cxx:536:69: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]

         self->draw = new draw_adaptor<agg::pixfmt_bgr24>(self, "BGR");

                                                                     ^

aggdraw.cxx:539:71: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]

         self->draw = new draw_adaptor<agg::pixfmt_rgba32>(self, "RGBA");

                                                                       ^

aggdraw.cxx: In function ‘agg::rgba8 getcolor(PyObject*, int)’:

aggdraw.cxx:639:72: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]

         result = PyObject_CallFunction(aggdraw_getcolor_obj, "O", color);

                                                                        ^

aggdraw.cxx: In function ‘PyObject* draw_flush(DrawObject*, PyObject*)’:

aggdraw.cxx:1059:72: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]

     result = PyObject_CallMethod(self->image, "fromstring", "N", buffer);

                                                                        ^

aggdraw.cxx:1059:72: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]

aggdraw.cxx: In function ‘void draw_dealloc(DrawObject*)’:

aggdraw.cxx:1114:18: warning: deleting object of abstract class type ‘draw_adaptor_base’ which has non-virtual destructor will cause undefined behaviour [-Wdelete-non-virtual-dtor]

     delete self->draw;

                  ^

aggdraw.cxx: In function ‘PyObject* pen_new(PyObject*, PyObject*, PyObject*)’:

aggdraw.cxx:1133:65: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]

     static char* kwlist[] = { "color", "width", "opacity", NULL };

                                                                 ^

aggdraw.cxx:1133:65: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]

aggdraw.cxx:1133:65: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]

aggdraw.cxx: In function ‘PyObject* brush_new(PyObject*, PyObject*, PyObject*)’:

aggdraw.cxx:1164:56: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]

     static char* kwlist[] = { "color", "opacity", NULL };

                                                        ^

aggdraw.cxx:1164:56: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]

aggdraw.cxx: In function ‘PyObject* font_new(PyObject*, PyObject*, PyObject*)’:

aggdraw.cxx:1195:72: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]

     static char* kwlist[] = { "color", "file", "size", "opacity", NULL };

                                                                        ^

aggdraw.cxx:1195:72: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]

aggdraw.cxx:1195:72: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]

aggdraw.cxx:1195:72: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]

aggdraw.cxx: At global scope:

aggdraw.cxx:169:21: warning: ‘FontType’ defined but not used [-Wunused-variable]

 static PyTypeObject FontType = {

                     ^

error: command 'x86_64-linux-gnu-gcc' failed with exit status 1

----------------------------------------
Cleaning up...
Command /mnt/data/home/stu/.virtualenvs/t4/bin/python -c "import setuptools, tokenize;__file__='/mnt/data/home/stu/.virtualenvs/t4/build/aggdraw/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" install --record /tmp/pip-QPxA_0-record/install-record.txt --single-version-externally-managed --compile --install-headers /mnt/data/home/stu/.virtualenvs/t4/include/site/python2.7 failed with error code 1 in /mnt/data/home/stu/.virtualenvs/t4/build/aggdraw
Traceback (most recent call last):
  File "/mnt/data/home/stu/.virtualenvs/t4/bin/pip", line 11, in <module>
    sys.exit(main())
  File "/mnt/data/home/stu/.virtualenvs/t4/local/lib/python2.7/site-packages/pip/__init__.py", line 185, in main
    return command.main(cmd_args)
  File "/mnt/data/home/stu/.virtualenvs/t4/local/lib/python2.7/site-packages/pip/basecommand.py", line 161, in main
    text = '\n'.join(complete_log)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 42: ordinal not in range(128)

Different results between using python 3 and using python 2

It seems that there are some differences in implementation of python 3. Here is a simple script to display the issue. In python 2, the result is 50800. In python 3, the print result is 0.

import aggdraw
from PIL import Image
import numpy as np

symbol = aggdraw.Symbol("M400 200 L400 400")
pen = aggdraw.Pen("red")
image = Image.fromarray(np.zeros((800, 600, 3)), mode="RGB")
canvas = aggdraw.Draw(image)
canvas.symbol((0, 0), symbol, pen)
canvas.flush()
print(np.asarray(image).sum())

The value in the coordinates list cannot exceed 32767.

In my project, I need to draw an image with a large size. But when I used the line method, I found that some lines could not be drawn. After testing, I found that if the value of coordinate of a point in the list of coordinates (both horizontal and vertical) exceeds 32767, then the line method will not draw the line, while Pillow does.

I have used the following code for testing.

from aggdraw import Draw, Pen
from PIL import Image, ImageDraw

im = Image.new('RGB', (40000, 1000), 'white')

# No problem when using Pillow, which draws a horizontal bar up to 40000 pixels long.
draw = ImageDraw.Draw(im)
draw.line((0, 250, 40000, 250), fill='red', width=500)

# This line cannot be drawn unless I change this value to 32767 or less.
draw2 = Draw(im)
pen = Pen(color=(0, 0, 255), width=500)
draw2.line((0, 750, 32768, 750), pen)
draw2.flush()

im.show()

In addition, this problem occurs in other methods that require a list of coordinates to be entered (such as path).

  • Windows 10
  • Python: 3.10
  • Pillow: 9.1.1
  • aggdraw: 1.3.15

multline text not supported

#!/usr/bin/env python3

import aggdraw

from PIL import Image, ImageDraw, ImageFont

im = Image.new("RGBA", (256, 256), (255, 255, 255, 255))
draw = ImageDraw.Draw(im)
font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 42)
draw.text((0, 0), "this\nis\nmultiline", font=font, fill=(0, 0, 0))
im.save("Pillow.png")


im = Image.new("RGBA", (256, 256), (255, 255, 255, 255))
draw = aggdraw.Draw(im)
font = aggdraw.Font("black", "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 42)
draw.text((0, 0), "this\nis\nmultiline", font)
draw.flush()
im.save("aggdraw.png")

Pillow:
Pillow

aggdraw:
aggdraw

Find a way to document freetype and windows-specific code

Certain parts of aggdraw are only available if running/built on Windows or if aggdraw was built with freetype support. Right now I'm making aggdraw docs on readthedocs which is not as easy to accomplish this stuff with. I see two options:

  1. Generate documentation on travis/appveyor (that would mean building on Windows with freetype).
  2. Manually copy/document those pieces of the package in the .rst files.

Convert factory functions to proper python classes

Aggdraw seems to define all of its class __new__ methods as functions in the aggdraw module. It then creates a new object by creating a new type. This is an issue because this means classes like aggdraw.Draw aren't actually classes, they are functions, and that a user has no access to the methods without creating an instance of the object. Even worse you can't use sphinx autodoc functionality to document the classes because they don't technically exist until an instance is made.

I don't think this will be extremely hard to implement, but it isn't a top priority for me. Additionally, it has a high chance of breaking something.

Convert wrapper to Cython

As discussed in #37, one option to clean up the aggdraw code is to use cython. As mentioned in #43, I recently noticed that all of the classes in aggdraw are actually declared as factory functions instead of real classes. I don't think any of the aggdraw functionality requires this design so it would be nice if the classes were declared as real classes.

I think the best idea would be to convert the C++ file to cython. This should:

  1. Make the code easier to read
  2. Avoid compatibility issues with new versions of python
  3. Limit unicode/bytes issues and handling

I think this rewrite could wait until aggdraw 2.0 and could look at adding #3's functionality/updating the agg version.

Add support to release linux aarch64 wheels

Problem

On aarch64, ‘pip install aggdraw’ builds the wheels from source code and then installs it. It requires the user to have a development environment installed on his system. Also, it takes some time to build the wheels than downloading and extracting the wheels from pypi.

Resolution

On aarch64, ‘pip install aggdraw’ should download the wheels from pypi

@djhoese and Team Please let me know your interest in releasing aarch64 wheels. I can help in this. To start with could you please tell the steps/CI which you are using presently to release the wheel on pypi.

Brush/Pen transparency weirdness

For various reasons, I've been using a pretty hacky method for applying transparency to aggdraw-drawn textures to surfaces in the Python package I maintain. This consisted of slicing off the 'A' value of any RGBA colours, creating a Brush and/or Pen with full opacity, and then applying the transparency value manually to the 'A' value for each pixel in the image using numpy. Last week, however, I figured out a way to fix the underlying problem that necessitated this workaround and decided to remove it and start using the regular Brush/Pen opacity values.

Much to my surprise, however, this produced dramatically different (and wrong) results. See the following two images:

screen shot 2018-01-11 at 10 58 54 am

screen shot 2018-01-11 at 11 04 32 am

In both images, the semi-transparent circle over the '6' is supposed to have a fill value of (192, 192, 192, 128). The first is done with the old numpy transparency hack, the second with an aggdraw Brush. As you can see, the aggdraw one is considerably darker than it should be.

Curious, I tried playing around with the Pillow image context aggdraw is drawing to, and sure enough, the fill colour of the fully transparent background affects the resulting colour of the aggdraw-drawn circle. For example, when setting opacity with aggdraw, drawing on a background with (255, 255, 255, 0) fill results in an actual fill (printing out the the pixel values to terminal) of (223, 223, 223, 127), whereas drawing on a background of (0, 0, 0, 0) fill results in an actual fill of (95, 95, 95, 127). When using the Numpy hack, it results in a background of (192, 192, 192, 128) regardless of what colour the transparent background fill has.

I'm guessing what's happening here is that aggdraw is trying to make up the difference between the background colour and the Brush colour as if it were an RGB surface without alpha, resulting in double-opacity. Is this something that's a quick fix in aggdraw, or is it a problem with the underling AGG library itself? I'd try my hand at a fix, but I have a lot on my plate programming-wise right now and I'm not too experienced in C.

Thanks in advance!

Remove .svn directories

The source tree still contains the .svn directories, please remove them.

find . -type d -name ".svn" -exec git rm -rf {} \;

Default drawing behaviour different after merging agg2.4

As I brought up in #50, the default line-end and line-cap arguments are different after merging the agg 2.4 update, unexpectedly changing the way various aggdraw-generated shapes look. Here are two screenshots from the same aggdraw-rendered experiment program, the first pre-2.4 and the second post-2.4:

Screen Shot 2019-08-13 at 7 21 10 PM

Screen Shot 2019-08-13 at 7 19 48 PM

If you download both the images and switch back and forth between them with Quick Look or something (ignoring the missing left line, that's just trial-to-trial variation), you can see that:

  1. The corners of the boxes are now rounded, whereas before they were completely square.
  2. The line in the middle of the box (created with the line() method of the aggdraw.Draw(), not the .rectangle() method) is slightly longer for some reason.
  3. The asterisk in the middle is slightly thicker.

I'm able to revert the drawing behaviour for both 1 and 2 to the pre-2.4 defaults by adding linejoin = 0 and linecap = 0 to the arguments when creating the Pen object, but this breaks backwards compatibility with old aggdraw versions, which lack these arguments. My personal preference would be to revert the defaults here to the old defaults before the next release, since a lot of the use of aggdraw in my field (cognitive science research) is in older Python experiments for generating stimuli, and people trying to revive/replicate one of those experiments (largely one-off scripts with no real maintainer) are highly unlikely to realize the shapes look different than they did 5-10 years ago and add the new arguments accordingly.

The thicker asterisk remains unchanged with the above overrides, however, which appears to be a regression because the thickness/size of the asterisk is exactly as specified pre-2.4 but appears to be an extra 1 pixel thicker/larger post-2.4. I'll see if I can figure out a minimal example that showcases this bug clearly, since what I have here is all wrapped in my own drawing/rendering code.

EDIT: To revert to the old defaults in aggdraw itself, I believe all that's required is replacing the agg::round_join with agg::miter_join and agg::round_cap with agg::butt_cap in this section here:

aggdraw/aggdraw.cxx

Lines 1823 to 1833 in e9d7bcb

static PyObject*
pen_new(PyObject* self_, PyObject* args, PyObject* kw)
{
PenObject* self;
PyObject* color;
float width = 1.0;
agg::line_join_e line_join = agg::round_join;
agg::line_cap_e line_cap = agg::round_cap;
float miter_limit = 4.0; // Like default in agg_math_stroke.h
int opacity = 255;

Installation error

Since freetype-config is not available on Archlinux the installation fails (actually the update to the latest version fails, so something changed there):

❯ LANG=C pip install aggdraw
Collecting aggdraw
  Using cached https://files.pythonhosted.org/packages/49/e8/5021fba0bf22434c1f15700f01fb67750a86bae0f320d39aee53a61ed968/aggdraw-1.3.5.tar.gz
Building wheels for collected packages: aggdraw
  Running setup.py bdist_wheel for aggdraw ... error
  Complete output from command /home/simon/.pyenv/versions/3.7.0/bin/python3.7 -u -c "import setuptools, tokenize;__file__='/tmp/simon/pip-install-yez_bvvk/aggdraw/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" bdist_wheel -d /tmp/simon/pip-wheel-1qocje58 --python-tag cp37:
  Using ctypes to find freetype library...
  === freetype found: '/tmp/simon/pip-install-yez_bvvk'
  running bdist_wheel
  running build
  running build_ext
  building 'aggdraw' extension
  creating build
  creating build/temp.linux-x86_64-3.7
  creating build/temp.linux-x86_64-3.7/agg2
  creating build/temp.linux-x86_64-3.7/agg2/src
  creating build/temp.linux-x86_64-3.7/agg2/font_freetype
  ccache /usr/local/bin/cc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -O3 -Wall -fPIC -DVERSION=1.3.5 -DHAVE_FREETYPE2 -Iagg2/include -Iagg2/font_freetype -I/tmp/simon/pip-install-yez_bvvk/include -I/tmp/simon/pip-install-yez_bvvk/include/freetype -I/tmp/simon/pip-install-yez_bvvk/include/freetype2 -I/home/simon/.pyenv/versions/3.7.0/include/python3.7m -c aggdraw.cxx -o build/temp.linux-x86_64-3.7/aggdraw.o
  In file included from aggdraw.cxx:84:
  agg2/font_freetype/agg_font_freetype.h:23:10: fatal error: ft2build.h: No such file or directory
   #include <ft2build.h>
            ^~~~~~~~~~~~
  compilation terminated.
  error: command 'ccache' failed with exit status 1

It could be related to #30, as ctypes.util.find_library does not return the full path of the so file (in my case it gives 'libfreetype.so.6'):

aggdraw/setup.py

Lines 39 to 40 in fb26ded

from ctypes.util import find_library
ft_lib_path = find_library('freetype')

So the flags are added but the paths are not valid.

Cannot install on Windows

Hello.
It seems there's some issue with aggdraw and windows.
I have installed of course the Built Tools for windows

But I get an error for font_freetype

this is the error

Collecting aggdraw
  Using cached aggdraw-1.3.11.tar.gz (255 kB)
Building wheels for collected packages: aggdraw
  Building wheel for aggdraw (setup.py) ... error
  ERROR: Command errored out with exit status 1:
   command: 'c:\python38\python.exe' -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\\Users\\anton\\AppData\\Local\\Temp\\pip-install-er4oxpcq\\aggdraw\\setup.py'"'"'; __file__='"'"'C:\\Users\\anton\\AppData\\Local\\Temp\\pip-install-er4oxpcq\\aggdraw\\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdist_wheel -d 'C:\Users\anton\AppData\Local\Temp\pip-wheel-07gjl80k'
       cwd: C:\Users\anton\AppData\Local\Temp\pip-install-er4oxpcq\aggdraw\
  Complete output (19 lines):
  Trying freetype-config to find freetype library...
  Using ctypes to find freetype library...
  === freetype found: 'C:\Program Files\Java\jdk-14.0.1'
  running bdist_wheel
  running build
  running build_ext
  building 'aggdraw' extension
  creating build
  creating build\temp.win-amd64-3.8
  creating build\temp.win-amd64-3.8\Release
  creating build\temp.win-amd64-3.8\Release\agg2
  creating build\temp.win-amd64-3.8\Release\agg2\src
  creating build\temp.win-amd64-3.8\Release\agg2\font_freetype
  C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\x86_amd64\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD -DVERSION=1.3.11 -DHAVE_FREETYPE2 -Iagg2/include -Iagg2/font_freetype "-IC:\Program Files\Java\jdk-14.0.1\include" "-IC:\Program Files\Java\jdk-14.0.1\include/freetype" "-IC:\Program Files\Java\jdk-14.0.1\include/freetype2" -Ic:\python38\include -Ic:\python38\include "-IC:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\8.1\include\shared" "-IC:\Program Files (x86)\Windows Kits\8.1\include\um" "-IC:\Program Files (x86)\Windows Kits\8.1\include\winrt" /EHsc /Tpaggdraw.cxx /Fobuild\temp.win-amd64-3.8\Release\aggdraw.obj
  aggdraw.cxx
  c:\users\anton\appdata\local\temp\pip-install-er4oxpcq\aggdraw\agg2\include\agg_array.h(523): warning C4311: 'type cast': pointer truncation from 'agg::int8u *' to 'unsigned long'
  c:\users\anton\appdata\local\temp\pip-install-er4oxpcq\aggdraw\agg2\include\agg_array.h(523): warning C4302: 'type cast': truncation from 'agg::int8u *' to 'unsigned long'
  agg2/font_freetype\agg_font_freetype.h(23): fatal error C1083: Cannot open include file: 'ft2build.h': No such file or directory
  error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\BIN\\x86_amd64\\cl.exe' failed with exit status 2
  ----------------------------------------
  ERROR: Failed building wheel for aggdraw```

Latest Documentation?

I haven't been following the latest developments on this project, but I see there's been a lot of new activity + bugfixes + new features. I hope to be using the latest version going forward however, so am in need of the latest documentation describing the latest API, especially now that the original effbot docs are down. I was trying to browse the code repo but couldn't seem to find anything, and reading the actual code is not as easy as it seems to be hidden in the various .cxx files which I'm not fully sure how to navigate.

  • Where are the current documentation files, if any? If there's currently none, I would like to help out, but would need some pointers how and where to start. I think this should be fairly doable, since the original API and docs was fairly short/straightforward.
  • And/or could someone list the main new developments achieved so far compared to the original aggdraw?

Otherwise, loving all the progress and work to keep aggdraw alive, and especially excited about potentially exposing new agg features like gradients or fillpatterns etc.

Project Status

Is this project still being maintained by you @jakul? Would it be possible to add some maintainers/collaborators to this project to continue making updates?

I'm sure @mraspaud and myself would be willing to help.

Upgrade to agg 2.4

I agree with @djhoese in this thread that upgrading to v2.4 would require a more solid set of tests. So I hope the tests get in place in order that we can do the upgrade to 2.4, the API isn't that complicated luckily. The reason being that it's the most recent (and final) version, and once we start doing changes to aggdraw it's going to get more and more difficult to upgrade the underlaying agg version. So in my view it should be a priority to get this done at an early stage.

Merging changes from existing forks

As you know there are a few forks out there which have made several independent changes and improvements. In my own fork, I have gone through the existing forks and merged a few of the ones that seemed more important, including some bug fixes, freetype things, and added support for line caps and joins (looks like the original author of this has already suggested this #3). The full list of changes that I considered can be seen here:

https://github.com/karimbahgat/aggdraw/commits/master

More generally it may be worth doing a systematic round of the various forks to see which preexisting changes may be worth incorporating:

https://github.com/search?p=1&q=aggdraw&type=Repositories
https://github.com/pytroll/aggdraw/network/members

pip install results in error Windows 10 21H1

When I run the pip command it results in an error. Windows 10 latest version

C:\Users\Developer>pip install --no-cache-dir aggdraw
Collecting aggdraw
Downloading aggdraw-1.3.12.tar.gz (255 kB)
|████████████████████████████████| 255 kB 3.3 MB/s
Using legacy 'setup.py install' for aggdraw, since package 'wheel' is not installed.
Installing collected packages: aggdraw
Running setup.py install for aggdraw ... error
ERROR: Command errored out with exit status 1:
command: 'c:\program files\python39\python.exe' -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\Users\Developer\AppData\Local\Temp\pip-install-5bf0w6jo\aggdraw_ad2a8930b1fc4f7e8660a048aab41f75\setup.py'"'"'; file='"'"'C:\Users\Developer\AppData\Local\Temp\pip-install-5bf0w6jo\aggdraw_ad2a8930b1fc4f7e8660a048aab41f75\setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(file) if os.path.exists(file) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, file, '"'"'exec'"'"'))' install --record 'C:\Users\Developer\AppData\Local\Temp\pip-record-5a4yao16\install-record.txt' --single-version-externally-managed --compile --install-headers 'c:\program files\python39\Include\aggdraw'
cwd: C:\Users\Developer\AppData\Local\Temp\pip-install-5bf0w6jo\aggdraw_ad2a8930b1fc4f7e8660a048aab41f75
Complete output (8 lines):
Trying freetype-config to find freetype library...
Using ctypes to find freetype library...
=== freetype found: 'C:\Program Files\AdoptOpenJDK\jdk-11.0.9.11-hotspot'
running install
running build
running build_ext
building 'aggdraw' extension
error: Microsoft Visual C++ 14.0 is required. Get it with "Build Tools for Visual Studio": https://visualstudio.microsoft.com/downloads/
----------------------------------------
ERROR: Command errored out with exit status 1: 'c:\program files\python39\python.exe' -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\Users\Developer\AppData\Local\Temp\pip-install-5bf0w6jo\aggdraw_ad2a8930b1fc4f7e8660a048aab41f75\setup.py'"'"'; file='"'"'C:\Users\Developer\AppData\Local\Temp\pip-install-5bf0w6jo\aggdraw_ad2a8930b1fc4f7e8660a048aab41f75\setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(file) if os.path.exists(file) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, file, '"'"'exec'"'"'))' install --record 'C:\Users\Developer\AppData\Local\Temp\pip-record-5a4yao16\install-record.txt' --single-version-externally-managed --compile --install-headers 'c:\program files\python39\Include\aggdraw' Check the logs for full command output.

fatal error: 'ft2build.h' file not found on OSX 10.10

Cloning into 'aggdraw'...
remote: Counting objects: 293, done.
remote: Total 293 (delta 0), reused 0 (delta 0), pack-reused 293
Receiving objects: 100% (293/293), 348.74 KiB | 133.00 KiB/s, done.
Resolving deltas: 100% (108/108), done.
Checking connectivity... done.
running build_ext
building 'aggdraw' extension
creating build
creating build/temp.macosx-10.10-intel-2.7
creating build/temp.macosx-10.10-intel-2.7/agg2
creating build/temp.macosx-10.10-intel-2.7/agg2/src
creating build/temp.macosx-10.10-intel-2.7/agg2/font_freetype
cc -fno-strict-aliasing -fno-common -dynamic -arch x86_64 -arch i386 -g -Os -pipe -fno-common -fno-strict-aliasing -fwrapv -DENABLE_DTRACE -DMACOSX -DNDEBUG -Wall -Wstrict-prototypes -Wshorten-64-to-32 -DNDEBUG -g -fwrapv -Os -Wall -Wstrict-prototypes -DENABLE_DTRACE -arch x86_64 -arch i386 -pipe -DHAVE_FREETYPE2 -Iagg2/include -Iagg2/font_freetype -I/usr/include -I/usr/include/freetype2 -I/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c aggdraw.cxx -o build/temp.macosx-10.10-intel-2.7/aggdraw.o
In file included from aggdraw.cxx:69:
agg2/font_freetype/agg_font_freetype.h:23:10: fatal error: 'ft2build.h' file not found
#include <ft2build.h>
         ^
1 error generated.
error: command 'cc' failed with exit status 1
Traceback (most recent call last):
  File "selftest.py", line 5, in <module>
    from PIL import Image
ImportError: No module named PIL
running install
running build
running build_ext
building 'aggdraw' extension
cc -fno-strict-aliasing -fno-common -dynamic -arch x86_64 -arch i386 -g -Os -pipe -fno-common -fno-strict-aliasing -fwrapv -DENABLE_DTRACE -DMACOSX -DNDEBUG -Wall -Wstrict-prototypes -Wshorten-64-to-32 -DNDEBUG -g -fwrapv -Os -Wall -Wstrict-prototypes -DENABLE_DTRACE -arch x86_64 -arch i386 -pipe -DHAVE_FREETYPE2 -Iagg2/include -Iagg2/font_freetype -I/usr/include -I/usr/include/freetype2 -I/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c aggdraw.cxx -o build/temp.macosx-10.10-intel-2.7/aggdraw.o
In file included from aggdraw.cxx:69:
agg2/font_freetype/agg_font_freetype.h:23:10: fatal error: 'ft2build.h' file not found
#include <ft2build.h>
         ^
1 error generated.

aggdraw does not some to be able to find fonts when installed in a venv

Minimal steps to reproduce (on Ubuntu 21.04, Python 3.9):

in terminal

% python -m venv aggdrawtest
% source  aggdrawtest/bin/activate
% pip install aggdraw
% python

in python:

>>> import aggdraw
>>> aggdraw.Font('black', '/usr/share/fonts/truetype/open-sans/OpenSans-Regular.ttf')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: cannot load font (no text renderer)

By contrast, if I do sudo apt install python3-aggdraw I see this in python:

>>> import aggdraw
>>> aggdraw.Font('black', '/usr/share/fonts/truetype/open-sans/OpenSans-Regular.ttf')
<Font object at 0x7f3847abcd10>

Clearly something is going wrong in the venv install. Any ideas?

Blank output image (v1.3)

The following MWE draws a square in version 1.1, but renders an empty image in version 1.3.

import numpy as np
import aggdraw
from PIL import Image
from colour import Color

pixel_array = np.zeros((1080,1920,4))
image = Image.fromarray(pixel_array, mode = "RGBA")
canvas = aggdraw.Draw(image)

# path for a square
pathstring = "M825 405 C915 405 1005 405 1095 405 C1095 495 1095 585 1095 675 C1005 675 915 675 825 675 C825 585 825 495 825 405 Z"
symbol = aggdraw.Symbol(pathstring)
pen = aggdraw.Pen("#00ff00", 5)
fill = aggdraw.Brush("#ff0000", 127)

canvas.symbol((0, 0), symbol, pen, fill)
canvas.flush()

image2 = Image.fromarray(pixel_array, mode = "RGBA")

image2.show()

Problem when executing setup.py

My system

Windows 7 Ultimate 64 bit

Python 2.7.15
pip 10.0.1 from c:\python27\lib\site-packages\pip (python 2.7)

Installed the following modules already (I'm trying to use manim)

Package       Version
------------- -------
colour        0.1.2
numpy         1.11.1
opencv-python 3.1.0.0
Pillow        3.4.2
pip           10.0.1
progressbar   2.3
scipy         0.17.1
setuptools    39.0.1
tqdm          4.7.1`

The problem

I'm having trouble when executing setup.py. The following message is what I get.


=== freetype support disabled
running install
running build
running build_ext
building 'aggdraw' extension
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\BIN\amd64\cl.exe /c /nolog
o /Ox /MD /W3 /GS- /DNDEBUG -Iagg2/include -IC:\Python27\include -IC:\Python27\P
C /Tpaggdraw.cxx /Fobuild\temp.win-amd64-2.7\Release\aggdraw.obj
aggdraw.cxx
c:\python27\include\pyconfig.h(239) : fatal error C1083: Cannot open include fil
e: 'basetsd.h': No such file or directory
error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio 9.0\\VC\\BIN\\a
md64\\cl.exe' failed with exit status 2

C:\Python27\aggdraw-64bits-master>python setup.py install
=== freetype support disabled
running install
running build
running build_ext
building 'aggdraw' extension
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\BIN\amd64\cl.exe /c /nolog
o /Ox /MD /W3 /GS- /DNDEBUG -Iagg2/include -IC:\Python27\include -IC:\Python27\P
C /Tpaggdraw.cxx /Fobuild\temp.win-amd64-2.7\Release\aggdraw.obj
aggdraw.cxx
**c:\python27\include\pyconfig.h(239) : fatal error C1083: Cannot open include fil
e: 'basetsd.h': No such file or directory
error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio 9.0\\VC\\BIN\\a
md64\\cl.exe' failed with exit status 2**

What I have tried to fix it

I have downloaded and installed both Microsoft Visual C++ 2008 Express (this one) and Microsoft Windows SDK for Windows 7 and .NET Framework 3.5 SP1 (this one).

Made a new renamed copy of ...\Microsoft Visual Studio 9.0\VC\bin\vcvars64.bat to ...\VC\bin\amd64\vcvarsamd64.bat.

Added C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin to PATH.

Then
C:\Python27\aggdraw-64bits-master>python setup.py install and got the error you saw above

No arc symbols?

The SVG spec apparently supports specification of arcs, but when I try:

pathstring = "M0,0 a .5 .5 0 0 1 1 0 z"
symbol = aggdraw.Symbol(pathstring)

I get the error:

ValueError: unknown path command 'A'

Am I doing something wrong, or does aggdraw not support arcs?

DOC: conda install has no freetype support on Windows

Hello. I realized now that README recommends install from source for all platforms. However, by intuition, I first tried conda install (and also pip install at some point, I think). While it installed successfully on Windows, it did not have freetype support. To get that to work on Windows, I did this:

  1. Clone the aggdraw repository.
  2. Modify setup.py like mentioned in https://stackoverflow.com/questions/17770413/aggdraw-cannot-load-font-no-text-renderer
  3. python setup.py install

I am documenting in here in case you wish to add a warning for Windows users. Thanks.

Line anti-aliasing issues due to missing sRGB mishandling

Hi,

I just started using aggdraw, and it definitively draws nicer lines than PIL for my application (opacity and antialiassing does help), but I noticed still imperfection and possibly a bug:

dump

Be sure to open it and view at 100% scale.

The issue is visible as uneven luminosity of the lines. I.e. if you look at the top center, and then count 3 or 4 lines to the right, it looks to be oscillating in brightness.

I am not talking about a Moiré pattern that appears in the center, that is somehow expected, but possibly is related partially. I am talking about straight slightly diagonal lines far from the center.

It feels like maybe the sRGB is not used correctly? Which is a bit strange, as I see there is support for gamma, linear and sRGB in the aggdraw.

# Python 3.8.1
from PIL import Image, ImageDraw  # Pillow 6.2.1
import aggdraw  # Version 1.3.11
w, h = 1024, 1024
img = Image.new("RGB", (w, h))
img1 = aggdraw.Draw(img)
img1.setantialias(True)
pen = aggdraw.Pen("white", 1.0, opacity=127)

img1.line(xyxyxy, pen)
# ...

img1.flush()
img.save("dump.png")
img.show()

With opacity=255 effect is visible even more:

dump

dump

When drawing a similar type of lines (width and angle) for example in Inkscape, I see much more uniform luminance and the oscillations are there, but essentially invisible.

1.3.1 core dumps in aggdraw.Pen() when run in xenial docker image

aggdraw 1.3.1 core dumps when run in a Xenial docker image. It works
fine with aggdraw 1.3 in a docker image, and both versions work find
when run natively.

I've isolated it to a call to aggdraw.Pen(). A docker image that
reproduces the problem is pasted below. Run it with
"gitlab-ci-multi-runner exec docker test".

image: ubuntu:xenial
test:
script:
- apt-get update
- apt-get -y install python-pip
- pip install 'aggdraw==1.3.1' pillow
- python -c "from PIL import Image;import aggdraw; main = Image.new('RGB', (480, 1024), 'white'); d = aggdraw.Draw(main); p = aggdraw.Pen((90,) * 3, 0.5)"

Couldn't install, seems to be a problem with pathing to freetype

Ok so I moved all the files from my install of freetype from this directory /usr/local/Cellar/freetype/2.5.3_1/include/freetype2
Put them in the folder /Users/username/Downloads/aggdraw-master/agg2/font_freetype
Then to install it on OSX sudo ARCHFLAGS=-Wno-error=unused-command-line-argument-hard-error-in-future easy_install /Users/username/Downloads/aggdraw-master

Add svg support from agg-svg

A few years back I extended the svg support of agg to be a bit more usable, see http://github/dov/agg-svg . It should be trivial to add a wrapper to aggdraw for this. Note that this adds one more dependency, expat. The question is whether this should be included in aggdraw, or perhaps in another module.

freetype not linked correctly in latest macOS Python 3.11 wheels (1.3.17 and 1.3.18)

Starting with 1.3.17 the wheels for Python 3.11 on macOS are not linked correctly:

    import aggdraw
ImportError: dlopen(/Users/alex/SOMEPATH/venv/lib/python3.11/site-packages/aggdraw.cpython-311-darwin.so, 0x0002): symbol not found in flat namespace '_FT_Attach_File'

When using otool on the .so file:

(venv) alex@Trinity site-packages % otool -L aggdraw.cpython-311-darwin.so
aggdraw.cpython-311-darwin.so:
	/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 1200.3.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1311.0.0)

one can see that libfreetype is not listed, hence the missing symbols.

The latest working wheels for this configuration was for version 1.3.16.

I suspect it is related to these changes here: 0c5124c.

Misleading information in the document

https://aggdraw.readthedocs.io/en/latest/

This will install the older version that is not published in Pypi.

Ekran Resmi 2023-09-19 23 44 39

Why hasn't this latest repo been released for years? I use aggdraw for the drawing library I wrote, I wish the new version was active. For example, the Draw.polygon() method always closes the entered coordinates. It would be better in terms of performance if there was a method that drew the entered coordinate sequence as an open-ended path.

Ekran Resmi 2023-09-19 23 56 16

Convert selftest.py to unit tests

The tests that are run on the continuous integration environments and by developers to prove that nothing has been broken are all stored in the selftest.py script in the root of the repository. I would like these converted to using pytest or at least unittest. The module should probably be moved to a tests directory and if possible they should be added to setup.py as a test_suite so they can be run from CI as python setup.py test.

Python 3.12 support

Some of the APIs used in aggdraw.cxx have been removed in Python 3.12 and the library doesn't compile anymore.

In file included from agg2/font_freetype/agg_font_freetype.h:28,
                 from aggdraw.cxx:86:
agg2/include/agg_scanline_storage_bin.h: In member function ‘unsigned int agg::scanline_storage_bin::byte_size() const’:
agg2/include/agg_scanline_storage_bin.h:247:38: warning: unused variable ‘sp’ [-Wunused-variable]
  247 |                     const span_data& sp = m_spans[span_idx++];
      |                                      ^~
aggdraw.cxx: In function ‘int text_getchar(PyObject*, int, long unsigned int*)’:
aggdraw.cxx:338:25: error: ‘PyUnicode_AS_UNICODE’ was not declared in this scope; did you mean ‘PyUnicode_AsUCS4’?
  338 |         Py_UNICODE* p = PyUnicode_AS_UNICODE(string);
      |                         ^~~~~~~~~~~~~~~~~~~~
      |                         PyUnicode_AsUCS4
aggdraw.cxx:339:20: error: ‘PyUnicode_GET_SIZE’ was not declared in this scope; did you mean ‘PyDict_GET_SIZE’?
  339 |         int size = PyUnicode_GET_SIZE(string);
      |                    ^~~~~~~~~~~~~~~~~~
      |                    PyDict_GET_SIZE

MNT: Stop using ci-helpers in appveyor.yml

To whom it may concern,

If you are using https://github.com/astropy/ci-helpers in your appveyor.yml , please know that the Astropy project has dropped active development/support for Appveyor CI. If it still works, good for you, because we did not remove the relevant files (yet). But if it ever stops working, we have no plans to fix anything for Appveyor CI. Please consider using native Windows support other CI, e.g., Travis CI (see https://docs.travis-ci.com/user/reference/windows/). We apologize for any inconvenience caused.

If this issue is opened in error or irrelevant to you, feel free to close. Thank you.

xref astropy/ci-helpers#464

aggdraw.Draw, aggdraw.Pen, aggdraw.Brush, etc... are not extendable (apparently)

aggdraw.Draw, aggdraw.Pen, aggdraw.Brush, and the other classes are not sub-classable / extendable (apparently.)

They are not even considered classes at all by python. Taking the type of an instance dos deliver something that are considered classes. But they are not extendable nor typable.

Can I request that some way to subclass the classes be provided. Or some hooks to enable subclassing.

Any details needed for this request please ask.

The why, is because it is very desirable in many situations to sub-class those classes. Wrapping and proxying them will work except that doing an instance class check still becomes impossible.

Thank you.

PyPy3.8 support

We can successfully install aggdraw on pypy3.7 (v7.3.7) and on CPython 3.8, but not pypy3.8 (v7.3.7). Does this output mean anything to anyone?

Preparing metadata (setup.py) ... done
Building wheels for collected packages: aggdraw
  Building wheel for aggdraw (setup.py) ... error
  ERROR: Command errored out with exit status 1:
   command: /home/barnesc/.pyenv/versions/pypy3.8-7.3.7/envs/cm-pypy38/bin/python -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-_7xqrttx/aggdraw_bcd0f8bd313f41a4882c9a0461bd9edd/setup.py'"'"'; __file__='"'"'/tmp/pip-install-_7xqrttx/aggdraw_bcd0f8bd313f41a4882c9a0461bd9edd/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdist_wheel -d /tmp/pip-wheel-jk4w5it5
       cwd: /tmp/pip-install-_7xqrttx/aggdraw_bcd0f8bd313f41a4882c9a0461bd9edd/
  Complete output (41 lines):
  Trying freetype-config to find freetype library...
  Using ctypes to find freetype library...
  === freetype found: '/usr'
  running bdist_wheel
  running build
  running build_ext
  building 'aggdraw' extension
  creating build
  creating build/temp.linux-x86_64-3.8
  creating build/temp.linux-x86_64-3.8/agg2
  creating build/temp.linux-x86_64-3.8/agg2/src
  creating build/temp.linux-x86_64-3.8/agg2/font_freetype
  gcc -pthread -DNDEBUG -O2 -fPIC -DVERSION=1.3.12 -DHAVE_FREETYPE2 -Iagg2/include -Iagg2/font_freetype -I/usr/include -I/usr/include/freetype -I/usr/include/freetype2 -I/home/barnesc/.pyenv/versions/pypy3.8-7.3.7/envs/cm-pypy38/include -I/home/barnesc/.pyenv/versions/pypy3.8-7.3.7/include/pypy3.8 -c aggdraw.cxx -o build/temp.linux-x86_64-3.8/aggdraw.o
  In file included from agg2/include/agg_conv_transform.h:23,
                   from aggdraw.cxx:81:
  agg2/include/agg_trans_affine.h: In member function ‘void agg::trans_affine::transform(double*, double*) const’:
  agg2/include/agg_trans_affine.h:254:25: warning: ISO C++17 does not allow ‘register’ storage class specifier [-Wregister]
    254 |         register double tx = *x;
        |                         ^~
  agg2/include/agg_trans_affine.h: In member function ‘void agg::trans_affine::inverse_transform(double*, double*) const’:
  agg2/include/agg_trans_affine.h:262:25: warning: ISO C++17 does not allow ‘register’ storage class specifier [-Wregister]
    262 |         register double d = determinant();
        |                         ^
  agg2/include/agg_trans_affine.h:263:25: warning: ISO C++17 does not allow ‘register’ storage class specifier [-Wregister]
    263 |         register double a = (*x - m4) * d;
        |                         ^
  agg2/include/agg_trans_affine.h:264:25: warning: ISO C++17 does not allow ‘register’ storage class specifier [-Wregister]
    264 |         register double b = (*y - m5) * d;
        |                         ^
  aggdraw.cxx: At global scope:
  aggdraw.cxx:269:1: error: invalid conversion from ‘printfunc’ {aka ‘int (*)(_object*, FILE*, int)’} to ‘Py_ssize_t’ {aka ‘long int’} [-fpermissive]
    269 | };
        | ^
        | |
        | printfunc {aka int (*)(_object*, FILE*, int)}
  aggdraw.cxx:310:1: error: invalid conversion from ‘printfunc’ {aka ‘int (*)(_object*, FILE*, int)’} to ‘Py_ssize_t’ {aka ‘long int’} [-fpermissive]
    310 | };
        | ^
        | |
        | printfunc {aka int (*)(_object*, FILE*, int)}
  error: command 'gcc' failed with exit status 1
  ----------------------------------------
  ERROR: Failed building wheel for aggdraw
  Running setup.py clean for aggdraw
Failed to build aggdraw
Installing collected packages: aggdraw
    Running setup.py install for aggdraw ... error
    ERROR: Command errored out with exit status 1:
     command: /home/barnesc/.pyenv/versions/pypy3.8-7.3.7/envs/cm-pypy38/bin/python -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-_7xqrttx/aggdraw_bcd0f8bd313f41a4882c9a0461bd9edd/setup.py'"'"'; __file__='"'"'/tmp/pip-install-_7xqrttx/aggdraw_bcd0f8bd313f41a4882c9a0461bd9edd/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-7kzeod5l/install-record.txt --single-version-externally-managed --compile --install-headers /home/barnesc/.pyenv/versions/pypy3.8-7.3.7/envs/cm-pypy38/include/site/python3.8/aggdraw
         cwd: /tmp/pip-install-_7xqrttx/aggdraw_bcd0f8bd313f41a4882c9a0461bd9edd/
    Complete output (41 lines):
    Trying freetype-config to find freetype library...
    Using ctypes to find freetype library...
    === freetype found: '/usr'
    running install
    running build
    running build_ext
    building 'aggdraw' extension
    creating build
    creating build/temp.linux-x86_64-3.8
    creating build/temp.linux-x86_64-3.8/agg2
    creating build/temp.linux-x86_64-3.8/agg2/src
    creating build/temp.linux-x86_64-3.8/agg2/font_freetype
    gcc -pthread -DNDEBUG -O2 -fPIC -DVERSION=1.3.12 -DHAVE_FREETYPE2 -Iagg2/include -Iagg2/font_freetype -I/usr/include -I/usr/include/freetype -I/usr/include/freetype2 -I/home/barnesc/.pyenv/versions/pypy3.8-7.3.7/envs/cm-pypy38/include -I/home/barnesc/.pyenv/versions/pypy3.8-7.3.7/include/pypy3.8 -c aggdraw.cxx -o build/temp.linux-x86_64-3.8/aggdraw.o
    In file included from agg2/include/agg_conv_transform.h:23,
                     from aggdraw.cxx:81:
    agg2/include/agg_trans_affine.h: In member function ‘void agg::trans_affine::transform(double*, double*) const’:
    agg2/include/agg_trans_affine.h:254:25: warning: ISO C++17 does not allow ‘register’ storage class specifier [-Wregister]
      254 |         register double tx = *x;
          |                         ^~
    agg2/include/agg_trans_affine.h: In member function ‘void agg::trans_affine::inverse_transform(double*, double*) const’:
    agg2/include/agg_trans_affine.h:262:25: warning: ISO C++17 does not allow ‘register’ storage class specifier [-Wregister]
      262 |         register double d = determinant();
          |                         ^
    agg2/include/agg_trans_affine.h:263:25: warning: ISO C++17 does not allow ‘register’ storage class specifier [-Wregister]
      263 |         register double a = (*x - m4) * d;
          |                         ^
    agg2/include/agg_trans_affine.h:264:25: warning: ISO C++17 does not allow ‘register’ storage class specifier [-Wregister]
      264 |         register double b = (*y - m5) * d;
          |                         ^
    aggdraw.cxx: At global scope:
    aggdraw.cxx:269:1: error: invalid conversion from ‘printfunc’ {aka ‘int (*)(_object*, FILE*, int)’} to ‘Py_ssize_t’ {aka ‘long int’} [-fpermissive]
      269 | };
          | ^
          | |
          | printfunc {aka int (*)(_object*, FILE*, int)}
    aggdraw.cxx:310:1: error: invalid conversion from ‘printfunc’ {aka ‘int (*)(_object*, FILE*, int)’} to ‘Py_ssize_t’ {aka ‘long int’} [-fpermissive]
      310 | };
          | ^
          | |
          | printfunc {aka int (*)(_object*, FILE*, int)}
    error: command 'gcc' failed with exit status 1
    ----------------------------------------
ERROR: Command errored out with exit status 1: /home/barnesc/.pyenv/versions/pypy3.8-7.3.7/envs/cm-pypy38/bin/python -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-_7xqrttx/aggdraw_bcd0f8bd313f41a4882c9a0461bd9edd/setup.py'"'"'; __file__='"'"'/tmp/pip-install-_7xqrttx/aggdraw_bcd0f8bd313f41a4882c9a0461bd9edd/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-7kzeod5l/install-record.txt --single-version-externally-managed --compile --install-headers /home/barnesc/.pyenv/versions/pypy3.8-7.3.7/envs/cm-pypy38/include/site/python3.8/aggdraw Check the logs for full command output

Resolve differences after agg 2.2 and agg 2.4 migration

In #50 aggdraw master was updated to use the agg C++ library by @dov. Later it was pointed out by @a-hurst that there were some differences between aggdraw using agg 2.2 and aggdraw using 2.4 in issue #61 which was resolved in #62. At the end of #61 @a-hurst and I started discussing some of the other differences we were noticing with the C++ library changes. As it stands, the master branch (unreleased) does not produce matching results to the aggdraw 1.3.x release. I'd like to figure this out once and for all so I've broken my example from the pycoast package down in to a simpler case. Here is the big pycoast-based result difference from #61:

aggdraw 1.3.x:

image

aggdraw 1.4 (master):

image

Look at the smaller polygons (islands) for the biggest difference. If I strip this down to this code example:

import aggdraw
from PIL import Image
import os
width = 200
height = 200
img = Image.new('RGB', (width, height))
draw = aggdraw.Draw(img)

pen = aggdraw.Pen('white', 1, 255)
coordinates = [166.56794437411008, 77.25389224364426, 48.00197334018185, 78.96339024123063, 81.28185670937546, 83.30298429919458, 89.3666036554605, 154.98793226592443, 88.69627544716832, 84.44108529130517]
draw.line(coordinates, pen)
draw.flush()
img.save('new.png')

And you run that with both versions (obviously change the filename), you will see extremely small differences like the below.

aggdraw 1.3.x:

old

aggdraw 1.4 (master):

new

Note that including the change for line:

as suggested by @a-hurst in #61 from 1.0 to 0.5 doesn't seem to have an effect on this use case.

So something has changed and on the small scale it is almost impossible to see but for many lines (the coastlines above) it is much more apparent. Does anyone have any ideas what other values we could play with to make aggdraw produce equivalent results? @a-hurst sorry if I'm forgetting some suggestion from #61.

Providing pre-compiled binaries

One of the recurring issues I've seen in the past among users of aggdraw has been with the lack of precompiled binaries and the difficulties and errors relating to compiling.
With this as the new aggdraw for the future, it would be a very good thing for usability to provide precompiled binaries in the form of wheels on the PyPI site so that it can easily be installed via pip install aggdraw without requiring the user to have a compiler and all the errors that can arise from that.

Unable to load font on Debian 9 with Python 3

After using Aggdraw for a few days, I got the following error when trying to instantiate a Font object: IOError: cannot load font (no text renderer)

I have excluded a missing font or other obvious causes, and tried to rebuild the package using the FREETYPE_ROOT = "/usr/local" suggestion. But the error remained.

Strangely enough, the problem did not exist on my other computer. Thus I suspected that the error could be caused by a system depended problem. I eventually resorted to reinstalling my computer (which I actually needed to do anyway), but the problem remained.

After installing aggdraw as a super user (on Debian 9), the error seem to be gone... Meaning that there could be a problem in the package that results in it being unable to handle a local install of aggdraw (instead of global). It might help others if this problem is documented, and it might be solvable...?

Technically speaking: pip3 install aggdraw results in mentioned error, while sudo pip3 install aggdraw works fine.

Segmentation fault debugging aggdraw.Pen

Using aggdraw 1.3.10 in arch linux with cpython 3.7, I get a segmentation fault every time my debugger tries to inspect an aggdraw.Pen object. I tried it debugging with pudb3, with vscode python extension and with pycharm. Here's a minimal code:

from PIL import Image
import aggdraw


def main():
    image = create_image()
    image.show()


def create_image():
    image = Image.new('RGBA', (1024, 1024))
    draw = aggdraw.Draw(image)
    pen = aggdraw.Pen('red', 20)
    draw.line((0, 0, 100, 100), pen)
    draw.flush()
    return image


if __name__ == '__main__':
    main()

Put a breakpoint in the line draw.line((0, 0, 100, 100), pen) and try to inspect pen in your debugger to see if you can reproduce it.

I checked some issues here, and found #22 that also mentions segmentation faults related to Pen, but it seems to be a different issue, and already solved.

And less important, but just to mention it, I don't really want to inspect this object. It's just that debuggers usually show all local variables when you break, so every time I put a breakpoint with a local Pen object, my session crashes and this is the real problem

aggdraw 1.3.9 API change?

I recently upgraded my old legacy aggdraw to the newest 1.3.9 PyPI version produced by this project (super happy about that and the precompiled wheels btw, a simple pip install did the trick).
One thing I noticed was that my existing code using the Draw.path() method failed. It seems that in this new version, the args to path() have switched from what was previously:

Draw.path(xy, pathobj, pen, brush)

...to the new 1.3.9:

Draw.path(pathobj, xy, (pen, brush))

The path() docstring still refers to the old way of doing it. Was this API change intentional / is it documented anywhere, or was it an inadvertent mistake from some of the recent AGG version portings?

Diferences between pip version and source-compiled version

Hi,

I am having an API difference between the version installed using pip and the version installed by hand. I found that if I install aggdraw using pip install aggdraw, I have the next issue:

Traceback (most recent call last):
(...) 
  File "/opt/canvashanddraw/drawhelper.py", line 134, in _draw_points
    pen = aggdraw.Pen(color, ((1.0 - float(smoothWidth)) * float(actualLineWidth)) + (float(self._options.lineWidth) * float(smoothWidth)), linecap = 2, linejoin = 2)
TypeError: Pen() takes at most 3 arguments (4 given)

The help for the class using help(aggdraw.Pen) on this version:

Help on built-in function Pen in module aggdraw:

Pen(...)
    Creates a Pen object.

    Parameters
    ----------
    color : tuple or str or int
        Pen color. This can be a color tuple (R, G, B) or (R, G, B, A),
        a CSS-style color name, or a color integer (0xaarrggbb).
    width : int, optional
        Pen width. Default 1.
    opacity : int, optional
        Pen opacity. Default 255.

But if I follow the process for installing it from source:

$ git clone https://github.com/pytroll/aggdraw
$ cd aggdraw
$ python setup.py build_ext -i
$ python setup.py install

The code works as expected, according to the docs

The help for the class using help(aggdraw.Pen):

Help on built-in function Pen in module aggdraw:

Pen(...)
    Creates a Pen object.

    Parameters
    ----------
    color : tuple or str or int
        Pen color. This can be a color tuple (R, G, B) or (R, G, B, A),
        a CSS-style color name, or a color integer (0xaarrggbb).
    width : int, optional
        Pen width. Default 1.
    opacity : int, optional
        Pen opacity. Default 255.
    linejoin : int, optional
        Type of line_join. Types are 0=miter_join
        1=miter_join_revert; 2=round_join; 3=bevel_join;
        4=miter_join_round. Default 0 (miter join).
    linecap : int, optional
        Type of linecap. Types are 0=butt_cap;
        1=square_cap; 2=round_cap. Default 1 (butt cap).
    miterlimit : float, optional
        Type of miterlimit. Default 4.0.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.