New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Writing your own image plugin documentation missing information #4818
Comments
I can quickly answer the first question:
The second way is better. For example, with
from PIL import Image
import SpamImagePlugin
with Image.open("1.spam") as im:
print(im)
print(im.format)
print(im.format_description)
$ python 1.py
<SpamImagePlugin.SpamImageFile image mode=1 size=1x1 at 0x1023D5E50>
SPAM
Spam raster image |
Are you writing a decoder in C, or in Python? You've referred to https://pillow.readthedocs.io/en/stable/handbook/writing-your-own-file-decoder.html#the-raw-decoder
I don't think that's the same as saying that you bear the responsibility of mapping your data to PIL's internal pixel layout. The 'raw mode' is how the image data is stored in the file. Pillow converts this into a given 'mode', standardising things a bit. If you look at the list of unpackers, you can see that for 32 bits, "LA;16B", "RGBA", "RGBa", "BGRa", "RGBA;I", "RGBA;L", "BGRA", "ARGB", "ABGR", "YCCA;P" are all converted into "RGBA". Much easier to deal with in Pillow's conversation operations. However, it is worth considering that the documentation also states
Do you think that your mode isn't covered by anything already in Pillow? |
Hello, Thanks for answering, @radarhere : I'm trying in Python, I'm not familiar enough with C. From what i gathered
The format I'm working on does not correspond to the ones listed in the pillow mode list, it is represented as a line by line sequence with colors separated in a different order as follow : Lets take an image of 100 pixel width and 50 pixels height (or 50 lines)
So i think i need to loop by 400 bytes and group it by pixel (CMYK) to put it in pillow in memory image object or to feed it as a file to the raw decoder. I did the mapping and i can print it to the console but i didn't yet figure how to feed it to pillow. When i use the Image.new() followed by Image.putdata() instructions in the decoder the Image.tobytes() always returns a sequence of zeros as if i didn't use the putdata() one. I'll let you know if i find a way. |
That actually sounds like "CMYK;L", except with a different order - YMCK;L. Maybe this is too simple for your situation because I don't have the specifics, but I think you could just write a plugin loading CMYK;L and then swap the channels. |
Hi, I have a similar situation so I'm posting here, guessing opening another issue would be redundant. I'm trying to write my own Python plugin to work with a somewhat exotic image format and also found the documentation lacking. The format details are not relevant. Following the For that, I found a related PR that decodes ASCII/Plain PPM and so was able to get a basic decoder for my format working. However, there are some things I don't understand:
Suppose inside Documentation on writing your own encoder would also be nice. I have trouble understanding the intended use of the I may well be that I am underqualified to tackle this. Either way, any help would be appreciated. |
I believe |
Thank you for your swift reply. I agree that example should totally be mentioned in the docs. I'm having some issues setting the Diving a bit deeper into the |
The raw decoder takes two parameters: the image mode and the raw mode (specified in the first and second columns of the Lines 688 to 690 in 2d6e51e
Do you mean 1 bit per pixel or 1 byte per pixel? Since The message could be a bit clearer, perhaps |
I decoded my (bitonal) image to one byte per pixel. It's just a I seem to have mixed up the image and raw modes a bit. Maybe that distinction should be made more explicit in the Upon further experimentation, I found that either
yield more or less the same result. The first option considers However, mixing inconsistent modes (ie: Thank you very much for your help. I think I've got it now. Should I open a PR with my suggested modifications to the documentation? Edit: I misunderstood a part of your comment. |
Yes, it sounds like your image is 1 bit per pixel stored in individual bytes, which is The one pixel per byte comment for image |
Let me try and round up the requests for better documentation
It seems to be documented well enough at in Writing Your Own Image Plugin - which is exactly what you were doing when you needed this information? There is also a request for an error message to be clearer. I've created #5457 for that. |
Perhaps the
Yes. Playing around I managed to get a decoder working with
Yes.
This would be a very nice perk. Although by the looks of it it's gonna need lots of writing to be useful.
Also yes.
At the moment I wrote that I was asking myself, why a list of descriptors? when would I need more than one? I was obviously not seeing the big picture, but the docs could at least make a case for the necessity of the list and refer to a format implementation that makes use of multiple tiles. I would add:
Thanks for following up on this issue. |
This is hard to debug without a specific example. This following code does not return zeros. from PIL import Image
im = Image.new("L", (256, 256))
im.putdata(list(range(256)) * 256)
print(im.tobytes())
I don't quite see why there is confusion between If I'm following correctly, then you settled on using I've created PR #6094 to document this. |
I've added a comment in #6094 about this providing more freedom, but also possibly leading to more memory usage, depending on how your codec is written.
I've pushed a commit to #6094 to remove the experimental label. I've also pushed commits to #6094 adding a note using
I've pushed a commit to #6094 linking to PsdImagePlugin, which uses multiple tiles. I think the best answer to your question might be that multiple tiles are helpful when working within the framework of our unpackers. Multiple tiles would have appeared particularly unhelpful to you because you were also thinking about writing your own decoder, not just a plugin. I've created #6099 to talk about alternatives to accessing individual pixels. |
SpamImagePlugin uses the "raw" decoder, and I think there is value in having a simple plugin example. The user may not need to write a custom decoder. DdsImagePlugin is now linked to, and so is BlpImagePlugin. There is also potentially another example in the Pillow codebase with #6102. The documentation is improved now. If there are any suggestions about how to improve it further, let us know. |
Hello,
First, thank you guys for the work you put in.
I hope this is the good place to ask.
Today i got to work on files in an exotic format generated by an old RIP software.
I checked the doc and it seems there is exactly what i need in the handbook chapter called "Writing your own image plugin".
However, the documentation is not explaining everything so I'm left with questions and i hope i could get some pointers here :
What should be the recommended way of loading the new plugin ? Should we clone the pillow repo and copy it in the PIL folder ? or should we call it in some way to add it in the register before calling
Image.open()
?the decoders documentation specify that we should set the data to the PIL's internal pixel layout when writing our own, I tried to check in the source code and it seems that the function
set_as_raw
from thePyDecoder
class is the way to go but it doesn't describe the layout itself nor the way to fill it.What did you do?
Search the documentation, and browse the source code to try to find the information.
What did you expect to happen?
It would be nice if the page/example could provide a bit more details.
What actually happened?
What are your OS, Python and Pillow versions?
The text was updated successfully, but these errors were encountered: