UNPKG

n8n-nodes-piapi

Version:

Community n8n nodes for PiAPI - integrate generative AI capabilities (image, video, audio, 3D) into your workflows

243 lines 10.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.QubicoSegment = void 0; const GenericFunctions_1 = require("../shared/GenericFunctions"); class QubicoSegment { constructor() { this.description = { displayName: 'PiAPI Qubico Image Segmentation', name: 'qubicoSegment', icon: 'file:../piapi.svg', group: ['transform'], version: 1, description: 'Segment images using semantic prompts via PiAPI Qubico', defaults: { name: 'Qubico Segment', }, inputs: ["main"], outputs: ["main"], credentials: [ { name: 'piAPIApi', required: true, }, ], properties: [ { displayName: 'Image Input Method', name: 'imageInputMethod', type: 'options', options: [ { name: 'URL', value: 'url', }, { name: 'Binary Field', value: 'binaryField', }, ], default: 'url', description: 'How to input the image to segment', }, { displayName: 'Image URL', name: 'imageUrl', type: 'string', default: '', required: true, displayOptions: { show: { imageInputMethod: ['url'], }, }, description: 'URL of the image to segment', }, { displayName: 'Binary Field', name: 'binaryField', type: 'string', default: 'data', required: true, displayOptions: { show: { imageInputMethod: ['binaryField'], }, }, description: 'The binary field containing the image to segment', }, { displayName: 'Prompt', name: 'prompt', type: 'string', typeOptions: { rows: 4, }, default: '', placeholder: 'clothes,shoes', required: true, description: 'The semantic prompt of the things that you want to segment, separate by comma', }, { displayName: 'Negative Prompt', name: 'negativePrompt', type: 'string', typeOptions: { rows: 4, }, default: '', placeholder: 'pants', description: 'The semantic prompt of the things that you do not want to segment, separate by comma', }, { displayName: 'Segment Factor', name: 'segmentFactor', type: 'number', default: 0, description: 'Pixels that expand or shrink on the edge, positive integer for expansion, negative for shrinking', }, { displayName: 'Wait For Completion', name: 'waitForCompletion', type: 'boolean', default: false, description: 'Whether to wait for the segmentation to complete', }, { displayName: 'Return Binary Data', name: 'returnBinaryData', type: 'boolean', default: false, description: 'Whether to return the segmented image as binary data', displayOptions: { show: { waitForCompletion: [true], }, }, }, { displayName: 'Binary Property', name: 'binaryPropertyName', type: 'string', default: 'data', required: true, displayOptions: { show: { returnBinaryData: [true], waitForCompletion: [true], }, }, description: 'Name of the binary property to which to write the data of the segmented image', }, ], }; } async execute() { const items = this.getInputData(); const returnData = []; for (let i = 0; i < items.length; i++) { try { const imageInputMethod = this.getNodeParameter('imageInputMethod', i); const prompt = this.getNodeParameter('prompt', i); const negativePrompt = this.getNodeParameter('negativePrompt', i, ''); const segmentFactor = this.getNodeParameter('segmentFactor', i, 0); const waitForCompletion = this.getNodeParameter('waitForCompletion', i, false); let imageUrl; if (imageInputMethod === 'url') { imageUrl = this.getNodeParameter('imageUrl', i); } else { const binaryField = this.getNodeParameter('binaryField', i); if (items[i].binary === undefined) { throw new Error('No binary data exists on item!'); } const binaryData = items[i].binary[binaryField]; if (binaryData === undefined) { throw new Error(`No binary data found for field "${binaryField}"!`); } if (binaryData.url) { imageUrl = String(binaryData.url); } else { const mimeType = binaryData.mimeType; const base64 = Buffer.from(binaryData.data, 'base64').toString('base64'); imageUrl = `data:${mimeType};base64,${base64}`; } } const params = { model: 'Qubico/image-toolkit', task_type: 'segment', input: { image: imageUrl, prompt, negative_prompt: negativePrompt, segment_factor: segmentFactor, }, }; const response = await GenericFunctions_1.piApiRequest.call(this, 'POST', '/api/v1/task', params); const taskId = response.data.task_id; if (waitForCompletion) { const completedTask = await GenericFunctions_1.waitForTaskCompletion.call(this, taskId); const returnBinaryData = this.getNodeParameter('returnBinaryData', i, false); if (returnBinaryData) { const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i); const segmentedImageUrl = completedTask.output && typeof completedTask.output === 'object' ? completedTask.output.image_url : undefined; if (segmentedImageUrl) { const imageData = await this.helpers.request({ method: 'GET', url: segmentedImageUrl, encoding: null, resolveWithFullResponse: true, }); const newItem = { json: completedTask, binary: {}, }; if (newItem.binary) { newItem.binary[binaryPropertyName] = await this.helpers.prepareBinaryData(Buffer.from(imageData.body), segmentedImageUrl.split('/').pop() || 'segmented-image.png', imageData.headers['content-type']); } returnData.push(newItem); } else { returnData.push({ json: { ...completedTask, error: 'No segmented image URL found in the response', }, }); } } else { returnData.push({ json: completedTask, }); } } else { returnData.push({ json: { taskId, ...response.data, }, }); } } catch (error) { if (this.continueOnFail()) { returnData.push({ json: { error: error.message, }, }); continue; } throw error; } } return [returnData]; } } exports.QubicoSegment = QubicoSegment; //# sourceMappingURL=QubicoSegment.node.js.map