mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): wip canvas
This commit is contained in:
@ -1,39 +0,0 @@
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import {
|
||||
FrontendToBackendParametersConfig,
|
||||
frontendToBackendParameters,
|
||||
} from 'common/util/parameterTranslation';
|
||||
import { generationSelector } from 'features/parameters/store/generationSelectors';
|
||||
import { postprocessingSelector } from 'features/parameters/store/postprocessingSelectors';
|
||||
import { systemSelector } from 'features/system/store/systemSelectors';
|
||||
import { canvasSelector } from '../store/canvasSelectors';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
|
||||
const selector = createSelector(
|
||||
[generationSelector, postprocessingSelector, systemSelector, canvasSelector],
|
||||
(generation, postprocessing, system, canvas) => {
|
||||
const frontendToBackendParametersConfig: FrontendToBackendParametersConfig =
|
||||
{
|
||||
generationMode: 'unifiedCanvas',
|
||||
generationState: generation,
|
||||
postprocessingState: postprocessing,
|
||||
canvasState: canvas,
|
||||
systemState: system,
|
||||
};
|
||||
|
||||
return frontendToBackendParametersConfig;
|
||||
}
|
||||
);
|
||||
|
||||
export const usePrepareCanvasState = () => {
|
||||
const frontendToBackendParametersConfig = useAppSelector(selector);
|
||||
|
||||
const getGenerationParameters = useCallback(() => {
|
||||
const { generationParameters, esrganParameters, facetoolParameters } =
|
||||
frontendToBackendParameters(frontendToBackendParametersConfig);
|
||||
console.log(generationParameters);
|
||||
}, [frontendToBackendParametersConfig]);
|
||||
|
||||
return getGenerationParameters;
|
||||
};
|
@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Gets a Blob from a canvas.
|
||||
*/
|
||||
export const canvasToBlob = async (canvas: HTMLCanvasElement): Promise<Blob> =>
|
||||
new Promise((resolve, reject) => {
|
||||
canvas.toBlob((blob) => {
|
||||
if (blob) {
|
||||
resolve(blob);
|
||||
return;
|
||||
}
|
||||
reject('Unable to create Blob');
|
||||
});
|
||||
});
|
@ -1,3 +1,6 @@
|
||||
/**
|
||||
* Gets an ImageData object from an image dataURL by drawing it to a canvas.
|
||||
*/
|
||||
export const dataURLToImageData = async (
|
||||
dataURL: string,
|
||||
width: number,
|
@ -104,6 +104,7 @@
|
||||
import { CanvasMaskLine } from 'features/canvas/store/canvasTypes';
|
||||
import Konva from 'konva';
|
||||
import { IRect } from 'konva/lib/types';
|
||||
import { canvasToBlob } from './canvasToBlob';
|
||||
|
||||
/**
|
||||
* Generating a mask image from InpaintingCanvas.tsx is not as simple
|
||||
@ -115,7 +116,7 @@ import { IRect } from 'konva/lib/types';
|
||||
* drawing the mask and compositing everything correctly to output a valid
|
||||
* mask image.
|
||||
*/
|
||||
const generateMask = (lines: CanvasMaskLine[], boundingBox: IRect): string => {
|
||||
const generateMask = async (lines: CanvasMaskLine[], boundingBox: IRect) => {
|
||||
// create an offscreen canvas and add the mask to it
|
||||
const { width, height } = boundingBox;
|
||||
|
||||
@ -157,11 +158,13 @@ const generateMask = (lines: CanvasMaskLine[], boundingBox: IRect): string => {
|
||||
stage.add(baseLayer);
|
||||
stage.add(maskLayer);
|
||||
|
||||
const dataURL = stage.toDataURL({ ...boundingBox });
|
||||
const maskDataURL = stage.toDataURL(boundingBox);
|
||||
|
||||
const maskBlob = await canvasToBlob(stage.toCanvas(boundingBox));
|
||||
|
||||
offscreenContainer.remove();
|
||||
|
||||
return dataURL;
|
||||
return { maskDataURL, maskBlob };
|
||||
};
|
||||
|
||||
export default generateMask;
|
||||
|
@ -8,7 +8,8 @@ import {
|
||||
} from 'common/util/arrayBuffer';
|
||||
import openBase64ImageInTab from 'common/util/openBase64ImageInTab';
|
||||
import generateMask from './generateMask';
|
||||
import { dataURLToImageData } from './dataURLToUint8ClampedArray';
|
||||
import { dataURLToImageData } from './dataURLToImageData';
|
||||
import { canvasToBlob } from './canvasToBlob';
|
||||
|
||||
const moduleLog = log.child({ namespace: 'getCanvasDataURLs' });
|
||||
|
||||
@ -62,10 +63,13 @@ export const getCanvasData = async (state: RootState) => {
|
||||
};
|
||||
|
||||
const baseDataURL = canvasBaseLayer.toDataURL(offsetBoundingBox);
|
||||
const baseBlob = await canvasToBlob(
|
||||
canvasBaseLayer.toCanvas(offsetBoundingBox)
|
||||
);
|
||||
|
||||
canvasBaseLayer.scale(tempScale);
|
||||
|
||||
const maskDataURL = generateMask(
|
||||
const { maskDataURL, maskBlob } = await generateMask(
|
||||
isMaskEnabled ? objects.filter(isCanvasMaskLine) : [],
|
||||
boundingBox
|
||||
);
|
||||
@ -82,9 +86,6 @@ export const getCanvasData = async (state: RootState) => {
|
||||
boundingBox.height
|
||||
);
|
||||
|
||||
console.log('baseImageData', baseImageData);
|
||||
console.log('maskImageData', maskImageData);
|
||||
|
||||
const {
|
||||
isPartiallyTransparent: baseIsPartiallyTransparent,
|
||||
isFullyTransparent: baseIsFullyTransparent,
|
||||
@ -117,7 +118,9 @@ export const getCanvasData = async (state: RootState) => {
|
||||
|
||||
return {
|
||||
baseDataURL,
|
||||
baseBlob,
|
||||
maskDataURL,
|
||||
maskBlob,
|
||||
baseIsPartiallyTransparent,
|
||||
baseIsFullyTransparent,
|
||||
doesMaskHaveBlackPixels,
|
||||
|
Reference in New Issue
Block a user