Spaces:
Running
Running
| class ImageGenerator { | |
| constructor() { | |
| this.baseURL = 'https://soiz-flux-1-dev-serverless.hf.space/generate'; | |
| this.prompt = ''; | |
| this.negativePrompt = ''; | |
| this.width = 512; | |
| this.height = 512; | |
| this.steps = 25; | |
| this.cfgs = 7; | |
| this.sampler = 'DPM++ 2M'; | |
| this.strength = 0.7; | |
| this.seed = -1; | |
| this.guidanceScale = 7.5; | |
| this.numReturnSequences = 1; | |
| this.temperature = 1.0; | |
| this.topK = 50; | |
| this.topP = 0.9; | |
| this.eta = 0.1; | |
| this.returnType = 'dataURL'; // dataURL or blobURL | |
| } | |
| // Generate URL for fetching | |
| generateFetchURL() { | |
| return `${this.baseURL}?prompt=${encodeURIComponent(this.prompt)}&negative_prompt=${encodeURIComponent(this.negativePrompt)}&width=${this.width}&height=${this.height}&steps=${this.steps}&cfgs=${this.cfgs}&sampler=${encodeURIComponent(this.sampler)}&strength=${this.strength}&seed=${this.seed}&guidance_scale=${this.guidanceScale}&num_return_sequences=${this.numReturnSequences}&temperature=${this.temperature}&top_k=${this.topK}&top_p=${this.topP}&eta=${this.eta}`; | |
| } | |
| // Return parameters as JSON for debugging | |
| getParametersAsJSON() { | |
| return JSON.stringify({ | |
| prompt: this.prompt, | |
| negativePrompt: this.negativePrompt, | |
| width: this.width, | |
| height: this.height, | |
| steps: this.steps, | |
| cfgs: this.cfgs, | |
| sampler: this.sampler, | |
| strength: this.strength, | |
| seed: this.seed, | |
| guidanceScale: this.guidanceScale, | |
| numReturnSequences: this.numReturnSequences, | |
| temperature: this.temperature, | |
| topK: this.topK, | |
| topP: this.topP, | |
| eta: this.eta | |
| }); | |
| } | |
| // Fetch function to generate the image | |
| async fetchImage() { | |
| const url = this.generateFetchURL(); | |
| try { | |
| const response = await fetch(url); | |
| if (!response.ok) throw new Error('Failed to generate image'); | |
| const blob = await response.blob(); | |
| if (this.returnType === 'blobURL') { | |
| return URL.createObjectURL(blob); | |
| } else { | |
| // Convert Blob to Data URL | |
| return await new Promise((resolve, reject) => { | |
| const reader = new FileReader(); | |
| reader.onloadend = () => resolve(reader.result); | |
| reader.onerror = reject; | |
| reader.readAsDataURL(blob); | |
| }); | |
| } | |
| } catch (error) { | |
| console.error(error); | |
| throw new Error('Error generating image: ' + error.message); | |
| } | |
| } | |
| getInfo() { | |
| return { | |
| id: 'imageGenerator', | |
| name: 'Image Generator', | |
| blocks: [ | |
| { opcode: 'setPrompt', blockType: Scratch.BlockType.COMMAND, text: 'set prompt to [TEXT]', arguments: { TEXT: { type: Scratch.ArgumentType.STRING, defaultValue: '1girl, halo, white wings, white sundress, angel, blue sky, blonde hair, blue eyes, long hair, dynamic angle' } } }, | |
| { opcode: 'setNegativePrompt', blockType: Scratch.BlockType.COMMAND, text: 'set negative prompt to [TEXT]', arguments: { TEXT: { type: Scratch.ArgumentType.STRING, defaultValue: 'anatomically bad, low quality, old, 1900s, 1800s, bad anatomically, many fingers, deformed feet, deformed fingers, deformed face , deformed eyes, blurry eyes, blurry, old quality' } } }, | |
| { opcode: 'setWidth', blockType: Scratch.BlockType.COMMAND, text: 'set width to [NUM]', arguments: { NUM: { type: Scratch.ArgumentType.NUMBER, defaultValue: 512 } } }, | |
| { opcode: 'setHeight', blockType: Scratch.BlockType.COMMAND, text: 'set height to [NUM]', arguments: { NUM: { type: Scratch.ArgumentType.NUMBER, defaultValue: 512 } } }, | |
| { opcode: 'setSteps', blockType: Scratch.BlockType.COMMAND, text: 'set steps to [NUM]', arguments: { NUM: { type: Scratch.ArgumentType.NUMBER, defaultValue: 25 } } }, | |
| { opcode: 'setCfgScale', blockType: Scratch.BlockType.COMMAND, text: 'set CFG Scale to [NUM]', arguments: { NUM: { type: Scratch.ArgumentType.NUMBER, defaultValue: 7 } } }, | |
| { opcode: 'setSampler', blockType: Scratch.BlockType.COMMAND, text: 'set sampler to [TEXT]', arguments: { TEXT: { type: Scratch.ArgumentType.STRING, defaultValue: 'DPM++ 2M' } } }, | |
| { opcode: 'setStrength', blockType: Scratch.BlockType.COMMAND, text: 'set strength to [NUM]', arguments: { NUM: { type: Scratch.ArgumentType.NUMBER, defaultValue: 0.7 } } }, | |
| { opcode: 'setSeed', blockType: Scratch.BlockType.COMMAND, text: 'set seed to [NUM]', arguments: { NUM: { type: Scratch.ArgumentType.NUMBER, defaultValue: -1 } } }, | |
| { opcode: 'setGuidanceScale', blockType: Scratch.BlockType.COMMAND, text: 'set guidance scale to [NUM]', arguments: { NUM: { type: Scratch.ArgumentType.NUMBER, defaultValue: 7.5 } } }, | |
| { opcode: 'setNumReturnSequences', blockType: Scratch.BlockType.COMMAND, text: 'set number of return sequences to [NUM]', arguments: { NUM: { type: Scratch.ArgumentType.NUMBER, defaultValue: 1 } } }, | |
| { opcode: 'setTemperature', blockType: Scratch.BlockType.COMMAND, text: 'set temperature to [NUM]', arguments: { NUM: { type: Scratch.ArgumentType.NUMBER, defaultValue: 1.0 } } }, | |
| { opcode: 'setTopK', blockType: Scratch.BlockType.COMMAND, text: 'set top K to [NUM]', arguments: { NUM: { type: Scratch.ArgumentType.NUMBER, defaultValue: 50 } } }, | |
| { opcode: 'setTopP', blockType: Scratch.BlockType.COMMAND, text: 'set top P to [NUM]', arguments: { NUM: { type: Scratch.ArgumentType.NUMBER, defaultValue: 0.9 } } }, | |
| { opcode: 'setEta', blockType: Scratch.BlockType.COMMAND, text: 'set eta to [NUM]', arguments: { NUM: { type: Scratch.ArgumentType.NUMBER, defaultValue: 0.1 } } }, | |
| { opcode: 'setReturnType', blockType: Scratch.BlockType.COMMAND, text: 'set return type to [TYPE]', arguments: { TYPE: { type: Scratch.ArgumentType.STRING, menu: 'returnTypes', defaultValue: 'dataURL' } } }, | |
| { opcode: 'generateImage', blockType: Scratch.BlockType.REPORTER, text: 'generate image' }, | |
| { opcode: 'getFetchURL', blockType: Scratch.BlockType.REPORTER, text: 'get fetch URL' }, | |
| { opcode: 'getParametersJSON', blockType: Scratch.BlockType.REPORTER, text: 'get parameters as JSON' } | |
| ], | |
| menus: { | |
| returnTypes: { acceptReporters: true, items: ['dataURL', 'blobURL'] } | |
| } | |
| }; | |
| } | |
| // Block functions | |
| setPrompt(args) { this.prompt = args.TEXT; } | |
| setNegativePrompt(args) { this.negativePrompt = args.TEXT; } | |
| setWidth(args) { this.width = args.NUM; } | |
| setHeight(args) { this.height = args.NUM; } | |
| setSteps(args) { this.steps = args.NUM; } | |
| setCfgScale(args) { this.cfgs = args.NUM; } | |
| setSampler(args) { this.sampler = args.TEXT; } | |
| setStrength(args) { this.strength = args.NUM; } | |
| setSeed(args) { this.seed = args.NUM; } | |
| setGuidanceScale(args) { this.guidanceScale = args.NUM; } | |
| setNumReturnSequences(args) { this.numReturnSequences = args.NUM; } | |
| setTemperature(args) { this.temperature = args.NUM; } | |
| setTopK(args) { this.topK = args.NUM; } | |
| setTopP(args) { this.topP = args.NUM; } | |
| setEta(args) { this.eta = args.NUM; } | |
| setReturnType(args) { this.returnType = args.TYPE; } | |
| async generateImage() { return this.fetchImage(); } | |
| getFetchURL() { return this.generateFetchURL(); } | |
| getParametersJSON() { return this.getParametersAsJSON(); } | |
| } | |
| // Register the extension | |
| Scratch.extensions.register(new ImageGenerator()); | |