mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-04-23 03:00:31 -04:00
fix(ui): save canvas to gallery does nothing
The root issue is the compositing cache. When we save the canvas to gallery, we need to first composite raster layers together and then upload the image. The compositor makes extensive use of caching to reduce the number of images created and improve performance. There are two "layers" of caching: 1. Caching the composite canvas element, which is used both for uploading the canvas and for generation mode analysis. 2. Caching the uploaded composite canvas element as an image. The combination of these caches allows for the various processes that require composite canvases to do minimal work. But this causes a problem in this situation, because the user expects a new image to be uploaded when they click save to gallery. For example, suppose we have already composited and uploaded the raster layer state for use in a generation. Then, we ask the compositor to save the canvas to gallery. The compositor sees that we are requesting an image for the current canvas state, and instead of recompositing and uploading the image again, it just returns the cached image. In this case, no image is uploaded and it the button does nothing. We need to be able to opt out of the caching at some level, for certain actions. A `forceUpload` arg is added to the compositor's high-level `getCompositeImageDTO` method to do this. When true, we ignore the uppermost caching layer (the uploaded image layer), but still use the lower caching layer (the canvas element layer). So we don't recompute the canvas element, but we do upload it as a new image to the server.
This commit is contained in:
committed by
Kent Keirsey
parent
24d3c22017
commit
cd3d8df5a8
@@ -72,10 +72,16 @@ const useSaveCanvas = ({ region, saveToGallery, toastOk, toastError, onSave, wit
|
||||
|
||||
const result = await withResultAsync(() => {
|
||||
const rasterAdapters = canvasManager.compositor.getVisibleAdaptersOfType('raster_layer');
|
||||
return canvasManager.compositor.getCompositeImageDTO(rasterAdapters, rect, {
|
||||
is_intermediate: !saveToGallery,
|
||||
metadata,
|
||||
});
|
||||
return canvasManager.compositor.getCompositeImageDTO(
|
||||
rasterAdapters,
|
||||
rect,
|
||||
{
|
||||
is_intermediate: !saveToGallery,
|
||||
metadata,
|
||||
},
|
||||
undefined,
|
||||
true // force upload the image to ensure it gets added to the gallery
|
||||
);
|
||||
});
|
||||
|
||||
if (result.isOk()) {
|
||||
|
||||
@@ -253,18 +253,20 @@ export class CanvasCompositorModule extends CanvasModuleBase {
|
||||
* @param rect The region to include in the rasterized image
|
||||
* @param uploadOptions Options for uploading the image
|
||||
* @param compositingOptions Options for compositing the entities
|
||||
* @param forceUpload If true, the image is always re-uploaded, returning a new image DTO
|
||||
* @returns A promise that resolves to the image DTO
|
||||
*/
|
||||
getCompositeImageDTO = async (
|
||||
adapters: CanvasEntityAdapter[],
|
||||
rect: Rect,
|
||||
uploadOptions: Pick<UploadOptions, 'is_intermediate' | 'metadata'>,
|
||||
compositingOptions?: CompositingOptions
|
||||
compositingOptions?: CompositingOptions,
|
||||
forceUpload?: boolean
|
||||
): Promise<ImageDTO> => {
|
||||
assert(rect.width > 0 && rect.height > 0, 'Unable to rasterize empty rect');
|
||||
|
||||
const hash = this.getCompositeHash(adapters, { rect });
|
||||
const cachedImageName = this.manager.cache.imageNameCache.get(hash);
|
||||
const cachedImageName = forceUpload ? undefined : this.manager.cache.imageNameCache.get(hash);
|
||||
|
||||
let imageDTO: ImageDTO | null = null;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user