| 1642 | $('#sd_model').val(extension_settings.sd.model).trigger('change'); | 1642 | $('#sd_model').val(extension_settings.sd.model).trigger('change'); |
| 1643 | } | 1643 | } |
| 1644 | } | 1644 | } |
| | 1645 | |
| 1645 | async function generateStabilityImage(prompt, negativePrompt) { | 1646 | async function generateStabilityImage(prompt, negativePrompt) { |
| 1646 | let endpoint; | 1647 | const payload = { |
| | 1648 | prompt: prompt, |
| | 1649 | negative_prompt: negativePrompt, |
| | 1650 | width: extension_settings.sd.width, |
| | 1651 | height: extension_settings.sd.height, |
| | 1652 | seed: extension_settings.sd.seed >= 0 ? extension_settings.sd.seed : undefined, |
| | 1653 | style_preset: extension_settings.sd.stability_style_preset, |
| | 1654 | output_format: extension_settings.sd.stability_output_format, |
| | 1655 | }; |
| | 1656 | |
| | 1657 | const formData = new FormData(); |
| | 1658 | for (const [key, value] of Object.entries(payload)) { |
| | 1659 | if (value !== undefined) { |
| | 1660 | formData.append(key, String(value)); |
| | 1661 | } |
| | 1662 | } |
| | 1663 | |
| | 1664 | let apiUrl; |
| 1647 | switch (extension_settings.sd.model) { | 1665 | switch (extension_settings.sd.model) { |
| 1648 | case 'stable-image-ultra': | 1666 | case 'stable-image-ultra': |
| 1649 | endpoint = '/v2beta/stable-image/generate/ultra'; | 1667 | apiUrl = 'https://api.stability.ai/v2beta/stable-image/generate/ultra'; |
| 1650 | break; | 1668 | break; |
| 1651 | case 'stable-image-core': | 1669 | case 'stable-image-core': |
| 1652 | endpoint = '/v2beta/stable-image/generate/core'; | 1670 | apiUrl = 'https://api.stability.ai/v2beta/stable-image/generate/core'; |
| 1653 | break; | 1671 | break; |
| 1654 | case 'stable-diffusion-3': | 1672 | case 'stable-diffusion-3': |
| 1655 | endpoint = '/v2beta/stable-image/generate/sd3'; | 1673 | apiUrl = 'https://api.stability.ai/v2beta/stable-image/generate/sd3'; |
| 1656 | break; | 1674 | break; |
| 1657 | default: | 1675 | default: |
| 1658 | throw new Error('Invalid Stability AI model selected'); | 1676 | throw new Error('Invalid Stability AI model selected'); |
| 1659 | } | 1677 | } |
| 1660 | | 1678 | |
| 1661 | const result = await fetch('/api/sd/stability/generate', { | 1679 | try { |
| | 1680 | const response = await fetch(apiUrl, { |
| 1662 | method: 'POST', | 1681 | method: 'POST', |
| 1663 | headers: getRequestHeaders(), | 1682 | headers: { |
| 1664 | body: JSON.stringify({ | 1683 | 'Authorization': `Bearer ${extension_settings.sd.stability_key}`, |
| 1665 | key: extension_settings.sd.stability_key, | 1684 | 'Accept': 'image/*', |
| 1666 | endpoint: endpoint, | 1685 | }, |
| 1667 | prompt: prompt, | 1686 | body: formData, |
| 1668 | negative_prompt: negativePrompt, | | |
| 1669 | seed: extension_settings.sd.seed >= 0 ? extension_settings.sd.seed : undefined, | | |
| 1670 | style_preset: extension_settings.sd.stability_style_preset, | | |
| 1671 | aspect_ratio: extension_settings.sd.stability_aspect_ratio, | | |
| 1672 | }), | | |
| 1673 | }); | 1687 | }); |
| 1674 | | 1688 | |
| 1675 | if (result.ok) { | 1689 | if (!response.ok) { |
| 1676 | const data = await result.json(); | 1690 | const errorText = await response.text(); |
| 1677 | return { format: extension_settings.sd.stability_output_format, data: data.image }; | 1691 | throw new Error(`HTTP ${response.status}: ${errorText}`); |
| 1678 | } else { | 1692 | } |
| 1679 | const text = await result.text(); | 1693 | |
| 1680 | throw new Error(text); | 1694 | const arrayBuffer = await response.arrayBuffer(); |
| | 1695 | const base64Image = arrayBufferToBase64(arrayBuffer); |
| | 1696 | |
| | 1697 | return { |
| | 1698 | format: extension_settings.sd.stability_output_format, |
| | 1699 | data: base64Image, |
| | 1700 | }; |
| | 1701 | } catch (error) { |
| | 1702 | console.error('Error generating image with Stability AI:', error); |
| | 1703 | throw error; |
| | 1704 | } |
| | 1705 | } |
| | 1706 | |
| | 1707 | function arrayBufferToBase64(buffer) { |
| | 1708 | let binary = ''; |
| | 1709 | const bytes = new Uint8Array(buffer); |
| | 1710 | const len = bytes.byteLength; |
| | 1711 | for (let i = 0; i < len; i++) { |
| | 1712 | binary += String.fromCharCode(bytes[i]); |
| 1681 | } | 1713 | } |
| | 1714 | return btoa(binary); |
| 1682 | } | 1715 | } |
| 1683 | | 1716 | |
| 1684 | | 1717 | |