AUTOMATIC1111 / stable-diffusion-webui

Stable Diffusion web UI
GNU Affero General Public License v3.0
142.65k stars 26.91k forks source link

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

Closed micky2be closed 1 week ago

micky2be commented 1 year ago

Is there an existing issue for this?

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

missionfloyd commented 1 year ago

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

micky2be commented 1 year ago

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 commented 1 year ago

X/Y/Z plot uses the same setting. https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/22bcc7be428c94e9408f589966c2040187245d81/scripts/xyz_grid.py#L669-L675 https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/22bcc7be428c94e9408f589966c2040187245d81/modules/shared.py#L231

micky2be commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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

paintbot commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

@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 commented 11 months ago

Any update?

Shurale7 commented 10 months ago

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 commented 10 months ago

@Shurale7 feel free to use my alternative solution

EchoHeadache commented 6 months ago

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 commented 3 months ago

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 commented 2 months ago