libvips / pyvips

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

Convenience methods for Pillow integration #486

Open jonashaag opened 3 months ago

jonashaag commented 3 months ago

Proposal: Add convenience integration with PIL/Pillow, eg. converting back and forth. Something along the lines of

pyvips.Image.from_pil(pil_img)

and

vips_img.pil()  # -> PIL.Image.Image

Happy to contribute a first draft if this is accepted.

jcupitt commented 3 months ago

Hi @jonashaag, sure this sounds useful. What would it add over going via numpy?

jonashaag commented 3 months ago

Probably nothing on the technical side, just a few convenience methods.

jcupitt commented 3 months ago

It should be pretty easy right now:

import PIL.Image
pil_image = PIL.Image.new('RGB', (60, 30), color = 'red')
image = pyvips.Image.new_from_array(pil_image)

and:

import pyvips
import PIL.Image
image = pyvips.Image.black(100, 100, bands=3)
pil_image = PIL.Image.fromarray(image.numpy())

I don't know what PIL does with image metadata, maybe there's a simple way to bring that over as well?

jonashaag commented 3 months ago

You're right that it's already quite simple... my suggestion of from_pil is the same as new_from_array (it's just a bit confusingly named for that purpose), and my convenience method for the other direction would be

    def pil(self):
        try:
            from PIL import Image
        except ModuleNotFoundError as e:
            raise ModuleNotFoundError("Pillow must be installed") from e

        return Image.fromarray(self.numpy())

Honestly not sure anymore if it's worth adding this because it's a very thin wrapper...