├── .gitignore ├── README.md ├── duck.jpg ├── index.js ├── mask.png ├── package-lock.json └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | output.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ideogram inpainting 2 | 3 | This simple demo shows you how to use the [Ideogram V2 inpainting model](https://replicate.com/blog/ideogram-v2-inpainting) on Replicate using Node.js. 4 | 5 | ![inpainting](https://github.com/user-attachments/assets/2618ebc3-66fc-4d9b-9399-fcd57d07835a) 6 | 7 | ## What is inpainting? 8 | 9 | Inpainting is like an AI-powered erasing and painting tool. You can use it to remove unwanted objects from an image, or change parts of an image to create something new. 10 | 11 | To inpaint an image, you need: 12 | 13 | 1. A starting image that you want to change. (See [duck.jpg](duck.jpg)) 14 | 2. A mask image that describes which parts of the image you want to inpaint. **Black** areas are inpainted and **white** areas are left unchanged. (See [mask.png](mask.png)) 15 | 3. A text prompt that describes the changes you want to see. 16 | 17 | 18 | ## Usage 19 | 20 | To run this demo, you'll need to have [Node.js](https://nodejs.org) installed. 21 | 22 | Create a [Replicate API token](https://replicate.com/account/api-tokens) and add it to your environment variables: 23 | 24 | ```sh 25 | export REPLICATE_API_TOKEN=r8_... 26 | ``` 27 | 28 | Then, install the dependencies and run the script: 29 | 30 | ```sh 31 | npm install 32 | node index.js 33 | ``` 34 | 35 | This will: 36 | 37 | - Run the model with Replicate's cloud API 38 | - Save the output image to `output.png` 39 | - Open the output image in your default image viewer 40 | 41 | ## See also 42 | 43 | - [replicate.com/ideogram-ai/ideogram-v2-turbo](https://replicate.com/ideogram-ai/ideogram-v2-turbo) - Turbo version of the model 44 | - [replicate.com/ideogram-ai/ideogram-v2](https://replicate.com/ideogram-ai/ideogram-v2) - Full version of the model 45 | - [Ideogram v2 inpainting on Replicate](https://replicate.com/blog/ideogram-v2-inpainting) - blog post announcing Ideogram v2 inpainting on Replicate 46 | - [Replicate Playground](https://replicate.com/playground) - Web-based tool for inpainting images right on replicate.com 47 | - [Inpainter.app](https://github.com/replicate/inpainter) - Open-source Next.js app for inpainting images 48 | - [Outpainter.app](https://github.com/replicate/outpainter) - Open-source Nuxt.js app for extending images beyond their original canvas 49 | - [Inpainting with Stable Diffusion](https://replicate.com/docs/guides/stable-diffusion/inpainting) - an older guide, but still useful. -------------------------------------------------------------------------------- /duck.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/replicate/ideogram-inpainting-example-js/cc722d0b1abb69bafa1621e02d08c6913bfad930/duck.jpg -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import Replicate from 'replicate' 2 | import fs from 'node:fs/promises' 3 | import open from 'open' 4 | 5 | const replicate = new Replicate() 6 | 7 | // Define the model to use 8 | // https://replicate.com/ideogram-ai/ideogram-v2 9 | const model = 'ideogram-ai/ideogram-v2' 10 | 11 | // Inputs to the model 12 | const prompt = 'a duck wearing a hat' 13 | const image = await fs.readFile('duck.jpg') 14 | const mask = await fs.readFile('mask.png') 15 | const input = { prompt, image, mask } 16 | 17 | console.log('Running model...') 18 | console.log({ model, input }) 19 | 20 | // Run the model with Replicate's cloud API 21 | const output = await replicate.run(model, { input }) 22 | 23 | // For images under 5MB, `replicate.run` returns the output file 24 | // as a base64 encoded string. This code saves that to a file: 25 | const href = output.url().href 26 | const base64Data = href.split(',')[1] 27 | const outputPath = 'output.png' 28 | await fs.writeFile(outputPath, base64Data, 'base64') 29 | 30 | console.log(`File saved as ${outputPath}`) 31 | 32 | await open(outputPath) 33 | -------------------------------------------------------------------------------- /mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/replicate/ideogram-inpainting-example-js/cc722d0b1abb69bafa1621e02d08c6913bfad930/mask.png -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ideogram-inpainting-example-js", 3 | "lockfileVersion": 3, 4 | "requires": true, 5 | "packages": { 6 | "": { 7 | "dependencies": { 8 | "open": "^10.1.0", 9 | "replicate": "^1.0.1" 10 | } 11 | }, 12 | "node_modules/abort-controller": { 13 | "version": "3.0.0", 14 | "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", 15 | "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", 16 | "license": "MIT", 17 | "optional": true, 18 | "dependencies": { 19 | "event-target-shim": "^5.0.0" 20 | }, 21 | "engines": { 22 | "node": ">=6.5" 23 | } 24 | }, 25 | "node_modules/base64-js": { 26 | "version": "1.5.1", 27 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", 28 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", 29 | "funding": [ 30 | { 31 | "type": "github", 32 | "url": "https://github.com/sponsors/feross" 33 | }, 34 | { 35 | "type": "patreon", 36 | "url": "https://www.patreon.com/feross" 37 | }, 38 | { 39 | "type": "consulting", 40 | "url": "https://feross.org/support" 41 | } 42 | ], 43 | "license": "MIT", 44 | "optional": true 45 | }, 46 | "node_modules/buffer": { 47 | "version": "6.0.3", 48 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", 49 | "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", 50 | "funding": [ 51 | { 52 | "type": "github", 53 | "url": "https://github.com/sponsors/feross" 54 | }, 55 | { 56 | "type": "patreon", 57 | "url": "https://www.patreon.com/feross" 58 | }, 59 | { 60 | "type": "consulting", 61 | "url": "https://feross.org/support" 62 | } 63 | ], 64 | "license": "MIT", 65 | "optional": true, 66 | "dependencies": { 67 | "base64-js": "^1.3.1", 68 | "ieee754": "^1.2.1" 69 | } 70 | }, 71 | "node_modules/bundle-name": { 72 | "version": "4.1.0", 73 | "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", 74 | "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", 75 | "license": "MIT", 76 | "dependencies": { 77 | "run-applescript": "^7.0.0" 78 | }, 79 | "engines": { 80 | "node": ">=18" 81 | }, 82 | "funding": { 83 | "url": "https://github.com/sponsors/sindresorhus" 84 | } 85 | }, 86 | "node_modules/default-browser": { 87 | "version": "5.2.1", 88 | "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", 89 | "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", 90 | "license": "MIT", 91 | "dependencies": { 92 | "bundle-name": "^4.1.0", 93 | "default-browser-id": "^5.0.0" 94 | }, 95 | "engines": { 96 | "node": ">=18" 97 | }, 98 | "funding": { 99 | "url": "https://github.com/sponsors/sindresorhus" 100 | } 101 | }, 102 | "node_modules/default-browser-id": { 103 | "version": "5.0.0", 104 | "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", 105 | "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", 106 | "license": "MIT", 107 | "engines": { 108 | "node": ">=18" 109 | }, 110 | "funding": { 111 | "url": "https://github.com/sponsors/sindresorhus" 112 | } 113 | }, 114 | "node_modules/define-lazy-prop": { 115 | "version": "3.0.0", 116 | "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", 117 | "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", 118 | "license": "MIT", 119 | "engines": { 120 | "node": ">=12" 121 | }, 122 | "funding": { 123 | "url": "https://github.com/sponsors/sindresorhus" 124 | } 125 | }, 126 | "node_modules/event-target-shim": { 127 | "version": "5.0.1", 128 | "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", 129 | "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", 130 | "license": "MIT", 131 | "optional": true, 132 | "engines": { 133 | "node": ">=6" 134 | } 135 | }, 136 | "node_modules/events": { 137 | "version": "3.3.0", 138 | "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", 139 | "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", 140 | "license": "MIT", 141 | "optional": true, 142 | "engines": { 143 | "node": ">=0.8.x" 144 | } 145 | }, 146 | "node_modules/ieee754": { 147 | "version": "1.2.1", 148 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", 149 | "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", 150 | "funding": [ 151 | { 152 | "type": "github", 153 | "url": "https://github.com/sponsors/feross" 154 | }, 155 | { 156 | "type": "patreon", 157 | "url": "https://www.patreon.com/feross" 158 | }, 159 | { 160 | "type": "consulting", 161 | "url": "https://feross.org/support" 162 | } 163 | ], 164 | "license": "BSD-3-Clause", 165 | "optional": true 166 | }, 167 | "node_modules/is-docker": { 168 | "version": "3.0.0", 169 | "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", 170 | "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", 171 | "license": "MIT", 172 | "bin": { 173 | "is-docker": "cli.js" 174 | }, 175 | "engines": { 176 | "node": "^12.20.0 || ^14.13.1 || >=16.0.0" 177 | }, 178 | "funding": { 179 | "url": "https://github.com/sponsors/sindresorhus" 180 | } 181 | }, 182 | "node_modules/is-inside-container": { 183 | "version": "1.0.0", 184 | "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", 185 | "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", 186 | "license": "MIT", 187 | "dependencies": { 188 | "is-docker": "^3.0.0" 189 | }, 190 | "bin": { 191 | "is-inside-container": "cli.js" 192 | }, 193 | "engines": { 194 | "node": ">=14.16" 195 | }, 196 | "funding": { 197 | "url": "https://github.com/sponsors/sindresorhus" 198 | } 199 | }, 200 | "node_modules/is-wsl": { 201 | "version": "3.1.0", 202 | "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", 203 | "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", 204 | "license": "MIT", 205 | "dependencies": { 206 | "is-inside-container": "^1.0.0" 207 | }, 208 | "engines": { 209 | "node": ">=16" 210 | }, 211 | "funding": { 212 | "url": "https://github.com/sponsors/sindresorhus" 213 | } 214 | }, 215 | "node_modules/open": { 216 | "version": "10.1.0", 217 | "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz", 218 | "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==", 219 | "license": "MIT", 220 | "dependencies": { 221 | "default-browser": "^5.2.1", 222 | "define-lazy-prop": "^3.0.0", 223 | "is-inside-container": "^1.0.0", 224 | "is-wsl": "^3.1.0" 225 | }, 226 | "engines": { 227 | "node": ">=18" 228 | }, 229 | "funding": { 230 | "url": "https://github.com/sponsors/sindresorhus" 231 | } 232 | }, 233 | "node_modules/process": { 234 | "version": "0.11.10", 235 | "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", 236 | "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", 237 | "license": "MIT", 238 | "optional": true, 239 | "engines": { 240 | "node": ">= 0.6.0" 241 | } 242 | }, 243 | "node_modules/readable-stream": { 244 | "version": "4.5.2", 245 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", 246 | "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", 247 | "license": "MIT", 248 | "optional": true, 249 | "dependencies": { 250 | "abort-controller": "^3.0.0", 251 | "buffer": "^6.0.3", 252 | "events": "^3.3.0", 253 | "process": "^0.11.10", 254 | "string_decoder": "^1.3.0" 255 | }, 256 | "engines": { 257 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 258 | } 259 | }, 260 | "node_modules/replicate": { 261 | "version": "1.0.1", 262 | "resolved": "https://registry.npmjs.org/replicate/-/replicate-1.0.1.tgz", 263 | "integrity": "sha512-EY+rK1YR5bKHcM9pd6WyaIbv6m2aRIvHfHDh51j/LahlHTLKemTYXF6ptif2sLa+YospupAsIoxw8Ndt5nI3vg==", 264 | "license": "Apache-2.0", 265 | "engines": { 266 | "git": ">=2.11.0", 267 | "node": ">=18.0.0", 268 | "npm": ">=7.19.0", 269 | "yarn": ">=1.7.0" 270 | }, 271 | "optionalDependencies": { 272 | "readable-stream": ">=4.0.0" 273 | } 274 | }, 275 | "node_modules/run-applescript": { 276 | "version": "7.0.0", 277 | "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", 278 | "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", 279 | "license": "MIT", 280 | "engines": { 281 | "node": ">=18" 282 | }, 283 | "funding": { 284 | "url": "https://github.com/sponsors/sindresorhus" 285 | } 286 | }, 287 | "node_modules/safe-buffer": { 288 | "version": "5.2.1", 289 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 290 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 291 | "funding": [ 292 | { 293 | "type": "github", 294 | "url": "https://github.com/sponsors/feross" 295 | }, 296 | { 297 | "type": "patreon", 298 | "url": "https://www.patreon.com/feross" 299 | }, 300 | { 301 | "type": "consulting", 302 | "url": "https://feross.org/support" 303 | } 304 | ], 305 | "license": "MIT", 306 | "optional": true 307 | }, 308 | "node_modules/string_decoder": { 309 | "version": "1.3.0", 310 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", 311 | "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", 312 | "license": "MIT", 313 | "optional": true, 314 | "dependencies": { 315 | "safe-buffer": "~5.2.0" 316 | } 317 | } 318 | } 319 | } 320 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module", 3 | "dependencies": { 4 | "open": "^10.1.0", 5 | "replicate": "^1.0.1" 6 | } 7 | } 8 | --------------------------------------------------------------------------------