stable-diffusion-webui icon indicating copy to clipboard operation
stable-diffusion-webui copied to clipboard

[Bug]: 'KeyError: '.jpg' - no longer able to create images after latest update

Open rbbrdckybk opened this issue 2 years ago • 8 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues and checked the recent builds/commits

What happened?

Performed a git pull to update today (to commit 685f9631b56ff8bd43bce24ff5ce0f9a0e9af490), was unable to generate images regardless of settings or model (using the SD 1.5 base model for the below error). Did a complete fresh re-install and the same issue persists. I get the below error regardless of settings:

Error completing request2:43,  5.41it/s]
Arguments: ('test', '', 'None', 'None', 20, 1, False, False, 1, 1, 7.5, -1.0, -1.0, 0, 0, 0, False, 512, 512, False, 0.7, 0, 0, 0, False, False, False, False, '', 1, '', 0, '', True, False, False) {}
Traceback (most recent call last):
  File "D:\Applications\stable-diffusion-webui\modules\call_queue.py", line 45, in f
    res = list(func(*args, **kwargs))
  File "D:\Applications\stable-diffusion-webui\modules\call_queue.py", line 28, in f
    res = func(*args, **kwargs)
  File "D:\Applications\stable-diffusion-webui\modules\txt2img.py", line 49, in txt2img
    processed = process_images(p)
  File "D:\Applications\stable-diffusion-webui\modules\processing.py", line 464, in process_images
    res = process_images_inner(p)
  File "D:\Applications\stable-diffusion-webui\modules\processing.py", line 607, in process_images_inner
    images.save_image(image, p.outpath_samples, "", seeds[i], prompts[i], opts.samples_format, info=infotext(n, i), p=p)
  File "D:\Applications\stable-diffusion-webui\modules\images.py", line 536, in save_image
    _atomically_save_image(image, fullfn_without_extension, extension)
  File "D:\Applications\stable-diffusion-webui\modules\images.py", line 508, in _atomically_save_image
    image_format = Image.registered_extensions()[extension]
KeyError: '.jpg'

Steps to reproduce the problem

  1. Install Auto1111 or update to commit 685f9631b56ff8bd43bce24ff5ce0f9a0e9af490
  2. enter "test" into txt2img prompt textbox
  3. press 'Generate'

What should have happened?

Normally I'd receive an image.

Been using Auto1111 for months on both Windows and Linux, through many updates and this is the first issue I've had.

Commit where the problem happens

685f9631b56ff8bd43bce24ff5ce0f9a0e9af490

What platforms do you use to access UI ?

Windows

What browsers do you use to access the UI ?

Google Chrome

Command Line Arguments

No response

Additional information, context and logs

No response

rbbrdckybk avatar Dec 10 '22 20:12 rbbrdckybk

does it work if you set it to .png?

ClashSAN avatar Dec 10 '22 21:12 ClashSAN

Ah, it does work if I set image type to .png. Even weirder, if I then change to .jpg (after successfully making a .png image), it continues to work.

But if I restart the webui (leaving it set to .jpg), I'll get the same error when I try to create an image upon the next startup. The only way to create images it to change it to .png again (and then I can change it back to .jpg, which will work within that session).

rbbrdckybk avatar Dec 10 '22 22:12 rbbrdckybk

see if you can find what commit is hardcoding saving the images to png

ClashSAN avatar Dec 10 '22 23:12 ClashSAN

Same issue here, after a git pull

paolodalprato avatar Dec 11 '22 00:12 paolodalprato

@ClashSAN not really familiar enough with the code to start poking around at the moment, but I'm 99% sure that the issue was introduced in hash 685f9631b56ff8bd43bce24ff5ce0f9a0e9af490. I update auto1111 nearly every day, and yesterday when I ran git pull I was up-to-date (and everything worked properly). Today I updated to 685f9631b56ff8bd43bce24ff5ce0f9a0e9af490 and have the issue.

rbbrdckybk avatar Dec 11 '22 00:12 rbbrdckybk

@rbbrdckybk same for me, also i update every day

paolodalprato avatar Dec 11 '22 00:12 paolodalprato

Can confirm same issue with the same workaround

Seantourage avatar Dec 11 '22 02:12 Seantourage

I encountered this error and have temporarily fixed it by undoing commit 89237852f4962447a0858fc6e5fb048b35b9d9fc which is equivalent to replacing images.py with the version from commit 59c2dfe1e6a29dcf231fa9d894ac238887e40c39

davidastgtciv avatar Dec 11 '22 13:12 davidastgtciv

Same issue here and the workaround of first saving as PNG worked for me also.

xberg avatar Dec 14 '22 06:12 xberg

This is because the PR https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/5119 used PIL.Image.registered_extensions(). image What is interesting is it seems to be supported on my Windows 10 system (pillow==9.3.0), so this issue is related to the user's own system.

aliencaocao avatar Dec 16 '22 03:12 aliencaocao

I've done a fresh install for a couple of days, with the minimum of extensions I use, at the moment I haven't had this problem anymore

paolodalprato avatar Dec 16 '22 12:12 paolodalprato

Hmm, some possibly helpful information (Win 10, Python 3.10.7):

  1. When I print registered_extensions() in images.py, I get only .png and .apng -- no JPEG support
  2. When I print it straight from Python without venv (virtual environment) I don't even have PIL
  3. When I activate virtual env and print in Python shell, I get full set of support sumilar to aliencacao above
  4. When I print extensions in launch.py I get full set of format support
  5. ...When I print extensions in webui.py (from launch.py), I get only PNG support

Seems like the environment or PIL image support is getting degraded somewhere along the launch path... Might be a side effect of something introduced in recent versions.

Update: Did a little further testing and the PIL.Images formats disappear after from modules import shared -- before this line if I import PIL I get full support, after that, I get only PNG

jokkebk avatar Dec 18 '22 10:12 jokkebk

Alright, further digging showed the likely culprit to be gradio:

  1. If I import PIL.Image before gradio, I get full support
  2. If I import gradio and then PIL.Image, I get only PNG

Simple code to put on top of launch.py to replicate:

import gradio as gr # comment this out to get .jpg support
from PIL import Image
print(Image.registered_extensions())
exit(1)

Easiest workaround is to have from PIL import Image in launch.py. That way it gets imported before gradio does its "magic". Putting it before "import webui" seemed to work for me. Top of the launch.py did not. Go figure.

jokkebk avatar Dec 18 '22 10:12 jokkebk

I was able to replicate the issue with latest version of Gradio on a clean environment both on Windows and Ubuntu (WSL2). Posted an issue on Gradio github, probably some of the later SD webui updates caused Gradio to be imported before PIL which triggered this bug.

jokkebk avatar Dec 18 '22 11:12 jokkebk

I am able to reproduce @jokkebk 's observations, working to see if I can fix for Gradio.

aliencaocao avatar Dec 18 '22 11:12 aliencaocao

I found something very weird:

from PIL import Image
print(Image.registered_extensions())

If I run this script with pycharm, it gives ONLY png (this seems to be due to pycharm professional importing matplotlib.figure for its sciplot function, see below) If I run with python test.py in the same dir, it gives everything If I run this in jupyter notebook in pycharm, it gives everything

However, my pycharm run config has been carefully checked to make sure it is exactly the same as I would have ran it in the cmd, so I'm quite confused on why it causes a difference.

Seems like gradio isn't the only cause here (although it still breaks it if it was imported, no matter how I run the python file), but it looks like some thing related to the OS too.

I zoomed it down to https://github.com/gradio-app/gradio/blob/3cb2bb061c8fa42ea1c13d73438dbff132f42983/gradio/components.py#L24 import matplotlib.figure causes it

EDIT: I finally found the root cause: https://github.com/python-pillow/Pillow/blob/d594f4cb8dc47fb0c69ae58d9fff86faae4515bd/src/PIL/PngImagePlugin.py#L1453 causes it. When gradio imports matplotlib which imports pnginfo, the extensions will be overridden to only PNG.

aliencaocao avatar Dec 18 '22 11:12 aliencaocao

What this means is that, relying on PIL.Image.registered_extensions() will not be accurate since importing pnginfo overrides it. I will try to find a alternative for it. Our last resort should be just import PIL.Image before gradio but it is a pretty dirty fix.

This seems to be a PIL issue. I opened https://github.com/python-pillow/Pillow/issues/6809

aliencaocao avatar Dec 18 '22 12:12 aliencaocao

Gradio has merged https://github.com/gradio-app/gradio/pull/2846 which also fixes this. When they make a stable release, users of this repo need to update gradio. For those want to workaround their issue asap, you can either pip install directly from gradio's main branch, or do the monkey patch in https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/5838/files

cc @brian000

aliencaocao avatar Dec 20 '22 03:12 aliencaocao

Gradio has released 3.15.0 which fixes this. However SD webui seems to be only compatiable up to 3.9.0..

aliencaocao avatar Dec 22 '22 01:12 aliencaocao

I'm at my wits end here..

Tried installing the latest gradio from their github: didn't work.

Tried the monkey patch and inserting from PIL import Image at the top of launch.py and webui.py: didn't work.

Even tried creating a fresh new environment, installing all the requirements from scratch: still didn't work.

I'm being cornered here as I'm down to my last 100 GB on my HD and now I have to deal with the double whammy of saving as PNGs instead of JPGs.

Maybe I need to create a script to convert all PNGs to JPGs in the outputs folder and run it on a cron job or something.

xjdeng avatar Dec 22 '22 02:12 xjdeng

Are you running your script using pycharm?

aliencaocao avatar Dec 22 '22 02:12 aliencaocao

I tried the monkey patch, but it does not work. I don't use pycharm.

roygear avatar Dec 23 '22 13:12 roygear

Not a pycharm user either.

My workaround for now is to create a Python script to convert all PNGs to JPG.

from path import Path as path
from PIL import Image
import piexif

files = path("./").walkfiles()

for f in files:
    if f.ext.lower() == ".png":
        img = Image.open(f)
        dirpath = f.abspath().dirname()
        namebase = f.namebase
        newfile = "{}/{}.jpg".format(dirpath, namebase)
        exif_ifd = {piexif.ExifIFD.UserComment: img.info['parameters'].encode()}
        exif_dict = {"Exif": exif_ifd}
        img.save(newfile, exif = piexif.dump(exif_dict))
        f.remove()

Save the above into your outputs folder as png_to_jpg.py

Next, open a command prompt and install some libraries:

pip install Pillow piexif path.py==12.0.1

And create a .bat file with the single line and save it there to directly launch the script:

python png_to_jpg.py

Every once in a while, esp if i'm low on space or i need to back up some photos, I'll run that batch file. The hardest part was figuring out how to preserve the EXIF info which includes your prompt.

xjdeng avatar Dec 23 '22 14:12 xjdeng

They have merged a fix at pillow, you can pip install their latest master branch

aliencaocao avatar Dec 23 '22 15:12 aliencaocao

Having trouble installing the latest Pillow due to problems with zlib.. oh well, guess I'll have to wait till Jan 3 for the fixed version to be uploaded to pypi

xjdeng avatar Dec 23 '22 17:12 xjdeng