import { RefObject } from 'react'; import { canvasSize } from './generativeFillConstants'; export interface APISuccess { status: 'success'; urls: string[]; } export interface APIError { status: 'error'; message: string; } export class ImageUtility { static canvasToBlob = (canvas: HTMLCanvasElement): Promise => { return new Promise(resolve => { canvas.toBlob(blob => { if (blob) { resolve(blob); } }, 'image/png'); }); }; static getEdit = async (imgBlob: Blob, maskBlob: Blob, prompt: string, n?: number): Promise => { const apiUrl = 'https://api.openai.com/v1/images/edits'; const fd = new FormData(); fd.append('image', imgBlob, 'image.png'); fd.append('mask', maskBlob, 'mask.png'); fd.append('prompt', prompt); fd.append('size', '1024x1024'); fd.append('n', n ? JSON.stringify(n) : '1'); fd.append('response_format', 'b64_json'); try { const res = await fetch(apiUrl, { method: 'POST', headers: { Authorization: `Bearer ${process.env.OPENAI_KEY}`, }, body: fd, }); const data = await res.json(); console.log(data.data); return { status: 'success', urls: (data.data as { b64_json: string }[]).map(data => `data:image/png;base64,${data.b64_json}`), }; } catch (err) { console.log(err); return { status: 'error', message: 'API error.' }; } }; static mockGetEdit = async (mockSrc: string): Promise => { return { status: 'success', urls: [mockSrc, mockSrc, mockSrc], }; }; static getCanvasContext = (canvasRef: RefObject): CanvasRenderingContext2D | null => { if (!canvasRef.current) return null; const ctx = canvasRef.current.getContext('2d'); if (!ctx) return null; return ctx; }; static downloadCanvas = (canvas: HTMLCanvasElement) => { const url = canvas.toDataURL(); const downloadLink = document.createElement('a'); downloadLink.href = url; downloadLink.download = 'canvas'; downloadLink.click(); downloadLink.remove(); }; static downloadImageCanvas = (imgUrl: string) => { const img = new Image(); img.src = imgUrl; img.onload = () => { const canvas = document.createElement('canvas'); canvas.width = canvasSize; canvas.height = canvasSize; const ctx = canvas.getContext('2d'); ctx?.drawImage(img, 0, 0, canvasSize, canvasSize); this.downloadCanvas(canvas); }; }; static drawImgToCanvas = (img: HTMLImageElement, canvasRef: React.RefObject, loaded?: boolean) => { if (loaded) { const ctx = this.getCanvasContext(canvasRef); if (!ctx) return; ctx.globalCompositeOperation = 'source-over'; const scale = Math.max(canvasSize / img.width, canvasSize / img.height); const width = img.width * scale; const height = img.height * scale; ctx.clearRect(0, 0, canvasSize, canvasSize); ctx.drawImage(img, 0, 0, width, height); } else { img.onload = () => { const ctx = this.getCanvasContext(canvasRef); if (!ctx) return; ctx.globalCompositeOperation = 'source-over'; const scale = Math.max(canvasSize / img.width, canvasSize / img.height); const width = img.width * scale; const height = img.height * scale; ctx.clearRect(0, 0, canvasSize, canvasSize); ctx.drawImage(img, 0, 0, width, height); }; } }; // The image must be loaded! static getCanvasImg = (img: HTMLImageElement): HTMLCanvasElement => { const canvas = document.createElement('canvas'); canvas.width = canvasSize; canvas.height = canvasSize; const ctx = canvas.getContext('2d'); ctx?.clearRect(0, 0, canvasSize, canvasSize); ctx?.drawImage(img, 0, 0, canvasSize, canvasSize); return canvas; }; }