libvips / pyvips

python binding for libvips using cffi
MIT License
642 stars 49 forks source link

inplace operations #256

Open rvalieris opened 3 years ago

rvalieris commented 3 years ago

hello, I need to draw many rectangles on a image, I understand pyvips copies the image in every operation so I'm wondering how can I bypass that, the docs say:

If you want to avoid the copies, you’ll need to call drawing operations yourself.

can you give me an example on how to call the drawing operations directly ? thanks.

jcupitt commented 3 years ago

Hello @rvalieris,

The ruby binding has a new feature to handle this and we plan to add this to pyvips as well. It would offer the best solution, I think:

https://libvips.github.io/libvips/2021/03/08/ruby-vips-mutate.html

I'm a little unsure what the best Python equivalent would be, perhaps:

def my_mutate_function(mutable):
    for i in range(1000):
        mutable.draw_circle_direct ...

y = x.mutate(my_mutate_function)

You could use a lambda too, but they don't work well for complex code. draw_circle_direct would be a no-copy version of draw_circle which only existed for mutable images.

rvalieris commented 3 years ago

thanks I will look into the ruby bindings.

as for the proposed API, I guess the most similar to ruby would be using a context manager: https://docs.python.org/3/reference/datamodel.html#context-managers although, if you want to return the modified image at the end, its not clear to me how that would work.

jcupitt commented 3 years ago

I agree, I don't think a context manager would work, unfortunately.

Ruby is a little slower than Python and needs a lot more memory, unfortunately. Though of course fast enough is fast enough.