mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
fix(ui): caching broke layer rendering
This commit is contained in:
parent
de7ecc8e3e
commit
cf4c1750cb
@ -1,3 +1,5 @@
|
||||
import openBase64ImageInTab from 'common/util/openBase64ImageInTab';
|
||||
import { imageDataToDataURL } from 'features/canvas/util/blobToDataURL';
|
||||
import Konva from 'konva';
|
||||
import type { Layer as KonvaLayerType } from 'konva/lib/Layer';
|
||||
import type { Node as KonvaNodeType, NodeConfig as KonvaNodeConfigType } from 'konva/lib/Node';
|
||||
@ -35,10 +37,12 @@ export const getImageDataBbox = (imageData: ImageData) => {
|
||||
* Get the bounding box of a regional prompt konva layer. This function has special handling for regional prompt layers.
|
||||
* @param layer The konva layer to get the bounding box of.
|
||||
* @param filterChildren Optional filter function to exclude certain children from the bounding box calculation. Defaults to including all children.
|
||||
* @param preview Whether to open a new tab displaying the rendered layer, which is used to calculate the bbox.
|
||||
*/
|
||||
export const getKonvaLayerBbox = (
|
||||
layer: KonvaLayerType,
|
||||
filterChildren?: (item: KonvaNodeType<KonvaNodeConfigType>) => boolean
|
||||
filterChildren?: (item: KonvaNodeType<KonvaNodeConfigType>) => boolean,
|
||||
preview: boolean = false
|
||||
): IRect => {
|
||||
// To calculate the layer's bounding box, we must first render it to a pixel array, then do some math.
|
||||
// We can't use konva's `layer.getClientRect()`, because this includes all shapes, not just visible ones.
|
||||
@ -57,14 +61,17 @@ export const getKonvaLayerBbox = (
|
||||
// TODO: Would be more efficient to create a totally new layer and add only the children we want, but possibly less
|
||||
// accurate, as we wouldn't get the original layer's config and such.
|
||||
const layerClone = layer.clone();
|
||||
if (filterChildren) {
|
||||
for (const child of layerClone.getChildren(filterChildren)) {
|
||||
offscreenStage.add(layerClone);
|
||||
|
||||
for (const child of layerClone.getChildren()) {
|
||||
if (filterChildren && filterChildren(child)) {
|
||||
child.destroy();
|
||||
} else {
|
||||
// We need to re-cache to handle children with transparency and multiple objects - like prompt region layers.
|
||||
child.cache();
|
||||
}
|
||||
}
|
||||
|
||||
offscreenStage.add(layerClone.clone());
|
||||
|
||||
// Get the layer's image data, ensuring we capture an area large enough to include the full layer, including any
|
||||
// portions that are outside the current stage bounds.
|
||||
const layerRect = layerClone.getClientRect();
|
||||
@ -82,6 +89,10 @@ export const getKonvaLayerBbox = (
|
||||
?.getImageData(0, 0, width, height);
|
||||
assert(layerImageData, "Unable to get layer's image data");
|
||||
|
||||
if (preview) {
|
||||
openBase64ImageInTab([{ base64: imageDataToDataURL(layerImageData), caption: layer.id() }]);
|
||||
}
|
||||
|
||||
// Calculate the layer's bounding box.
|
||||
const layerBbox = getImageDataBbox(layerImageData);
|
||||
|
||||
|
@ -6,6 +6,11 @@ import { $stage, REGIONAL_PROMPT_LAYER_NAME } from 'features/regionalPrompts/sto
|
||||
import Konva from 'konva';
|
||||
import { assert } from 'tsafe';
|
||||
|
||||
/**
|
||||
* Get the blobs of all regional prompt layers.
|
||||
* @param preview Whether to open a new tab displaying each layer.
|
||||
* @returns A map of layer IDs to blobs.
|
||||
*/
|
||||
export const getRegionalPromptLayerBlobs = async (preview: boolean = false): Promise<Record<string, Blob>> => {
|
||||
const state = getStore().getState();
|
||||
const stage = $stage.get();
|
||||
@ -27,8 +32,13 @@ export const getRegionalPromptLayerBlobs = async (preview: boolean = false): Pro
|
||||
|
||||
for (const layer of regionalPromptLayers) {
|
||||
const layerClone = layer.clone();
|
||||
for (const child of layerClone.getChildren(selectPromptLayerObjectGroup)) {
|
||||
child.destroy();
|
||||
for (const child of layerClone.getChildren()) {
|
||||
if (selectPromptLayerObjectGroup(child)) {
|
||||
child.destroy();
|
||||
} else {
|
||||
// We need to re-cache to handle children with transparency and multiple objects - like prompt region layers.
|
||||
child.cache();
|
||||
}
|
||||
}
|
||||
offscreenStage.add(layerClone);
|
||||
const blob = await new Promise<Blob>((resolve) => {
|
||||
|
Loading…
Reference in New Issue
Block a user