UNPKG

woolball-client

Version:

Client-side library for Woolball enabling secure browser resource sharing for distributed AI task processing

80 lines (79 loc) 3.22 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.imageConversion = void 0; async function imageConversion(data) { const { input, outputFormat = 'image/webp', quality = 0.8, maxWidth, maxHeight, ...options } = data; try { if (!('ImageDecoder' in globalThis)) { throw new Error('WebCodecs API (ImageDecoder) is not available in this browser.'); } let inputData = typeof input === 'string' ? JSON.parse(input) : input; let imageData; if (inputData.base64) { const base64String = inputData.base64.split(',')[1] || inputData.base64; const binaryString = atob(base64String); const bytes = new Uint8Array(binaryString.length); for (let i = 0; i < binaryString.length; i++) { bytes[i] = binaryString.charCodeAt(i); } imageData = bytes.buffer; } else if (inputData.buffer) { imageData = inputData.buffer; } else { throw new Error('Invalid input format. Provide an image as base64 or ArrayBuffer.'); } const inputType = inputData.type || 'image/jpeg'; const validFormats = ['image/webp', 'image/jpeg', 'image/png', 'image/avif']; if (!validFormats.includes(outputFormat)) { throw new Error(`Invalid output format. Supported formats: ${validFormats.join(', ')}`); } const decoder = new ImageDecoder({ data: imageData, type: inputType }); await decoder.completed; const { image: frame } = await decoder.decode(); let outputWidth = frame.displayWidth; let outputHeight = frame.displayHeight; if (maxWidth && outputWidth > maxWidth) { const ratio = maxWidth / outputWidth; outputWidth = maxWidth; outputHeight = Math.round(outputHeight * ratio); } if (maxHeight && outputHeight > maxHeight) { const ratio = maxHeight / outputHeight; outputHeight = maxHeight; outputWidth = Math.round(outputWidth * ratio); } const canvas = new OffscreenCanvas(outputWidth, outputHeight); const ctx = canvas.getContext('2d'); if (!ctx) { throw new Error('Could not create canvas context.'); } ctx.drawImage(frame, 0, 0, outputWidth, outputHeight); frame.close(); const blob = await canvas.convertToBlob({ type: outputFormat, quality }); const reader = new FileReader(); const base64Promise = new Promise((resolve, reject) => { reader.onload = () => resolve(reader.result); reader.onerror = reject; }); reader.readAsDataURL(blob); const base64 = await base64Promise; return { image: base64, format: outputFormat, width: outputWidth, height: outputHeight, originalFormat: inputType, originalWidth: frame.displayWidth, originalHeight: frame.displayHeight }; } catch (error) { throw error; } } exports.imageConversion = imageConversion;