mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
fix(ui): fix layer debug
This commit is contained in:
parent
8911017bd1
commit
e7523bd1d9
@ -26,7 +26,7 @@ export const LayerColorPicker = ({ id }: Props) => {
|
||||
<ColorPreview previewColor={layer.color} />
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>
|
||||
<PopoverBody w={64} h={64}>
|
||||
<PopoverBody minH={64}>
|
||||
<RgbColorPicker color={layer.color} onChange={onColorChange} withNumberInput />
|
||||
</PopoverBody>
|
||||
</PopoverContent>
|
||||
|
@ -5,7 +5,13 @@ import { LayerBoundingBox } from 'features/regionalPrompts/components/LayerBound
|
||||
import { LineComponent } from 'features/regionalPrompts/components/LineComponent';
|
||||
import { RectComponent } from 'features/regionalPrompts/components/RectComponent';
|
||||
import { useLayer } from 'features/regionalPrompts/hooks/layerStateHooks';
|
||||
import { $stage, layerBboxChanged, layerTranslated } from 'features/regionalPrompts/store/regionalPromptsSlice';
|
||||
import {
|
||||
$stage,
|
||||
layerBboxChanged,
|
||||
layerTranslated,
|
||||
REGIONAL_PROMPT_LAYER_NAME,
|
||||
REGIONAL_PROMPT_LAYER_OBJECT_GROUP_NAME,
|
||||
} from 'features/regionalPrompts/store/regionalPromptsSlice';
|
||||
import { getKonvaLayerBbox } from 'features/regionalPrompts/util/bbox';
|
||||
import type { Group as KonvaGroupType } from 'konva/lib/Group';
|
||||
import type { Layer as KonvaLayerType } from 'konva/lib/Layer';
|
||||
@ -19,7 +25,8 @@ type Props = {
|
||||
id: string;
|
||||
};
|
||||
|
||||
const filterChildren = (item: KonvaNodeType<KonvaNodeConfigType>) => item.name() !== 'regionalPromptLayerObjectGroup';
|
||||
export const selectPromptLayerObjectGroup = (item: KonvaNodeType<KonvaNodeConfigType>) =>
|
||||
item.name() !== REGIONAL_PROMPT_LAYER_OBJECT_GROUP_NAME;
|
||||
|
||||
export const LayerComponent: React.FC<Props> = ({ id }) => {
|
||||
const dispatch = useAppDispatch();
|
||||
@ -74,7 +81,7 @@ export const LayerComponent: React.FC<Props> = ({ id }) => {
|
||||
onChangeBbox(null);
|
||||
return;
|
||||
}
|
||||
onChangeBbox(getKonvaLayerBbox(layerRef.current, filterChildren));
|
||||
onChangeBbox(getKonvaLayerBbox(layerRef.current, selectPromptLayerObjectGroup));
|
||||
}, [tool, layer.objects, onChangeBbox]);
|
||||
|
||||
if (!layer.isVisible) {
|
||||
@ -85,8 +92,8 @@ export const LayerComponent: React.FC<Props> = ({ id }) => {
|
||||
<>
|
||||
<KonvaLayer
|
||||
ref={layerRef}
|
||||
id={`layer-${layer.id}`}
|
||||
name="regionalPromptLayer"
|
||||
id={layer.id}
|
||||
name={REGIONAL_PROMPT_LAYER_NAME}
|
||||
onDragEnd={onDragEnd}
|
||||
onDragMove={onDragMove}
|
||||
dragBoundFunc={dragBoundFunc}
|
||||
@ -94,7 +101,7 @@ export const LayerComponent: React.FC<Props> = ({ id }) => {
|
||||
>
|
||||
<KonvaGroup
|
||||
id={`layer-${layer.id}-group`}
|
||||
name="regionalPromptLayerObjectGroup"
|
||||
name={REGIONAL_PROMPT_LAYER_OBJECT_GROUP_NAME}
|
||||
ref={groupRef}
|
||||
listening={false}
|
||||
>
|
||||
|
@ -8,19 +8,23 @@ import { LayerListItem } from 'features/regionalPrompts/components/LayerListItem
|
||||
import { RegionalPromptsStage } from 'features/regionalPrompts/components/RegionalPromptsStage';
|
||||
import { ToolChooser } from 'features/regionalPrompts/components/ToolChooser';
|
||||
import { selectRegionalPromptsSlice } from 'features/regionalPrompts/store/regionalPromptsSlice';
|
||||
import { getLayerBlobs } from 'features/regionalPrompts/util/getLayerBlobs';
|
||||
import { getRegionalPromptLayerBlobs } from 'features/regionalPrompts/util/getLayerBlobs';
|
||||
import { ImageSizeLinear } from 'features/settingsAccordions/components/ImageSettingsAccordion/ImageSizeLinear';
|
||||
|
||||
const selectLayerIdsReversed = createSelector(selectRegionalPromptsSlice, (regionalPrompts) =>
|
||||
regionalPrompts.layers.map((l) => l.id).reverse()
|
||||
);
|
||||
|
||||
const debugBlobs = () => {
|
||||
getRegionalPromptLayerBlobs(true);
|
||||
};
|
||||
|
||||
export const RegionalPromptsEditor = () => {
|
||||
const layerIdsReversed = useAppSelector(selectLayerIdsReversed);
|
||||
return (
|
||||
<Flex gap={4}>
|
||||
<Flex flexDir="column" gap={4} flexShrink={0}>
|
||||
<Button onClick={getLayerBlobs}>DEBUG LAYERS</Button>
|
||||
<Button onClick={debugBlobs}>DEBUG LAYERS</Button>
|
||||
<AddLayerButton />
|
||||
<BrushSize />
|
||||
<ImageSizeLinear />
|
||||
|
@ -270,3 +270,5 @@ export const getStage = (): Konva.Stage => {
|
||||
assert(stage);
|
||||
return stage;
|
||||
};
|
||||
export const REGIONAL_PROMPT_LAYER_NAME = 'regionalPromptLayer';
|
||||
export const REGIONAL_PROMPT_LAYER_OBJECT_GROUP_NAME = 'regionalPromptLayerObjectGroup';
|
||||
|
@ -1,26 +1,51 @@
|
||||
import { getStore } from 'app/store/nanostores/store';
|
||||
import openBase64ImageInTab from 'common/util/openBase64ImageInTab';
|
||||
import { blobToDataURL } from 'features/canvas/util/blobToDataURL';
|
||||
import { $stage } from 'features/regionalPrompts/store/regionalPromptsSlice';
|
||||
import { selectPromptLayerObjectGroup } from 'features/regionalPrompts/components/LayerComponent';
|
||||
import { $stage, REGIONAL_PROMPT_LAYER_NAME } from 'features/regionalPrompts/store/regionalPromptsSlice';
|
||||
import Konva from 'konva';
|
||||
import { assert } from 'tsafe';
|
||||
|
||||
export const getLayerBlobs = async () => {
|
||||
export const getRegionalPromptLayerBlobs = async (preview: boolean = false): Promise<Record<string, Blob>> => {
|
||||
const state = getStore().getState();
|
||||
const stage = $stage.get();
|
||||
assert(stage !== null, 'Stage is null');
|
||||
const stageLayers = stage.getLayers().filter((l) => l.name() === 'regionalPromptLayer');
|
||||
for (const layer of stageLayers) {
|
||||
const regionalPromptLayers = stage.getLayers().filter((l) => l.name() === REGIONAL_PROMPT_LAYER_NAME);
|
||||
|
||||
// We need to reconstruct each layer to only output the desired data. This logic mirrors the logic in
|
||||
// `getKonvaLayerBbox()` in `invokeai/frontend/web/src/features/regionalPrompts/util/bbox.ts`
|
||||
const offscreenStageContainer = document.createElement('div');
|
||||
const offscreenStage = new Konva.Stage({
|
||||
container: offscreenStageContainer,
|
||||
width: stage.width(),
|
||||
height: stage.height(),
|
||||
});
|
||||
|
||||
const blobs: Record<string, Blob> = {};
|
||||
|
||||
for (const layer of regionalPromptLayers) {
|
||||
const layerClone = layer.clone();
|
||||
for (const child of layerClone.getChildren(selectPromptLayerObjectGroup)) {
|
||||
child.destroy();
|
||||
}
|
||||
offscreenStage.add(layerClone);
|
||||
const blob = await new Promise<Blob>((resolve) => {
|
||||
layer.toBlob({
|
||||
offscreenStage.toBlob({
|
||||
callback: (blob) => {
|
||||
assert(blob, 'Blob is null');
|
||||
resolve(blob);
|
||||
},
|
||||
});
|
||||
});
|
||||
const base64 = await blobToDataURL(blob);
|
||||
const prompt = state.regionalPrompts.layers.find((l) => l.id === layer.id())?.prompt;
|
||||
assert(prompt !== undefined, 'Prompt is undefined');
|
||||
openBase64ImageInTab([{ base64, caption: prompt }]);
|
||||
blobs[layer.id()] = blob;
|
||||
|
||||
if (preview) {
|
||||
const base64 = await blobToDataURL(blob);
|
||||
const prompt = state.regionalPrompts.layers.find((l) => l.id === layer.id())?.prompt;
|
||||
openBase64ImageInTab([{ base64, caption: prompt ?? '' }]);
|
||||
}
|
||||
layerClone.destroy();
|
||||
}
|
||||
|
||||
return blobs;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user