Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    Ryan Laursen
    @RLaursen
    recent updates to how GIFs were handled compounded the issue, as disposal methods 0/1 now leave behind a portion of the image8 array where the current frame is transparent, but if the current frame has a different color table (palette), the indices left in image8 will display the wrong colors
    now, generally, GIF frames are meant to be loaded individually and the disposal method signals the app displaying the frames regarding how to handle them as they're loaded... this would mean not stacking frames as a decoder, and returning frames independently. This would be the cleanest fix, but might confuse some users even more than the current implementation already does.
    I think the best compromise would be keeping colors from the previous frame that exist in the current frame and making colors that don't exist transparent, as these will be visible when the GIF is displayed
    I have several ideas regarding how to achieve this, but I wanted feedback about whether that'd be satisfactory behavior for GifImageFiles
    Ryan Laursen
    @RLaursen
    nothing would change except in the currently bugged case of disposal methods 0/1 and subsequent frames with local color tables which differ from previous frames' color tables
    another option is a utility function or method which extracts frames independently without applying disposal for use with problem GIF files
    Andrew Murray
    @radarhere
    @phillmac ok, I've started the ball rolling with python-pillow/pillow-depends#39
    Ryan Laursen
    @RLaursen
    @radarhere I responded trying to explain why that example gif itself isn't handled correctly at the moment
    phillmac
    @phillmac
    @radarhere Much appreciated
    Ryan Laursen
    @RLaursen

    Here are the options as far as handling GIF frames with LCTs, transparency, and disposal 0/1:

    1. Extract frame as they are with transparency .
    2. Have all colors from previous frame(s) which are in current frame's color table carry over with transparency in holes.
    3. Expand frames' palettes as needed.

    All three would mean currently broken GIF files would display properly, though 3 would need extra work when encoding to put back in transparency and squish the color tables and extra work as far as decoupling GIF frames from the GIF's data.

    Andrew Murray
    @radarhere
    I'm in favour of option 3
    Ryan Laursen
    @RLaursen
    :thumbsup:
    Ryan Laursen
    @RLaursen
    Okay, so it's possible to consolidate palettes and remap the previous frame's indices to point to the correct colors in the palette as long as total number of colors is <= 256. I will figure out how to handle total colors > 256 next, which will require the "extra work."
    Ryan Laursen
    @RLaursen
    Well, since a gif frame with > 256 colors can't exist, the only time extracting an individual frame stacked on others with total colors > 256 makes sense is when converting it, so there's no reason to even try to squish together multiple frames with too many colors between them until the point of conversion since it's impossible to save the individual frame with all of the color information as a gif
    Ryan Laursen
    @RLaursen
    The only tough part remaining is properly handling transparency, currently using a test-case dependent hack. The self.info dict has a lot of side effects when messed with so I might revert to only using initial frame transparency and remapping subsequent palettes to use it, the only issue with this is when background and transparency are the same index with disposal method 2, though that is broken by only using initial frame transparency anyway so that can be a different fix
    I also want to implement passing a sequence of ints as an argument to disposal since many gifs use different disposal methods on different frames
    but again it's in the info dict, how do we feel about a frame_info dict?
    Andrew Murray
    @radarhere

    You can already pass a sequence of ints for disposal - ‚Äčhttps://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html#saving

    Pass a single integer for a constant disposal, or a list or tuple to set the disposal for each frame separately

    Ryan Laursen
    @RLaursen
    ah neat
    well that's good, and I'm clearly still very green in this package because I missed that
    Ryan Laursen
    @RLaursen
    Any ideas regarding which attributes to use to handle the transparency of frames?
    Ryan Laursen
    @RLaursen
    as it is I will introduce an attribute and I'm overloading .save and .convert for frames with more than 256 colors to convert them to rgba to handle it
    Andrew Murray
    @radarhere

    Not sure what you're asking.

    At the moment, the transparency for the current GIF frame is stored in info["transparency"].

    When saving, that value is written as the transparency index.

    If you're asking for a strategy to specify transparency on an individual frame basis when saving, passing a sequence of ints to info["transparency"] sounds like the most consistent approach.

    If using the info dictionary is troublesome to you, be aware that Pillow copies keyword arguments from save() in as the encoderinfo dictionary, and often allows them to override info keys.

    Ryan Laursen
    @RLaursen
    ah nice, I like the sequence of ints idea
    Andrew Murray
    @radarhere
    @phillmac did microsoft ever respond to your false positive report?
    phillmac
    @phillmac
    yeah they just blew me off pretty much
    Andrew Murray
    @radarhere
    Ok, well, python-pillow/Pillow#5561 has just been merged, so if you upgrade to Pillow 8.3.0 (due to be released in 2 days), the problematic file will be taken off your system
    phillmac
    @phillmac
    Thanks, thats awsome
    Junas Orionsky
    @NayaStudios99_twitter
    Hello
    I got a problem, I want to draw UTF8 characters, but PIL doesn't seem to be able to use a fallback font when the chosen font can't display a character. Any idea how to solve that problem?
    Andrew Murray
    @radarhere
    There's an issue open about this - python-pillow/Pillow#4808
    Justin Arnold
    @JSArnold_Author_twitter
    I'm trying to use PIL with Mu, but it's not having it. I've done a Pip install, and IDLE's fine using the PIL library code, but Mu still says that there is no moduke named 'PIL'. Any ideas please?
    Andrew Murray
    @radarhere
    Looking at https://www.reddit.com/r/inventwithpython/comments/eo4zqg/modulenotfounderror_in_mu_editor/, it seems Mu has its own Python version, so would be separate to IDLE.
    Navigating to Settings, the Third Party Packages tab, entering Pillow and hitting Ok, I was able to get it to install
    Justin Arnold
    @JSArnold_Author_twitter
    Thank you so much Andrew!
    ibx34
    @ibx34

    Hey im getting an error (AttributeError: module 'PIL._imaging' has no attribute 'png_encoder') when trying to run img.tobytes("png","RGB") on Pillow version 8.3.1
    and Python 3.8.2
    EDIT: Im on windows, was told y'all may need it

    Full error:

    Traceback (most recent call last):
      File "C:\Users\ibx34\Documents\programming\Python\teddy-bear\venv\lib\site-packages\PIL\Image.py", line 453, in _getencoder
        encoder = getattr(core, encoder_name + "_encoder")
    AttributeError: module 'PIL._imaging' has no attribute 'png_encoder'
    
    The above exception was the direct cause of the following exception:
    
    Traceback (most recent call last):
      File "C:\Users\ibx34\Documents\programming\Python\teddy-bear\cogs\owner.py", line 245, in _eval
        ret = await func()
      File "<string>", line 17, in func
      File "C:\Users\ibx34\Documents\programming\Python\teddy-bear\venv\lib\site-packages\PIL\Image.py", line 747, in tobytes
        e = _getencoder(self.mode, encoder_name, args)
      File "C:\Users\ibx34\Documents\programming\Python\teddy-bear\venv\lib\site-packages\PIL\Image.py", line 455, in _getencoder
        raise OSError(f"encoder {encoder_name} not available") from e
    OSError: encoder png not available
    Andrew Murray
    @radarhere

    Hi. If you look at https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.tobytes, you will see there is a warning.

    This method returns the raw image data from the internal storage. For compressed image data (e.g. PNG, JPEG) use save(), with a BytesIO parameter for in-memory data.

    I think this is the trap you have fallen into. "png" is not the name of one of our encoders. Instead, I expect you want to do this -

    >>> from PIL import Image
    >>> im = Image.new("RGB", (100, 100))
    >>> import io
    >>> fp = io.BytesIO()
    >>> im.save(fp, "PNG")
    >>> fp.getvalue()
    b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00d\x00\x00\x00d\x08\x02\x00\x00\x00\xff\x80\x02\x03\x00\x00\x004IDATx\x9c\xed\xc1\x01\r\x00\x00\x00\xc2\xa0\xf7Om\x0e7\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00~\x0cu\x94\x00\x01\xa8P\xf29\x00\x00\x00\x00IEND\xaeB`\x82'
    NiceYT
    @NiceYT
    How to add emoji in a pillow text?
    soundart
    @soundart:matrix.org
    [m]
    Hi, I would like to be able to create RGB Images with 32bit per component, so 32bit for R, 32bit for G, and 32 bit for B. What is the best way to do this? My "best" result so far is "TypeError: color must be int or single-element tuple"
    Andrew Murray
    @radarhere
    I don't believe this currently possible with Pillow. While https://pillow.readthedocs.io/en/stable/handbook/concepts.html#modes lists BGR;32 as a mode with limited support, see python-pillow/Pillow#1888 for this as a feature request.
    soundart
    @soundart:matrix.org
    [m]

    Uh this is somewhat unexpected. A quick look into the code makes me worried wrt trying to implement this myself. And the feature request is quite old too... It might be easier doable for me to use something else (numpy?) as underlying data structure and add R32G32B32 open and save routines on top of that.

    BGR;32 does not really seem to exist and might be a 8bit per component format with padding, or?

    if (strcmp(mode, "BGR;32") == 0) {
    / EXPERIMENTAL /
    / 32-bit reversed true colour /
    im->bands = 1;
    im->pixelsize = 4;
    im->linesize = (xsize*4 + 3) & -4;
    im->type = IMAGING_TYPE_SPECIAL;

    Andrew Murray
    @radarhere

    Yes, on second thought, the convention indicates that it is BGR spread out for the channels to cover 32-bits in total, rather than 32-bits per channel.

    As I said, I don't imagine you'll have much luck with Pillow on this.

    soundart
    @soundart:matrix.org
    [m]
    Ok thank you!
    pil34523
    @pil34523:matrix.org
    [m]
    Hi!
    But instead of file I have string like b'blablabla'
    How do I dewal with that?
    Andrew Murray
    @radarhere
    Instead of a file, you have a bytestring of the file's contents?
    from PIL import Image
    import io
    with io.BytesIO(b"blablabla") as fp:
        with Image.open(fp) as im:
            print(im.size)
    pil34523
    @pil34523:matrix.org
    [m]
    tnx