{"id":28325010,"url":"https://github.com/totallynotdavid/image-generation","last_synced_at":"2026-02-28T13:32:02.563Z","repository":{"id":287154706,"uuid":"963783530","full_name":"totallynotdavid/image-generation","owner":"totallynotdavid","description":"A simple, lightweight TypeScript image-processing library for Deno, available on both JSR and npm","archived":false,"fork":false,"pushed_at":"2025-08-25T18:06:08.000Z","size":28109,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-09-26T19:41:07.614Z","etag":null,"topics":["deno","image-processing","typescript-library"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/totallynotdavid.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"license","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["totallynotdavid"]}},"created_at":"2025-04-10T07:48:22.000Z","updated_at":"2025-08-27T06:31:19.000Z","dependencies_parsed_at":"2025-08-18T22:18:23.864Z","dependency_job_id":"97f246e6-25bf-4a96-ab2f-a1615bcc111b","html_url":"https://github.com/totallynotdavid/image-generation","commit_stats":null,"previous_names":["totallynotdavid/image-generation"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/totallynotdavid/image-generation","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/totallynotdavid%2Fimage-generation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/totallynotdavid%2Fimage-generation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/totallynotdavid%2Fimage-generation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/totallynotdavid%2Fimage-generation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/totallynotdavid","download_url":"https://codeload.github.com/totallynotdavid/image-generation/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/totallynotdavid%2Fimage-generation/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29935363,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-28T13:16:57.922Z","status":"ssl_error","status_checked_at":"2026-02-28T13:11:15.149Z","response_time":90,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["deno","image-processing","typescript-library"],"created_at":"2025-05-25T19:14:10.889Z","updated_at":"2026-02-28T13:32:02.520Z","avatar_url":"https://github.com/totallynotdavid.png","language":"TypeScript","funding_links":["https://github.com/sponsors/totallynotdavid"],"categories":[],"sub_categories":[],"readme":"# [pkg]: image-generation [![JSR](https://jsr.io/badges/@dv/image-generation)](https://jsr.io/@dv/image-generation) [![npm version](https://badge.fury.io/js/@totallynotdavid%2Fimage-generation.svg)](https://badge.fury.io/js/@totallynotdavid%2Fimage-generation)\n\n[![CodeQL](https://github.com/totallynotdavid/image-generation/actions/workflows/codeql.yml/badge.svg)](https://github.com/totallynotdavid/image-generation/actions/workflows/codeql.yml)\n[![codecov](https://codecov.io/gh/totallynotdavid/image-generation/graph/badge.svg?token=Z9K6TC9HFO)](https://codecov.io/gh/totallynotdavid/image-generation)\n[![Deno CI](https://github.com/totallynotdavid/image-generation/actions/workflows/deno.yml/badge.svg)](https://github.com/totallynotdavid/image-generation/actions/workflows/deno.yml)\n\nA TypeScript/Deno image processing library providing powerful, production-ready\ntransformations with an extensible plugin architecture. Process images with\nbuilt-in effects or develop custom plugins to meet your specific needs.\n\nThis library offers a modern, type-safe approach to image manipulation, perfect\nfor:\n\n- Creating visual effects for social media bots\n- Adding image transformations to messaging applications (e.g., stickers)\n- Building custom image processing pipelines\n- Generating dynamic visual content\n\nOriginally built for a WhatsApp bot\n([check it out](https://github.com/totallynotdavid/WhatsAppBot)) and inspired by\n[discord-image-generation](https://www.npmjs.com/package/discord-image-generation),\nthis library has been completely rebuilt with TypeScript for better type safety\nand platform independence.\n\n## Features\n\n- 🖼️ Ready-to-use image effects including color manipulation, cropping, and\n  animation\n- 🧩 Easily create and integrate custom transformations\n- ⚙️ Robust parameter checking to prevent runtime errors\n- 🔍 Complete TypeScript definitions for better developer experience\n\n## Transformation gallery\n\n| Transformation  | Description                                    | Example Usage                                                                | Result                                           |\n| --------------- | ---------------------------------------------- | ---------------------------------------------------------------------------- | ------------------------------------------------ |\n| **Greyscale**   | Convert images to black and white              | `await greyscale({ input: \"image.png\" })`                                    | ![greyscale](example/output/greyscale.png)       |\n| **Color Tint**  | Apply color overlay with blend modes           | `await color({ input: \"image.png\", options: { hex: \"#ff5500\" } })`           | ![color-tint](example/output/red-overlay.png)    |\n| **Circle Crop** | Crop images into circles with optional borders | `await circle({ input: \"image.png\", options: { borderWidth: 5 } })`          | ![circle-crop](example/output/circle-border.png) |\n| **Animation**   | Create GIF animations from image sequences     | `await blink({ inputs: [\"img1.png\", \"img2.png\"], options: { delay: 200 } })` | ![animation](example/output/blink-animation.gif) |\n\nThe cat in the image examples is\n[@rexiecat](https://www.instagram.com/rexiecat/). Give them some love.\n\n## Getting started\n\n### Installation \u0026 basic usage\n\nFor projects using Deno, simply add the package:\n\n```bash\ndeno add @dv/image-generation\n```\n\nNode.js support via npm is coming soon.\n\nImport the transformations you need and apply them to your images:\n\n```typescript\nimport { greyscale } from '@dv/image-generation';\n\nconst greyImage = await greyscale({\n    input: './photos/profile.png',\n});\n\nawait Deno.writeFile('./output/greyscale-profile.png', greyImage);\n```\n\nWhen running with Deno, you'll need these permissions:\n\n```bash\ndeno run --allow-read --allow-write your-script.ts\n```\n\nIf you’d rather not write a script just to test things, you can run:\n\n```bash\ndeno task dev:example\n```\n\n## Examples\n\nThe library provides several ways to transform images, from simple single-image\noperations to complex multi-step pipelines.\n\n### Single image transformations\n\nMost transformations operate on a single input image, producing a modified\noutput that can be saved or passed along in your pipeline.\n\nFor example, to apply a color tint with blend mode to an image:\n\n```typescript\nimport { color } from '@dv/image-generation';\n\nconst tintedImage = await color({\n    input: './input.jpg',\n    options: {\n        hex: '#FF99CC',\n        blendMode: 'softlight',\n    },\n});\n```\n\nFor the `hex` parameter, you can use either 6-digit or 3-digit hex codes. The\n`blendMode` parameter accepts either `softlight` or `overlay`. See the\ndocumentation for complete parameter options.\n\nTo create a circular avatar with a border:\n\n```typescript\nimport { circle } from '@dv/image-generation';\n\nconst avatarImage = await circle({\n    input: './photos/profile.png',\n    options: {\n        borderWidth: 5,\n        borderColor: '#000000',\n    },\n});\n```\n\n### Multi-image processing\n\nSome transformations like animations require multiple input images. For these,\nuse the `inputs` parameter instead of `input`:\n\n```typescript\nimport { blink } from '@dv/image-generation';\n\nconst animatedImage = await blink({\n    inputs: ['frame1.png', 'frame2.png', 'frame3.png'],\n    options: {\n        delay: 200, // milliseconds between frames\n        loop: true, // loop continuously\n    },\n});\n```\n\n### Building transformation pipelines\n\nThe real power of this library comes from combining transformations. You can\nchain them to create complex effects by passing the output of one transformation\nas the input to another. For example, you could do:\n\n```typescript\nimport { blink, circle, greyscale } from '@dv/image-generation';\n\nconst inputFrames = ['frame1.png', 'frame2.png'];\n\n// Create a processing pipeline for each frame\nconst processedFrames = await Promise.all(\n    inputFrames.map(async (img) =\u003e {\n        const grey = await greyscale({ input: img });\n\n        return circle({\n            input: grey,\n            options: { borderWidth: 3, borderColor: '#ffffff' },\n        });\n    }),\n);\n\n// Combine processed frames into an animation\nconst animation = await blink({\n    inputs: processedFrames,\n    options: { delay: 300 },\n});\n\nawait Deno.writeFile('./output/animated-avatars.gif', animation);\n```\n\nThis example shows how to create a more complex workflow:\n\n1. Load multiple image frames\n2. Convert each to greyscale (we use the `greyscale` function for this)\n3. Crop each into a circle with border (for this, we use the `circle` function)\n4. Combine them into an animated GIF (using `blink`)\n\nEach transformation returns a buffer that can be passed directly as input to the\nnext transformation, making it easy to create sophisticated image processing\nchains without saving intermediate files.\n\n## For developers\n\nThe library is designed to be both user-friendly and developer-friendly. If\nyou're interested in contributing or extending the library with your own\ntransformations, this section will help you get started.\n\n### Setting up your environment\n\nTo set up your development environment:\n\n1. Clone the repository:\n\n   ```bash\n   git clone https://github.com/totallynotdavid/image-generation\n   cd image-generation\n   ```\n\n2. Install Deno if you don't have it:\n\n   ```bash\n   # Unix-based systems\n   curl -fsSL https://deno.land/install.sh | sh\n\n   # Windows\n   irm https://deno.land/install.ps1 | iex\n   ```\n\n3. Install dependencies:\n\n   ```bash\n   deno install --allow-scripts\n   ```\n\n4. Run the example to verify your setup:\n\n   ```bash\n   deno task dev:example\n   ```\n\n   You can see the results in `example/output`.\n\nThe repo includes several useful development commands:\n\n- `deno task dev` - Run development mode with hot reload\n- `deno task dev:example` - Execute the example code\n- `deno task tidy` - Format code and run linter\n- `deno task test` - Run the test suite\n\n### Structure of the codebase\n\nThe codebase is organized to make it easy to understand and extend:\n\n```\nsrc/\n├── core/                       # Core processing components\n│   ├── asset-resolver.ts       # Asset path resolution\n│   └── processor.ts            # Core processing logic\n├── errors.ts                   # Custom error definitions\n├── index.ts                    # Main exports\n├── plugins/                    # Plugin system\n│   ├── index.ts\n│   └── register-built-ins.ts\n├── transforms/                 # Built-in transformations\n│   ├── blink.ts\n│   ├── circle.ts\n│   ├── color.ts\n│   └── greyscale.ts\n├── types/                      # Type definitions\n│   └── transforms.ts\n└── validation/                 # Parameter validation\n    ├── schemas.ts\n    └── utils.ts\n```\n\nIf you're looking to understand how transformations work, start by exploring the\n`transforms` directory, which contains all the built-in effects.\n\n### Contributing\n\nContributions are welcome! If you'd like to add a new transformation or improve\nan existing one, here's how:\n\n1. Create a new file in `src/transforms/` for your transformation\n2. Define the transform parameters in `src/types/transforms.ts`\n3. Add parameter validation in `src/validation/schemas.ts`\n4. Register your plugin in `src/plugins/register-built-ins.ts`\n5. Add tests and documentation\n\nBefore submitting a pull request:\n\n- Run `deno task tidy` to ensure code formatting and linting pass\n- Make sure all tests pass with `deno task test`\n- Update documentation to reflect your changes\n\n## License\n\n[MIT License](LICENSE)\n\n## Acknowledgements\n\n- Inspired by\n  [discord-image-generation](https://www.npmjs.com/package/discord-image-generation)\n  by mrkayjaydee\n- Built with [Deno](https://deno.land/) and\n  [sharp](https://sharp.pixelplumbing.com/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftotallynotdavid%2Fimage-generation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftotallynotdavid%2Fimage-generation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftotallynotdavid%2Fimage-generation/lists"}