TypeError: initializer for ctype 'unsigned int *' must be a cdata pointer, not bytes

307 views
Skip to first unread message

poster

unread,
Mar 18, 2019, 2:29:14 PM3/18/19
to python-cffi

Hello,


I try to convert PIL image to leptonica PIX. Here is my code python 3.6:


import os, cffi
from PIL import Image

# initialize leptonica
ffi
= cffi.FFI()
ffi
.cdef("""
    typedef int           l_int32;
    typedef unsigned int  l_uint32;
    struct                Pix;
    typedef struct Pix    PIX;
    PIX * pixCreate       (int width, int height, int depth);
    l_int32 pixSetData    (PIX *pix, l_uint32 *data);
"""
)
leptonica
= ffi.dlopen(os.path.join(os.getcwd(), "leptonica-1.78.0.dll"))

# convert PIL to PIX
im
= Image.open("test.png").convert("RGBA")
depth
= 32
width
, height = im.size
data
= im.tobytes("raw", "RGBA")
pixs
= leptonica.pixCreate(width, height, depth)
leptonica
.pixSetData(pixs, data)


leptonica.pixSetData failes with message: TypeError: initializer for ctype 'unsigned int *' must be a cdata pointer, not bytes.
How to get cdata pointer to bytes object (data)?


Armin Rigo

unread,
Mar 19, 2019, 12:00:01 PM3/19/19
to pytho...@googlegroups.com
Hi,

On Mon, 18 Mar 2019 at 19:29, poster <zdpo...@gmail.com> wrote:
> leptonica.pixSetData(pixs, data)
>
> leptonica.pixSetData failes with message: TypeError: initializer for ctype 'unsigned int *' must be a cdata pointer, not bytes.
> How to get cdata pointer to bytes object (data)?

Assuming you have the recent cffi 1.12, you can do:

laptonica.pixSetData(pixs, ffi.from_buffer("l_uint32[]", data))

The backward-compatible way is more complicated because we need to
make sure an intermediate object stays alive:

p = ffi.from_buffer(data)
laptonica.pixSetData(pixs, ffi.cast("l_uint32 *", p))
# 'p' must still be alive here after the call, so put it in a variable above!


A bientôt,

Armin.

poster

unread,
Mar 20, 2019, 3:42:05 AM3/20/19
to python-cffi
Thanks!
Reply all
Reply to author
Forward
0 new messages