Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request]: Option for not having a grid for X/Y/Z Plot #9399

Open
1 task done
micky2be opened this issue Apr 5, 2023 · 17 comments
Open
1 task done

[Feature Request]: Option for not having a grid for X/Y/Z Plot #9399

micky2be opened this issue Apr 5, 2023 · 17 comments
Labels
enhancement New feature or request

Comments

@micky2be
Copy link
Contributor

micky2be commented Apr 5, 2023

Is there an existing issue for this?

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

What would your feature do ?

I sometime want to generate a bunch of images from X/Y/Z plot system, although I don't need a grid.
And more importantly, the grid image has a limit of 200 MP which is blocking me from running different tests.
It's also weird there are option for batch grids, which do not apply to this one.

Proposed workflow

  1. Go to Script
  2. Select X/Y/Z Plot
  3. Uncheck the option to create a grid

Additional information

No response

@micky2be micky2be added the enhancement New feature or request label Apr 5, 2023
@missionfloyd
Copy link
Collaborator

You can disable saving grids and increase the resolution limit in settings (Saving images/grids).

@micky2be
Copy link
Contributor Author

micky2be commented Apr 7, 2023

For the file size, yes. For turning off the grid, no.
sure, it works for batches, but it's not applied for X/Y/Z plot. And couldn't find anything in the code to suggest there is such option.
That, or I'm blind.

@missionfloyd
Copy link
Collaborator

X/Y/Z plot uses the same setting.

if opts.grid_save:
# Auto-save main and sub-grids:
grid_count = z_count + 1 if z_count > 1 else 1
for g in range(grid_count):
#TODO: See previous comment about intentional data misalignment.
adj_g = g-1 if g > 0 else g
images.save_image(processed.images[g], p.outpath_grids, "xyz_grid", info=processed.infotexts[g], extension=opts.grid_format, prompt=processed.all_prompts[adj_g], seed=processed.all_seeds[adj_g], grid=True, p=processed)

"grid_save": OptionInfo(True, "Always save all generated image grids"),

@micky2be
Copy link
Contributor Author

micky2be commented Apr 9, 2023

This is the setting to save the image, not the generation of the image.
The grid will always generate no matter the option selected.

@TheOnlyHolyMoly
Copy link

I am struggling with the same issue... want to rotate a prompt through 600 checkpoints to see what models might work best for me... and every time I run into memory allocation issues as the grid generates internally... machine crashes before he could even consider NOT saving....

@DejitaruJin
Copy link
Contributor

This is an interesting idea, and, the last I looked at that script, very easy to implement. Even if only a couple people would need it, I think it's maybe 3 lines of code?

Then again, the script also needs better error handling and recovery anyways; would it be acceptable if the primary grid generation just failed gracefully and presented the images it collected?

@TheOnlyHolyMoly
Copy link

SD.next actually already has this feature implemented in the XYZ script. @AUTOMATIC1111 would just need to pull that into main branch.

@paintbot
Copy link

paintbot commented Jul 3, 2023

yes please @AUTOMATIC1111 include this option, would be so helpful as you can create really cool videos with the xy plot script where the grid is just hindering..

@dejayc
Copy link

dejayc commented Jul 13, 2023

While you're waiting for this feature to land, make the following changes to xyz_grid.py:

Look for following code:

        grid = images.image_grid(processed_result.images[start_index:end_index], rows=len(ys))
        if draw_legend:
            grid = images.draw_grid_annotations(grid, processed_result.images[start_index].size[0], processed_result.images[start_index].size[1], hor_texts, ver_texts, margin_size)
        processed_result.images.insert(i, grid)

Modify it as follows:

        # grid = images.image_grid(processed_result.images[start_index:end_index], rows=len(ys))
        if draw_legend:
            # grid = images.draw_grid_annotations(grid, processed_result.images[start_index].size[0], processed_result.images[start_index].size[1], hor_texts, ver_texts, margin_size)
            pass
        # processed_result.images.insert(i, grid)

Similarly, look for the following code:

    z_grid = images.image_grid(processed_result.images[:z_count], rows=1)
    if draw_legend:
        z_grid = images.draw_grid_annotations(z_grid, sub_grid_size[0], sub_grid_size[1], title_texts, [[images.GridAnnotation()]])
    processed_result.images.insert(0, z_grid)

Modify it as follows:

    # z_grid = images.image_grid(processed_result.images[:z_count], rows=1)
    if draw_legend:
        # z_grid = images.draw_grid_annotations(z_grid, sub_grid_size[0], sub_grid_size[1], title_texts, [[images.GridAnnotation()]])
        pass
    # processed_result.images.insert(0, z_grid)

Comment out the assertion that causes the script to fail:

# assert grid_mp < opts.img_max_size_mp, f'Error: Resulting grid would be too large ({grid_mp} MPixels) (max configured size is {opts.img_max_size_mp} MPixels)'

You can now enjoy x/y/z without generating or saving the grid.

@NoteToSelfFindGoodNickname

While you're waiting for this feature to land, make the following changes to xyz_grid.py:

Look for following code:

        grid = images.image_grid(processed_result.images[start_index:end_index], rows=len(ys))
        if draw_legend:
            grid = images.draw_grid_annotations(grid, processed_result.images[start_index].size[0], processed_result.images[start_index].size[1], hor_texts, ver_texts, margin_size)
        processed_result.images.insert(i, grid)

Modify it as follows:

        # grid = images.image_grid(processed_result.images[start_index:end_index], rows=len(ys))
        if draw_legend:
            # grid = images.draw_grid_annotations(grid, processed_result.images[start_index].size[0], processed_result.images[start_index].size[1], hor_texts, ver_texts, margin_size)
            pass
        # processed_result.images.insert(i, grid)

Similarly, look for the following code:

    z_grid = images.image_grid(processed_result.images[:z_count], rows=1)
    if draw_legend:
        z_grid = images.draw_grid_annotations(z_grid, sub_grid_size[0], sub_grid_size[1], title_texts, [[images.GridAnnotation()]])
    processed_result.images.insert(0, z_grid)

Modify it as follows:

    # z_grid = images.image_grid(processed_result.images[:z_count], rows=1)
    if draw_legend:
        # z_grid = images.draw_grid_annotations(z_grid, sub_grid_size[0], sub_grid_size[1], title_texts, [[images.GridAnnotation()]])
        pass
    # processed_result.images.insert(0, z_grid)

Comment out the assertion that causes the script to fail:

# assert grid_mp < opts.img_max_size_mp, f'Error: Resulting grid would be too large ({grid_mp} MPixels) (max configured size is {opts.img_max_size_mp} MPixels)'

You can now enjoy x/y/z without generating or saving the grid.

No, that will result in many errors which make things break apart.

@wynandhuizinga
Copy link

@AUTOMATIC1111 , this should be the commit which adds this:
Commit
Would love to see this implemented. My PC occasionally crashes from 500+ images getting put on one massive canvas.

@alexdosa92
Copy link

Any update?

@Shurale7
Copy link

I am struggling with the same issue... want to rotate a prompt through 600 checkpoints to see what models might work best for me... and every time I run into memory allocation issues as the grid generates internally... machine crashes before he could even consider NOT saving....

I have exactly the same problem. For me, it is simply impossible to run the prompt through checkpoints, limited as it is to 200 megapixels. I don’t need this collage at all. It’s incredible that there isn’t even an option to run a prompt without artificial limitations.

@micky2be
Copy link
Contributor Author

@Shurale7 feel free to use my alternative solution

@EchoHeadache
Copy link

EchoHeadache commented Apr 26, 2024

While you're waiting for this feature to land, make the following changes to xyz_grid.py:

Look for following code:

        grid = images.image_grid(processed_result.images[start_index:end_index], rows=len(ys))
        if draw_legend:
            grid = images.draw_grid_annotations(grid, processed_result.images[start_index].size[0], processed_result.images[start_index].size[1], hor_texts, ver_texts, margin_size)
        processed_result.images.insert(i, grid)

Modify it as follows:

        # grid = images.image_grid(processed_result.images[start_index:end_index], rows=len(ys))
        if draw_legend:
            # grid = images.draw_grid_annotations(grid, processed_result.images[start_index].size[0], processed_result.images[start_index].size[1], hor_texts, ver_texts, margin_size)
            pass
        # processed_result.images.insert(i, grid)

Similarly, look for the following code:

    z_grid = images.image_grid(processed_result.images[:z_count], rows=1)
    if draw_legend:
        z_grid = images.draw_grid_annotations(z_grid, sub_grid_size[0], sub_grid_size[1], title_texts, [[images.GridAnnotation()]])
    processed_result.images.insert(0, z_grid)

Modify it as follows:

    # z_grid = images.image_grid(processed_result.images[:z_count], rows=1)
    if draw_legend:
        # z_grid = images.draw_grid_annotations(z_grid, sub_grid_size[0], sub_grid_size[1], title_texts, [[images.GridAnnotation()]])
        pass
    # processed_result.images.insert(0, z_grid)

Comment out the assertion that causes the script to fail:

# assert grid_mp < opts.img_max_size_mp, f'Error: Resulting grid would be too large ({grid_mp} MPixels) (max configured size is {opts.img_max_size_mp} MPixels)'

You can now enjoy x/y/z without generating or saving the grid.

For those that wish to utilize this solution, take the advice above but instead of modifying the existing xyz_grid.py, copy the file and name it something else, and find the line:
class Script(scripts.Script): def title(self): return "X/Y/Z plot"

and modify the return value to give it a new discreet name in the drop-down list in the gui:

class Script(scripts.Script): def title(self): return "X/Y/Z plot NO GRID"

after both of these edits are complete, exit automatic1111 and be absolutely sure to close any open UI as these lists are cached and you will get errors if you try to generate from a page with old scripts cached.

Creating a new script with the edits and naming it as such allows you to freely select a grid-less xyz plot at will, and leaves the grid-generating one for you to return to, without modifying the .py again.

I've tested this successfully on v1.9.3

@Gabled-Waters
Copy link

I followed the suggestion of @EchoHeadache but it would indeed be useful to have this implemented. I often run tests of my lora over different checkpoints with various settings, and these easily generate 1000+ images.

@w-e-w
Copy link
Collaborator

w-e-w commented Aug 22, 2024

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests