automaticism / promptvision Goto Github PK
View Code? Open in Web Editor NEWLocal viewer for Stable Diffusion generated images (with EXIF data) built with Streamlit.
License: MIT License
Local viewer for Stable Diffusion generated images (with EXIF data) built with Streamlit.
License: MIT License
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 themThe 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:
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)
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.
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.
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.
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)
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.
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.
Promptvision v0.3 (or whatever is current on 2023/03/24 @ 2AM CST)
Firefox 111.0.1
MacOS 13.2.1
32Gb M1 Max
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.
python gallery.py --imagedir /Users/user/-AI/REFERENCE/GRABS
http://127.0.0.1:8000
or http://192.168.1.69:8000
into browser127.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 -
The ability to delete images would be a godsend when reviewing
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.
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):
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.
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)
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.
Desktop (please complete the following information):
Promptvision (current on 2023/03/26 @ 4PM CST)
Firefox 111.0.1
MacOS 13.2.1
32Gb M1 Max
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.
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.
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 -
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.
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?
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'
Is your feature request related to a problem? Please describe.
Describe the solution you'd like
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'):
...
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)
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?
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.
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
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:
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
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.
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;
}
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.
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.
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!
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.
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.
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]
.
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.
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.
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!
Promptvision v0.2
MacOS 13.2.1
32Gb M1 Max
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.
Run the command (on a similar system).
user@rig Promptvision % python gallery.py --imagedir /Users/user/-AI/REFERENCE/GRABS
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
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'
Is your feature request related to a problem? Please describe.
When there are non-picture files in the folder, it will raise <PIL.UnidentifiedImageError>.
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.
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)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.