{"id":11078,"library":"imagescript","title":"ImageScript","description":"ImageScript is a zero-dependency JavaScript library designed for high-performance bitmap image manipulation. It supports a wide array of image formats, including decoding PNG, JPEG, TIFF, and GIF, along with capabilities for rendering SVGs and vector fonts. The library also handles encoding images to PNG, JPEG, WebP, and GIF. Currently at version 1.4.0, it distinguishes itself from other JavaScript imaging tools by leveraging lower-level memory access, reduced memory copying, and utilizing WebAssembly or native binaries for superior performance and a smaller memory footprint. It offers a comprehensive set of image manipulation functions like cropping, rotation, compositing, and various color adjustments. The project maintains an active development pace with regular updates and ships with TypeScript types, enhancing developer experience.","status":"active","version":"1.3.1","language":"javascript","source_language":"en","source_url":"https://github.com/matmen/ImageScript","tags":["javascript","image","image processing","image manipulation","png","jpeg","jpg","scale","resize","typescript"],"install":[{"cmd":"npm install imagescript","lang":"bash","label":"npm"},{"cmd":"yarn add imagescript","lang":"bash","label":"yarn"},{"cmd":"pnpm add imagescript","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The primary class for bitmap image operations. While CommonJS `require` works, ESM `import` is recommended, especially for TypeScript users.","wrong":"const { Image } = require('imagescript');","symbol":"Image","correct":"import { Image } from 'imagescript';"},{"note":"Use the `GIF` class for GIF-specific decoding, encoding, and frame manipulation. Like `Image`, ESM is preferred.","wrong":"const { GIF } = require('imagescript');","symbol":"GIF","correct":"import { GIF } from 'imagescript';"},{"note":"Image.decode is an asynchronous static method. Always `await` its result. The CommonJS example misses `await` and uses `require`.","wrong":"const { Image } = require('imagescript');\nconst image = Image.decode(buffer);","symbol":"Image.decode","correct":"import { Image } from 'imagescript';\nconst image = await Image.decode(buffer);"}],"quickstart":{"code":"import { Image, GIF } from 'imagescript';\nimport { readFileSync, writeFileSync } from 'fs';\n\nasync function processImage() {\n  // Load an image from a buffer\n  const inputBuffer = readFileSync('./assets/example.png'); // Replace with a valid path to a PNG image\n  const image = await Image.decode(inputBuffer);\n\n  // Resize and add a red tint\n  image.resize(200, Image.RESIZE_AUTO);\n  image.tint(255, 0, 0, 0.2); // 20% red tint\n\n  // Composite another image (e.g., a watermark) if available\n  try {\n    const watermarkBuffer = readFileSync('./assets/watermark.png'); // Optional: replace with a watermark image\n    const watermark = await Image.decode(watermarkBuffer);\n    watermark.resize(image.width / 4, Image.RESIZE_AUTO);\n    image.composite(watermark, image.width - watermark.width - 10, image.height - watermark.height - 10);\n  } catch (e) {\n    console.warn('Watermark image not found, skipping compositing.');\n  }\n\n  // Render text onto the image\n  image.renderText(\n    'Hello ImageScript!',\n    'sans-serif', // Font family (must be available in the environment)\n    48,\n    0, 0, // position\n    0xFFFFFFFF, // white color with full alpha\n    0x000000FF, // black outline with full alpha\n    2\n  );\n\n  // Encode the modified image to a new PNG file\n  const outputBuffer = await image.encode();\n  writeFileSync('./output_image.png', outputBuffer);\n  console.log('Image processed and saved to output_image.png');\n\n  // Example of GIF decoding/encoding (requires a GIF file)\n  try {\n    const gifBuffer = readFileSync('./assets/example.gif'); // Replace with a valid path to a GIF image\n    const gif = await GIF.decode(gifBuffer);\n    gif.loop = 0; // Loop indefinitely\n    gif.frames.forEach(frame => {\n      frame.image.rotate(10); // Rotate each frame by 10 degrees\n    });\n    const outputGifBuffer = await gif.encode();\n    writeFileSync('./output_gif.gif', outputGifBuffer);\n    console.log('GIF processed and saved to output_gif.gif');\n  } catch (e) {\n    console.warn('GIF example skipped: Make sure to have a ./assets/example.gif file.');\n  }\n}\n\n// Create a dummy image file for the example if it doesn't exist\ntry {\n  readFileSync('./assets/example.png');\n} catch (e) {\n  console.log('Creating dummy assets for quickstart...');\n  const dummyImage = new Image(300, 200);\n  dummyImage.fill(0x0000FFFF); // Blue background\n  dummyImage.encode().then(buffer => writeFileSync('./assets/example.png', buffer));\n  const dummyWatermark = new Image(100, 50);\n  dummyWatermark.fill(0xFF000088); // Semi-transparent red\n  dummyWatermark.encode().then(buffer => writeFileSync('./assets/watermark.png', buffer));\n  console.log('Dummy images created. Re-run quickstart after this.');\n  // Exit so the user can re-run with the created files\n  process.exit(0);\n}\n\nprocessImage().catch(console.error);","lang":"typescript","description":"This quickstart demonstrates loading an image, performing common manipulations like resizing, tinting, compositing another image, rendering text, and finally encoding it back to a file. It also includes an example for processing GIF files by rotating each frame. Ensure you have 'assets/example.png' and optionally 'assets/watermark.png' and 'assets/example.gif' for full functionality; dummy files will be generated if not found."},"warnings":[{"fix":"Always prepend `await` before calling asynchronous ImageScript methods, for example: `const image = await Image.decode(buffer);`","message":"All image decoding and encoding operations (e.g., `Image.decode`, `Image.encode`, `GIF.decode`, `GIF.encode`) are asynchronous and return Promises. Forgetting to use `await` will result in unexpected behavior, typically a `TypeError` when attempting to call methods on the Promise object instead of the resolved Image or GIF instance.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Implement error handling for `OutOfMemoryError` where applicable. For extremely large images, consider pre-processing or breaking down tasks into smaller, more manageable chunks if possible. Optimize image dimensions before complex operations.","message":"While ImageScript is zero-dependency and performance-focused, handling very large images can still consume significant memory and CPU resources. Users processing high-resolution images in constrained environments should monitor memory usage and consider optimizing workflows (e.g., processing smaller tiles).","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Ensure input buffers contain complete and valid image data for the intended format. Implement robust `try-catch` blocks around `decode` operations to gracefully handle invalid inputs.","message":"ImageScript relies on specific byte patterns and structures for image decoding. Providing corrupted or malformed image data (e.g., an incomplete buffer, a file with an incorrect extension, or an unsupported sub-format) will lead to decoding errors, preventing image processing.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure `import { Image } from 'imagescript';` is used and the call is `const image = await Image.decode(buffer);` within an `async` function. For CommonJS, use `const { Image } = require('imagescript');`.","cause":"This error typically occurs if `Image.decode` was called without `await` in an async context, returning a Promise instead of the Image class itself, or if the `Image` class was not correctly imported.","error":"TypeError: Image.decode is not a function"},{"fix":"Verify that the input buffer is a complete and uncorrupted image file of a supported type (PNG, JPEG, TIFF, GIF) and that the file path or data source is correct.","cause":"The provided buffer does not contain valid image data for any of the supported formats, or the data is corrupted/incomplete.","error":"Error: Invalid image data"},{"fix":"For ImageScript, prefer ESM imports (`import { ... } from 'imagescript';`). If you must use CommonJS, ensure your project setup allows for interoperability or stick to `require` for the entire codebase if it's a CJS project. Set `\"type\": \"module\"` in `package.json` for ESM projects or use `.mjs` extensions.","cause":"This error arises when a CommonJS module (`require`) attempts to import an ESM-only package or when Node.js is configured for ESM but a CommonJS-style `require` is used with a mixed module type.","error":"ERR_REQUIRE_ESM"}],"ecosystem":"npm"}