feat(ui): wip canvas

This commit is contained in:
psychedelicious
2023-05-05 00:06:50 +10:00
parent 206e6b1730
commit 1c9429a6ea
33 changed files with 712 additions and 222 deletions

View File

@ -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');
});
});

View File

@ -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,

View File

@ -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;

View File

@ -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,