Repository navigation
Parameters for Image.open() #569
Description
Activity
I am +1, I think, but @wiredfool will need to comment. Any precedent in any other API for doing this?
I want to look carefully at the code before endorsing an api change. I'm at a tentative +1.
@aclark4life The
Image.save()API already has arguments; of course, in that case, you specify the format, so it’s obvious what they mean. Contrast withImage.open(), where you don't necessarily know the type of the file you’re loading; in that case, you may still wish to pass arguments that matter to you if the file turns out to be of a particular type, but we don’t want type-specific arguments to clash.I was going to propose something like the following:
im = Image.open(fp, mode='r', size=None, format_args={})We already have the
modeargument;sizewould be a 2-tuple of pixel dimensions, whileformat_argsis a dictionary mapping format names to format-specific-argument dictionaries. A JPEG 2000 themed example might be:im = Image.open(fp, mode='r', format_args={ 'JPEG2000': { 'layers': 4 } })the idea being that if
fpturns out to be a JPEG 2000 file, the arguments in the relevant sub dictionary will apply. If it isn’t a JPEG 2000, it will be loaded without regard to those arguments. An alternative might be to use a flat dictionary with dot notation, e.g.im = Image.open(fp, mode='r', format_args={ 'JPEG2000.layers': 4 })Perhaps slightly easier to read and write?
Additionally, the
sizeargument should always be passed to the plugin, because JPEG and JPEG 2000 are — in some cases — capable of loading and processing just enough data to obtain an image of the requested size.Maybe this can go in 2.5.0 due in 3 months
We already have the mode argument
This is not truth. Mode is not "image mode", this is "file read mode" and it is always "r". First lines of
open():if mode != "r": raise ValueError("bad mode %r" % mode)
I strongly disagree about passing
modeandsizein constructor because:There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch.Currently that way is opening image and calling
draft(). This have many advantages: you can open image, check it dimensions, mode, some options and even verify sometimes before loading an image into memory.I agree what there should be some way to configure decoder, but
format_args={'JPEG2000': {'layers': 4}}looks too ugly. Maybe something like this?i = Image.open(image) i.draft(mode, size) i.configure_decoder(jpeg2000={'layers': 4})
I'm not sure I understand your point about the
modeargument. Maybe you’re confused and think I was proposing using it for the image mode, but indeed I was not.As far as the
draftmethod goes, it looks like you’re right that that’s the way to go here — however, this is not documented particularly well and the documentation could do with an overhaul in this regard. Right now there is code out there that is not usingdraftbut instead pokes about directly in the Image object to set the desired mode and size.I like the
configure_decodermethod also; it has less visual noise than using an explicit dictionary.I created #1349 as a suggestion, but did not progress due to lack of a specific use for the API.
im = Image.open(fp, mode='r', format_args={ 'JPEG2000': { 'layers': 4 } })
in this what is
fp? what is the value for fp? is that mandatory?@Shivahk027
fpis short for 'file pointer'. It is one way of referencing the image that is being opened.from PIL import Image with open("Tests/images/hopper.png", "rb") as fp: im = Image.open(fp, mode='r', format_args={ 'JPEG2000': { 'layers': 4 } })
Another way is just to use the path of the image.
from PIL import Image im = Image.open("Tests/images/hopper.png", mode='r', format_args={ 'JPEG2000': { 'layers': 4 } })
For more information, see https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.open
Note however that
format_argsis still under discussion here, and has not been implemented.Let's close this issue as it's not really progressed in many years. We can reopen if necessary.
There are a few file formats that would benefit from the ability to pass parameters through the
Image.open()method. This needs to be thought about carefully because there are clearly some parameters that are generic (e.g.mode,sizeanddpiarguments, which could cause conversion or resizing, all of which can in some instances be supported directly by the image file plugin), while others are very format specific (e.g. the number of quality layers to load in a JPEG 2000 image).As of today, some image file plugins are essentially relying on the laziness of PIL’s loading machinery so that the user can call
openand subsequently set some properties on the returned object beforeloadgets called. This is, IMO, pretty nasty.(I might be up for fixing this myself, but I want to file a bug report before doing any coding because I want the opinions of others on how this should work.)