Giter Club home page Giter Club logo

promptvision's Introduction

PromptvisionNG

Codacy Badge Platform | MacOS, Windows, Linux Written with Streamlit

Supports Automatic1111 Supports SD.next Supports ComfyUI Supports InvokeAI Supports NovelAI

An evolution of the previous Promptvision. View all your image generations in one place. Browse folder by folder. Filter by your favorite prompts. Regex search specific positive / negative prompts. Get your images scored by a specifically trained scoring model (ImageReward) which enables you to get third-party assessments of your generations.

Dive further into the weed with the ability to set favorite status & your personal ratings. All of the fields can then be used when filtering the images you want to watch. This also enables you to copy, move and delete images quickly.

Dive further into your prompt engineering analysis by going into the prompt explorer tab where you can run a few natural language processing algorithms on your specific fields such as your positive prompts. This can give you insight in what prompts that are most prevalent. You can also combine this with the former discussed filtering so that you can really gain a deeper understanding of your prompts and the end results.

ng image viewer ng image explorer ng prompt explorer ng gallery view ng settings view

Features

  • ImageReward score scoring of images
  • Rating and favoriting images
  • Filtering your images on all properties:
    • Prompts
    • Score
    • Personal rating
    • Favorite
    • Resolution
  • Copying, moving and deletion of images
  • Folder and subfolder navigation (will detect subfolders and enable you to view e.g. all images in a certain folder)

Setup and installation

  1. git clone https://github.com/Automaticism/Promptvision.git
  2. cd Promptvision
  3. conda create -n promptvision
  4. conda activate promptvision
  5. pip install -r requirements.txt
  6. streamlit run Promptvision.py
  7. Optionally if you use "Calculate ImageReward score" the ImageReward score will be downloaded. This will look like the following in your console:
  • 2023-07-22 00:56:36.538 Created a temporary directory at /var/folders/l5/n6jwr6tn71s_pm5dh926hbdr0000gn/T/tmpqf7yjji1 2023-07-22 00:56:36.538 Writing /var/folders/l5/n6jwr6tn71s_pm5dh926hbdr0000gn/T/tmpqf7yjji1/_remote_module_non_scriptable.py Downloading ImageReward.pt: 1%|▌ | 21.0M/1.79G [00:02<02:49, 10.4MB/s]

Application views

  • Promptvision.py the entrypoint of the multi-page Streammlit app (used to launch the program, streamlit run Promptvision.py). This page also contains settings for the application. Set the directory which will be used as the main directory. (E.g. open your main image folder and it will index all images and subfolders. You can then browse every subfolder.)
  • Gallery.py the gallery view of your images, select one image here and you can look closer in the Image viewer.py page
  • Prompt Explorer.py is running some Natural Language Processing models generating some statistical information to give insight into prompts (This will be the focus for further development)
  • Image viewer.py is the image viewer. Has typical option of navigating your images (next, previous), shows generational information (supports all the UIs via the https://github.com/d3x-at/sd-parsers module), enables you to set your personal rating and set favorite status, also enables you to view the ImageReward score. Rating & favorite can be used when you are filtering your images (e.g. filter all favorites and copy them to a new folder)

Bugs and known issues

  • This application is limited by Streamlit in some ways with how things are done the Streamlit way (and I am no Streamlit expert), you will get warnings such as:

AttributeError: st.session_state has no attribute "df". Did you forget to initialize it? More info: https://docs.streamlit.io/library/advanced-features/session-state#initialization

These are typical and will disappear when you set directory and browse the different pages. If they persist and something is broken, create an issue for it.

  • score might be 0.0 even after installing ImageReward model and having checked off the "Calculate ImageReward score", simply press "Reset cache" and it will recalc and most likely fix the problem

Credits

promptvision's People

Contributors

automaticism avatar drjkl avatar frozen-byte avatar sweep-ai[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

promptvision's Issues

AttributeError: module 'configparser' has no attribute 'SafeConfigParser'. Did you mean: 'RawConfigParser'?

Describe the bug
Installing in Windows 10 not working, pip requirements install gives warning about ConfigParser

To Reproduce
Steps to reproduce the behavior:

Follow steps provided in Civitai.com description
Reach step 5: pip install -r requirements.txt

Expected behavior
Pip installs the requirements

Screenshots
AttributeError: module 'configparser' has no attribute 'SafeConfigParser'. Did you mean: 'RawConfigParser'?
[end of output]

note: This error originates from a subprocess, and is likely not a problem with pip.
error: subprocess-exited-with-error

Desktop (please complete the following information):

  • OS: [e.g. iOS] Windows 10
  • Browser [e.g. chrome, safari] Firefox
  • Version [e.g. 22] Latest commit 5dcc03c

Thumbnails Disappear; Replaced With Error Message

App and OS versions

Promptvision (current on 2023/03/26 @ 4PM CST)
Firefox 111.0.1
MacOS 13.2.1
32Gb M1 Max

Describe the bug

In the Thumbnail section, selecting a thumbnail often causes the images to disappear and be replaced by debugger HTML and an error message.

Sometimes the thumbnails work fine, but this error comes up more often than not.

The format of the image I click on doesn't seem to make a difference.

As of yet I haven't been able to detect a pattern to the trigger.

The rest of the app still works; I can click through images using the left/right arrows in the metadata section, but as I do thumbnails section will switch between showing thumbnails and error message.

How to Reproduce

  1. Launch app
  2. Click thumbnails. Within one or three clicks, it is replaced with error message.

Error message

Thumbnail Section Output

OSError

OSError: cannot write mode RGBA as JPEG
Traceback (most recent call last)

    File "/opt/homebrew/lib/python3.11/site-packages/PIL/JpegImagePlugin.py", line 643, in _save

    rawmode = RAWMODE[im.mode]
              ^^^^^^^^^^^^^^^^

    The above exception was the direct cause of the following exception:
    File "/opt/homebrew/lib/python3.11/site-packages/flask/app.py", line 2551, in __call__

    return self.wsgi_app(environ, start_response)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    File "/opt/homebrew/lib/python3.11/site-packages/flask/app.py", line 2531, in wsgi_app

    response = self.handle_exception(e)
               ^^^^^^^^^^^^^^^^^^^^^^^^

    File "/opt/homebrew/lib/python3.11/site-packages/flask/app.py", line 2528, in wsgi_app

    response = self.full_dispatch_request()
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    File "/opt/homebrew/lib/python3.11/site-packages/flask/app.py", line 1825, in full_dispatch_request

    rv = self.handle_user_exception(e)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    File "/opt/homebrew/lib/python3.11/site-packages/flask/app.py", line 1823, in full_dispatch_request

    rv = self.dispatch_request()
         ^^^^^^^^^^^^^^^^^^^^^^^

    File "/opt/homebrew/lib/python3.11/site-packages/flask/app.py", line 1799, in dispatch_request

    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    File "/Users/user/Promptvision/gallery.py", line 349, in thumbnails

    thumbnails = fetch_thumbnails(limit=limit, offset=offset)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    File "/Users/user/Promptvision/gallery.py", line 220, in fetch_thumbnails

    thumbnail = (get_thumbnail_from_image(image))
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    File "/Users/user/Promptvision/gallery.py", line 196, in get_thumbnail_from_image

    img.save(thumbnail_path, format='JPEG', quality=85)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    File "/opt/homebrew/lib/python3.11/site-packages/PIL/Image.py", line 2431, in save

    save_handler(self, fp, filename)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    File "/opt/homebrew/lib/python3.11/site-packages/PIL/JpegImagePlugin.py", line 646, in _save

    raise OSError(msg) from e
    ^^^^^^^^^^^^^^^^^^^^^^^^^

    OSError: cannot write mode RGBA as JPEG

This is the Copy/Paste friendly version of the traceback.
Traceback (most recent call last):
  File "/opt/homebrew/lib/python3.11/site-packages/PIL/JpegImagePlugin.py", line 643, in _save
    rawmode = RAWMODE[im.mode]
              ^^^^^^^^^^^^^^^^
KeyError: 'RGBA'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/opt/homebrew/lib/python3.11/site-packages/flask/app.py", line 2551, in __call__
    return self.wsgi_app(environ, start_response)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/flask/app.py", line 2531, in wsgi_app
    response = self.handle_exception(e)
               ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/flask/app.py", line 2528, in wsgi_app
    response = self.full_dispatch_request()
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/flask/app.py", line 1825, in full_dispatch_request
    rv = self.handle_user_exception(e)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/flask/app.py", line 1823, in full_dispatch_request
    rv = self.dispatch_request()
         ^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/flask/app.py", line 1799, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/Promptvision/gallery.py", line 349, in thumbnails
    thumbnails = fetch_thumbnails(limit=limit, offset=offset)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/Promptvision/gallery.py", line 220, in fetch_thumbnails
    thumbnail = (get_thumbnail_from_image(image))
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/Promptvision/gallery.py", line 196, in get_thumbnail_from_image
    img.save(thumbnail_path, format='JPEG', quality=85)
  File "/opt/homebrew/lib/python3.11/site-packages/PIL/Image.py", line 2431, in save
    save_handler(self, fp, filename)
  File "/opt/homebrew/lib/python3.11/site-packages/PIL/JpegImagePlugin.py", line 646, in _save
    raise OSError(msg) from e
OSError: cannot write mode RGBA as JPEG
The debugger caught an exception in your WSGI application. You can now look at the traceback which led to the error. If you enable JavaScript you can also use additional features such as code execution (if the evalex feature is enabled), automatic pasting of the exceptions and much more.
Brought to you by DON'T PANIC, your friendly Werkzeug powered traceback interpreter.

Terminal Output

127.0.0.1 - - [26/Mar/2023 16:06:45] "GET /imagedirection?direction=next&image_name=%2FUsers%2Fuser%2F-AI%2FREFERENCE%2FGRABS%2FUnstable%20Diffusion%2Fland-and-cityscapes%2F00084-2838196845.png HTTP/1.1" 302 -
127.0.0.1 - - [26/Mar/2023 16:06:45] "GET /img?image_name=%2FUsers%2Fuser%2F-AI%2FREFERENCE%2FGRABS%2FUnstable+Diffusion%2Fland-and-cityscapes%2F00005-2485980304.png HTTP/1.1" 200 -
127.0.0.1 - - [26/Mar/2023 16:06:45] "GET /static/css/default.css HTTP/1.1" 304 -
127.0.0.1 - - [26/Mar/2023 16:06:45] "GET /image?image_name=%2FUsers%2Fuser%2F-AI%2FREFERENCE%2FGRABS%2FUnstable+Diffusion%2Fland-and-cityscapes%2F00005-2485980304.png HTTP/1.1" 200 -
127.0.0.1 - - [26/Mar/2023 16:06:45] "GET /static/js/app.js HTTP/1.1" 304 -
127.0.0.1 - - [26/Mar/2023 16:06:45] "GET /numimages HTTP/1.1" 200 -
127.0.0.1 - - [26/Mar/2023 16:06:45] "GET /thumbnails?limit=112&offset=0&imgsrc=/Users/user/Downloads/-AI/REFERENCE/GRABS/Unstable%20Diffusion/land-and-cityscapes/00005-2485980304.png HTTP/1.1" 500 -
Traceback (most recent call last):
  File "/opt/homebrew/lib/python3.11/site-packages/PIL/JpegImagePlugin.py", line 643, in _save
    rawmode = RAWMODE[im.mode]
              ^^^^^^^^^^^^^^^^
KeyError: 'RGBA'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/opt/homebrew/lib/python3.11/site-packages/flask/app.py", line 2551, in __call__
    return self.wsgi_app(environ, start_response)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/flask/app.py", line 2531, in wsgi_app
    response = self.handle_exception(e)
               ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/flask/app.py", line 2528, in wsgi_app
    response = self.full_dispatch_request()
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/flask/app.py", line 1825, in full_dispatch_request
    rv = self.handle_user_exception(e)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/flask/app.py", line 1823, in full_dispatch_request
    rv = self.dispatch_request()
         ^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/flask/app.py", line 1799, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/Promptvision/gallery.py", line 349, in thumbnails
    thumbnails = fetch_thumbnails(limit=limit, offset=offset)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/Promptvision/gallery.py", line 220, in fetch_thumbnails
    thumbnail = (get_thumbnail_from_image(image))
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/Promptvision/gallery.py", line 196, in get_thumbnail_from_image
    img.save(thumbnail_path, format='JPEG', quality=85)
  File "/opt/homebrew/lib/python3.11/site-packages/PIL/Image.py", line 2431, in save
    save_handler(self, fp, filename)
  File "/opt/homebrew/lib/python3.11/site-packages/PIL/JpegImagePlugin.py", line 646, in _save
    raise OSError(msg) from e
OSError: cannot write mode RGBA as JPEG
127.0.0.1 - - [26/Mar/2023 16:06:45] "GET /img?__debugger__=yes&cmd=resource&f=style.css HTTP/1.1" 304 -

Screenshots

Changelog & Devupdate

22.7.23

  • New complete rewrite released
  • Latest commit tried to fix scaling in regards to handling scaling images on MacOS (scaling stopped working, use_column_width=True removed from st.image() fixed issue. Lazily enabled re-run of indexing if imagereward=True so that all images are scored. A more optimal way to handle this would be to pull up all images that has a ir score calculated (e.g. all non 0.0 score) and then updating them
  • Changed to MIT license for the NG version

Feature Request: Word Wrap File Path Names

Is your feature request related to a problem? Please describe.

Some of the path names of my images are very long and include underscores, which forces the layout of the metadata section to redraw extra wide on some images, then back to normal on others.

Describe the solution you'd like

Add word-wrap: anywhere; to .metadata-table td so that unwieldy names don't break the layout.

.metadata-table td {
  padding: 12px 16px;
  color: #FFF;
  border: none;
  word-wrap: anywhere;
}

Describe alternatives you've considered

Since this would affect the list of Prompt tags as well, maybe just assign a special class tot he file path field and just apply it there.

Additional context

Adding text-align: left; to all fields would be nice. It's easier to scan the data when it's aligned left rather than centered.

List index out of range

I was able to get it working with a test directory but my main image directory is returning this error. I believe that directory is ~70k images, is there some limit in how large the directory can be?

File "C:\Users\user\AppData\Local\Programs\Python\Python310\lib\multiprocessing\pool.py", line 774, in get
raise self._value
IndexError: list index out of range

That is the recurring exception, occurring at either line 888 - parsed_data[Model] = sampler_settings[6] or 889 - parsed_data[Eta] = sampler_settings[7]

Here is the full error output

PS C:\Users\user\Promptvision> python .\gallery.py --imagedir "C:\Users\user\stable-diffusion-webui\outputs\images"
multiprocessing.pool.RemoteTraceback:
"""
Traceback (most recent call last):
File "C:\Users\user\AppData\Local\Programs\Python\Python310\lib\multiprocessing\pool.py", line 125, in worker
result = (True, func(*args, **kwds))
File "C:\Users\user\Promptvision\gallery.py", line 888, in read_exif_data
parsed_data['Model'] = sampler_settings[6].split(": ")[1]
IndexError: list index out of range
"""
The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "C:\Users\user\Promptvision\gallery.py", line 1007, in
bulk_exif_data = mp_bulk_exif_read(filtered_images)
File "C:\Users\user\Promptvision\gallery.py", line 933, in mp_bulk_exif_read
row = result.get()
File "C:\Users\user\AppData\Local\Programs\Python\Python310\lib\multiprocessing\pool.py", line 774, in get
raise self._value
IndexError: list index out of range

Thanks in advance and apologies if it's something I've done or missed.

Delete Button

The ability to delete images would be a godsend when reviewing

UI Doesn't Load

App and OS versions

Promptvision v0.3 (or whatever is current on 2023/03/24 @ 2AM CST)
Firefox 111.0.1
MacOS 13.2.1
32Gb M1 Max

Describe the bug

I have a folder of images (and sub-folders of images) I've grabbed from model cards and other sources. Formats include PNG, JPG, and WebP. Some have EXIF data, others do not.

I've directed the command to the master folder.

When I paste the URL in my browser -- either http://127.0.0.1:8000 or http://192.168.1.69:8000 -- it adds the path to a randomly selected image inside the folder to the URL, such as:

http://127.0.0.1:8000/img//Users/user/-AI/REFERENCE/GRABS/Unstable%20Diffusion/3D/00005-3815441304.png

and the browser reports:

Not Found
The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.

How to Reproduce

  1. Run command: python gallery.py --imagedir /Users/user/-AI/REFERENCE/GRABS
  2. Paste http://127.0.0.1:8000 or http://192.168.1.69:8000 into browser

Error message

127.0.0.1 - - [24/Mar/2023 02:10:56] "GET / HTTP/1.1" 302 -
127.0.0.1 - - [24/Mar/2023 02:10:56] "GET /img//Users/user/-AI/REFERENCE/GRABS/tints/248403.png HTTP/1.1" 404 -

192.168.1.69 - - [24/Mar/2023 02:14:57] "GET / HTTP/1.1" 302 -
192.168.1.69 - - [24/Mar/2023 02:14:54] "GET /img//Users/user/-AI/REFERENCE/GRABS/Unstable%20Diffusion/landscapes/23-9694577.png HTTP/1.1" 404 -

127.0.0.1 - - [24/Mar/2023 02:20:34] "GET / HTTP/1.1" 302 -
127.0.0.1 - - [24/Mar/2023 02:20:34] "GET /img//Users/user/-AI/REFERENCE/GRABS/Unstable%20Diffusion/3D/00005-3815441304.png HTTP/1.1" 404 -
127.0.0.1 - - [24/Mar/2023 02:20:40] code 400, message Bad request version ('\x87\\Gâ\x9b6ô¨\x815ÇV:;]ß¡mNáö\x977ÞLÜ`º>S×3\x00"\x13\x01\x13\x03\x13\x02À+À/̨̩À,À0À')
ERROR   2023-03-24 02:20:40,431 [ERROR][_log] line:224 127.0.0.1 - - [24/Mar/2023 02:20:40] code 400, message Bad request version ('\x87\\Gâ\x9b6ô¨\x815ÇV:;]ß¡mNáö\x977ÞLÜ`º>S×3\x00"\x13\x01\x13\x03\x13\x02À+À/̨̩À,À0À')
127.0.0.1 - - [24/Mar/2023 02:20:40] "ü-Õë�¹�¾´Ù´��ä"�ÂÌá�¡ §n��Z��\ �\Gâ�6ô¨�5ÇV:;]ß¡mNáö�7ÞLÜ`º>S×3"À+À/̨̩À,À0À" 400 -
127.0.0.1 - - [24/Mar/2023 02:22:01] "GET /img//Users/user/-AI/REFERENCE/GRABS/Unstable%20Diffusion/3D/00005-3815441304.png HTTP/1.1" 404 -
127.0.0.1 - - [24/Mar/2023 02:22:14] "GET /img/Users/user/-AI/REFERENCE/GRABS/Unstable%20Diffusion/3D/00005-3815441304.png HTTP/1.1" 404 -
127.0.0.1 - - [24/Mar/2023 02:22:28] "GET /img//Users/user/-AI/REFERENCE/GRABS/Unstable%20Diffusion/3D/00005-3815441304.png HTTP/1.1" 404 -

Screenshots

Please add support for an image where the information is written in the 'UserComment' field.

Is your feature request related to a problem? Please describe.

  1. For some images, the prompt cannot be parsed because the information is written in the 'UserComment' field of the EXIF.
  2. The re pattern does not have a complete analysis. (Although most of the time, viewing the prompt is the main purpose.)

Describe the solution you'd like

  1. I try to add some code to handle these "special images". (example images like: #5 )
import piexif
import piexif.helper

    # line 1041 
    try:
        # Use .info instead of .text
        exif_data = img.info

        if 'parameters' in exif_data:
            parameters = exif_data.get('parameters', '')
        elif 'exif' in exif_data:
            exif_info = piexif.load(exif_data['exif'])
            user_comment_info = exif_info.get('Exif', {}).get(piexif.ExifIFD.UserComment, b'')
            parameters = piexif.helper.UserComment.load(user_comment_info)

        logger.debug(f"-------\nexif_data:{exif_data}\nexif_data_type:{type(exif_data)}----------\n")
        ...

    # line 1049
    try:
        # line 1051
        # exif_data['parameters'] has been previously extracted
        for key_value in parameters.split('\n'):
        ...
  1. The re pattern does not have a complete analysis.
Steps: 80, Sampler: Euler a, CFG scale: 7, Seed: 3157911442, Size: 512x768, Model hash: 79e42fb744, Model: Baked_GF2+BM+AOM3_20-30-50, Denoising strength: 0.5, Clip skip: 2, Hires upscale: 2, Hires upscaler: Latent (bicubic antialiased)

Screenshot 2023-04-02 at 13 57 39

Additional
Is it too strict to use all() (line 1054 of gallery.py,) as a pre-parsing requirement for images with a shortage of parameters?
Is this part of the content bound together to speed up parsing?

Potential improvements

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Using on MacOS, this is a great first effort. I've been wanting something like this for a while. Some features that would help:

  • Consider moving the forward/back navigation to the bottom of the viewer pane, in fixed positions. Currently, when switching between portrait and landscape images, the center pane resizes causing the nav buttons to shift away from the current mouse position. Make the buttons span the width of the pane width so they're easy to (consistently) hit.

  • Add an option to lock/unlock the size of the viewer pane so the above resizing doesn't occur.

  • Instead of shifting the thumbnails every time a new image is loaded, keep them in fixed positions and reposition the highlighter. The constant refresh is unnecessary and the fixed positions would allow quick scanning which is currently difficult since the thumbs are always changing position.

  • Make all panes horizontally resizable.

  • Add a trash option -- removing images is needed as much as assigning tags and filtering.

  • If you provide a field for the current directory, you should list it, instead of having it empty.

Thanks for listening 👍
By user @netdzynr on CivitAI (https://civitai.com/models/22625)

Crashes During Launch

App and OS versions

Promptvision v0.2
MacOS 13.2.1
32Gb M1 Max

Describe the bug

I have a folder of images I've grabbed from model cards and other sources. Formats include PNG, JPG, and WebP. Some have EXIF data, others do not.

When I run the command, an exception crashes the process.

How to Reproduce

Run the command (on a similar system).

Error message

Command:

user@rig Promptvision % python gallery.py --imagedir /Users/user/-AI/REFERENCE/GRABS

About 440 lines of this:

ERROR   2023-03-23 17:54:16,091 [ERROR][read_exif_data] line:879 <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=755x1351 at 0x15A1F01D0>
ERROR   2023-03-23 17:54:16,091 [ERROR][read_exif_data] line:880 text

And then this:

multiprocessing.pool.RemoteTraceback: 
"""
Traceback (most recent call last):
  File "/opt/homebrew/Cellar/[email protected]/3.11.2_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/multiprocessing/pool.py", line 125, in worker
    result = (True, func(*args, **kwds))
                    ^^^^^^^^^^^^^^^^^^^
  File "/Users/user/Promptvision/gallery.py", line 885, in read_exif_data
    for key_value in exif_data['parameters'].split('\n'):
                     ~~~~~~~~~^^^^^^^^^^^^^^
KeyError: 'parameters'
"""

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/user/Promptvision/gallery.py", line 1026, in <module>
    bulk_exif_data = mp_bulk_exif_read(filtered_images)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/Promptvision/gallery.py", line 952, in mp_bulk_exif_read
    row = result.get()
          ^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/[email protected]/3.11.2_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/multiprocessing/pool.py", line 774, in get
    raise self._value
KeyError: 'parameters'

Screenshots

Exceeded Memory Limit?

Installed on macos 13.5.1 using miniconda.
After setting default directory, image scan ran for several minutes and then appeared to dump metadata of all images in Terminal, with this error:

Traceback (most recent call last):
File "/opt/homebrew/lib/python3.11/site-packages/streamlit/runtime/runtime.py", line 596, in _loop_coroutine
self._send_message(active_session_info, msg)
File "/opt/homebrew/lib/python3.11/site-packages/streamlit/runtime/runtime.py", line 661, in _send_message
populate_hash_if_needed(msg)
File "/opt/homebrew/lib/python3.11/site-packages/streamlit/runtime/forward_msg_cache.py", line 59, in populate_hash_if_needed
hasher.update(msg.SerializeToString())
^^^^^^^^^^^^^^^^^^^^^^^
ValueError: Message ForwardMsg exceeds maximum protobuf size of 2GB: 4704277104

render_image in Image viewer doesn't get all metadata when browsing root directory

Describe the bug
When browsing the root directory of a large folder with many subfolders and thousands of images there seems to be an issue pulling the metadata. Might have something to do with the lookup if it.

To Reproduce
Steps to reproduce the behavior:

  1. Go to image viewer.py
  2. view images
  3. See error that prompts are not filled out etc

Expected behavior
Expected to see all metadata. Can see metadata if I pull the folder and set that subfolder as the main folder.

def render_image(container):
    helper.store_metadata_in_session(st.session_state.my_index)
    # Get the selected image and its metadata from the session_state
    filename = st.session_state.filename
    positive_prompt = st.session_state.positive_prompt
    negative_prompt = st.session_state.negative_prompt
    metadata = st.session_state.metadata
    score = st.session_state.score

Expect issue to be around here in the image viewer.py or in the helper for store_metadata

sweep: Create documentation for this repository

Checklist
  • README.md

Add an overview of the repository and instructions on how to use it.

  • pages/PromptExplorer.py

Add inline comments explaining the purpose and functionality of each function and class.

  • LICENSE

Update the copyright year and ensure the license text is up to date.

  • pages/Gallery.py

Add a docstring at the beginning of the file explaining its purpose and usage.

  • pages/Imageexplorer.py

Add inline comments explaining the purpose and functionality of each function and class.

sd-parsers api changes

Hello there!

Just a quick heads-up, the sd-parsers api will "soon(tm)" be changing a bit. (see dev0.4 branch).
No real time estimate from my side though, maybe this year. ;-)

Quick mockup of what the code i found you using it might look like in the future:

from sd_parsers import ParserManager

parser_manager = ParserManager()

def test(image):
    exif = parser_manager.parse(image)
    if exif is None:
        raise Exception("No metadata found")

    positive_prompt = ", ".join(prompt.value for prompt in exif.prompts)
    if positive_prompt == "":
        positive_prompt = "No positive prompt found"

    negative_prompt = ", ".join(prompt.value for prompt in exif.negative_prompts)
    if negative_prompt == "":
        negative_prompt = "No negative prompt found"

    if exif.generator == "ComfyUI":
        print(exif.generator)
        print(exif.parameters["prompt"])
        print(exif.parameters["workflow"])
        metadata = exif.parameters
    else:
        metadata = exif.metadata

    print(positive_prompt, negative_prompt, metadata)

Have fun!

Does not read Prompt embedded in JPG files

Describe the bug
I have tens of thousands of AI-generated files, I use JPG for space purposes and I have been looking for a tool that will let me organize / rename / sort / file / tag those files.

To Reproduce
Steps to reproduce the behavior:
I loaded up prompt vision and pointed it at a folder with a few hundred images and it quickly loaded and displayed the images, but they all said there was no prompt information.

Expected behavior
All of the imaages show the prompt information if viewed in the A1111 PNG info tab. I expected this display the prompt information.

Screenshots
If applicable, add screenshots to help explain your problem.
2023-03-23 18_55_29-NVIDIA GeForce Overlay DT

Desktop (please complete the following information):

  • OS: Windows 10
  • Browser: Chrome
  • Version 111

Automatic1111 Extension & View Watermarking Data

Describe the solution you'd like

I'd love if this is a tab within A111. Running it as an additional application when it's really just a library of image + prompts feels a bit overheady.

Also one of the fields that would be nice to see is if the image has the embedded "Hidden" Stable Diffusion watermark.

eg.
https://medium.com/@steinsfu/stable-diffusion-the-invisible-watermark-in-generated-images-2d68e2ab1241

import cv2
from imwatermark import WatermarkDecoderdef testit(img_path):
    bgr = cv2.imread(img_path)
    decoder = WatermarkDecoder('bytes', 136)
    watermark = decoder.decode(bgr, 'dwtDct')
    try:
        dec = watermark.decode('utf-8')
    except:
        dec = "null"
    print(dec)

Avoid non-image files.

Is your feature request related to a problem? Please describe.
When there are non-picture files in the folder, it will raise <PIL.UnidentifiedImageError>.
Screenshot 2023-03-26 at 21 52 44

Describe the solution you'd like
The filter_images_in_image_folder_path() function on line 64 of the gallery.py code seems to be unable to avoid non-picture files, so that an exception is thrown.

Additional context
This project is very useful. The built-in image viewing program is somewhat inefficient, and I hope your project can continue to be optimized.

Feature Request: Thumbnail Viewer Should Show All Images in Source Folder

Is your feature request related to a problem? Please describe.

The Thumbnail section shows a maximum of 112 images.

Currently, clicking the left/right arrows in the metadata section load the next in sequence, and removes the thumb of the previous image from position 1 in the thumbnails viewer.

Describe the solution you'd like

I'd like to have access to all thumbnails at all times.

And having them sorted alphabetically by subfolder & name would be helpful.

Showing all 600 at once might be a bit too much, so maybe they get broken up into pages of 100?

Describe alternatives you've considered

Additional context

Subdirectories give: 500 Internal Server Error

500 Internal Server Error
ValueError occurred. Please try again.
Sample larger than population or is negative

I assume this is due to the number of images and sub folders? if I run it on one folder, it works fine.
Nice work but not useful if it cannot handle large numbers or subfolders.

Roadmap with planned future features

Roadmap

Initial Release 21.3.23

Our first release on March 21st, 2023 marked the beginning of our journey. We were excited to introduce our product to the world, and our team worked hard to ensure that the initial release was a success.

Rewrote Navigation to Use Requests 24.3.23

Just three days later, on March 24th, we made significant improvements to the navigation system. We replaced the old system with the latest requests technology, improving the overall user experience and making it easier to navigate through our application.

Extended Version 3.4.23

On April 3rd, we released an extended version of our application that included a range of new features and improvements. We added support for JPG images, rewrote our EXIF parsing functionality, improved our regex system, and tightened up the UI.

Aesthetic Score 4.4.23

Just one day later, on April 4th, we released an exciting new feature that we're confident our users will love. We added an aesthetic score to our application, allowing users to measure the beauty of their images.


(^ roadmap generated by ChatGPT)

Looking Ahead

  • Moving / copying / deleting / renaming utility functions
  • Analyzing prompts and extracting data (the reason behind the project and its name, Promptvision)

The last point is the main point that I will be focusing my effort on in the future.
The groundwork is done. Metadata and exif parsing are there. What's left is tying it together to be able to browse and extract prompt knowledge that will help you create even better prompts that will give you exactly what you are looking for. This project was originally inspired by multiple things, but one paper did inspire me more; Hard Prompts Made Easy: Gradient-Based Discrete Optimization for Prompt Tuning and Discovery
Of course we could just analyze the models directly and so on, but this approach is more of a discovery based way of finding your hard prompts that generate the results you are looking for.

I am currently either thinking of using Streamlit or Panel to visualize the data that this image viewer generates. This will enable dynamic analysis of all the data by having adjustable dashboards where you can pick and adjust which parameters that should be used to filter out what you want. E.g. adjust to see all images with aesthetic score > 5 where the prompts have "carrot" in them.

There are many possibilities for things that can be done with this. At the top of my head I have ideas such as filtering out all your favourites with atleast 4 stars, do fuzzy matching on their prompts, extract different clusters of prompts and do NLP analysis on the prompts. It isn't a hard task, it's just that a project such as this has so many nuances you can spend much time on such as design, QoL features and so on.

no exception handling

C:\Software\Stable_Diffusion\PromptVision\venv\Lib\site-packages\PIL\Image.py:3167: DecompressionBombWarning: Image size (148897792 pixels) exceeds limit of 89478485 pixels, could be decompression bomb DOS attack.
warnings.warn(
multiprocessing.pool.RemoteTraceback:
"""
Traceback (most recent call last):
File "C:\Python311\Lib\multiprocessing\pool.py", line 125, in worker
result = (True, func(*args, **kwds))
^^^^^^^^^^^^^^^^^^^
File "C:\Software\Stable_Diffusion\PromptVision\gallery.py", line 1019, in read_exif_data
img = Image.open(image)
^^^^^^^^^^^^^^^^^
File "C:\Software\Stable_Diffusion\PromptVision\venv\Lib\site-packages\PIL\Image.py", line 3283, in open
raise UnidentifiedImageError(msg)
PIL.UnidentifiedImageError: cannot identify image file 'C:\Software\Stable_Diffusion\Images\160.jpg'
"""

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "C:\Software\Stable_Diffusion\PromptVision\gallery.py", line 1197, in
bulk_exif_data = mp_bulk_exif_read(filtered_images)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Software\Stable_Diffusion\PromptVision\gallery.py", line 1117, in mp_bulk_exif_read
row = result.get()
^^^^^^^^^^^^
File "C:\Python311\Lib\multiprocessing\pool.py", line 774, in get
raise self._value
PIL.UnidentifiedImageError: cannot identify image file 'C:\Software\Stable_Diffusion\Images\160.jpg'

Dynamic Prompts Support + Minor Issues Reporting

Hey man, sorry to throw out your issue template, bit easier just to speak candidly here since there's kind of a few things I wanted to mention and I didn't want to clutter your Issues tab.


Firstly, nice job on the web app!

If you stick with this and keep improving it I think it'll be a really great tool.

Actual Feature Request

The main point of this Feature Request is to get Dynamic Prompts support added in. As one of the pain points of Dynamic Prompts is that the syntax you use __wildcard_name__ will get converted into the prompt value when saved to metadata, for example __hair__ might become straight blue hair. To assist with reusing prompts you can enable a setting to embed Template and Negative Template in the EXIF data.

Herein lies the problem...

If you have an image that uses this EXIF data, because your code assumes anything that isn't one of the expected tag name: is the positive prompt, it means the template metadata gets swapped in here instead. Namely the very last unexpected tag which is the negative one. See the blue outlined section.

image

Sampler Regex

Next, this is more of a bug than anything, your Regex for parsing the tags kinda dies on certain samplers. See the green outline above. I am actually using DPM++ SDE Karras. I used this Regex: ([\w\s]+):\s([\w\s\+\-\.]+)(?:,\s)? when I was playing around in my fork of your repo. That will match the tag as [0] and the value as [1].

Template Support & Correct Positive Prompt

To get around my templates getting picked up erroneously I also did something similar to this:

for i, key_value in enumerate(exif_data['parameters'].split('\n')):
    if i == 1 :
        parsed_data['Positive prompt'] = key_value

I think assuming the first one is always the positive prompt is fine... there's not much to work with is there? Kind of wish they had a prefix for it but oh well.

Model Hash Format

And this is more a minor request but it'd be nice if in the UI you combined the model name and hash like the UI does in Automatic1111, makes copy pasting the model into XYZ plot easier if you have a crapton of models and don't want to click the autofill button then manually delete everything else.

E.g. model my_model and hash abcd1234 is written as my_model [abcd1234].


Here's what it ends up looking like if you implement some of these fixes and also have the lesser used tags only appear if they contain a value.

image

Final Comments

I'd love it if you could add in Dynamic Prompt support in such a way that it only appears if the EXIF data includes it, as to not clutter your UI for others. If you haven't already used it, give it a shot it's cool as hell.

There's a few other things like monitoring changes in the folder that need improving but hey, one thing at a time.

I'm not holding my breath for any of these changes so you can close this feature request if you don't care much for Dynamic Promtps.

Keep up the good work!

Imaged without Prompt data lead to crash

The Image does not have prompt-data (ComfyUI does not save them, only workflow) and this leads to a crash of the app, if placed into a watched folder.

Place this File into watched folder:
sdxl_txt2img_0002

Produces the following error, on scanning:

IndexError: list index out of range
Traceback:
File "/home/frozen_byte/WebstormProjects/Promptvision/venv/lib/python3.11/site-packages/streamlit/runtime/scriptrunner/script_runner.py", line 552, in _run_script
    exec(code, module.__dict__)
File "/home/frozen_byte/WebstormProjects/Promptvision/Promptvision.py", line 50, in <module>
    helper.set_directory(imagereward=st.session_state.imagereward_check)
File "/home/frozen_byte/WebstormProjects/Promptvision/helper.py", line 27, in set_directory
    st.session_state["df"] = load_data(
                             ^^^^^^^^^^
File "/home/frozen_byte/WebstormProjects/Promptvision/venv/lib/python3.11/site-packages/streamlit/runtime/caching/cache_utils.py", line 211, in wrapper
    return cached_func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/frozen_byte/WebstormProjects/Promptvision/venv/lib/python3.11/site-packages/streamlit/runtime/caching/cache_utils.py", line 240, in __call__
    return self._get_or_create_cached_value(args, kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/frozen_byte/WebstormProjects/Promptvision/venv/lib/python3.11/site-packages/streamlit/runtime/caching/cache_utils.py", line 266, in _get_or_create_cached_value
    return self._handle_cache_miss(cache, value_key, func_args, func_kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/frozen_byte/WebstormProjects/Promptvision/venv/lib/python3.11/site-packages/streamlit/runtime/caching/cache_utils.py", line 320, in _handle_cache_miss
    computed_value = self._info.func(*func_args, **func_kwargs)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/frozen_byte/WebstormProjects/Promptvision/helper.py", line 20, in load_data
    df = pvision.process_directory(
         ^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/frozen_byte/WebstormProjects/Promptvision/pvision.py", line 152, in process_directory
    images = index_directory(
             ^^^^^^^^^^^^^^^^
File "/home/frozen_byte/WebstormProjects/Promptvision/pvision.py", line 55, in index_directory
    positive_prompt = exif.prompts[0][0].value
                      ~~~~~~~~~~~~^^^

Additional context
I am using python venv instead of conda (don't think it matters but that the only non-default setting)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.