{"id":13672774,"url":"https://github.com/KnicKnic/WASM-ImageMagick","last_synced_at":"2025-04-28T03:32:55.786Z","repository":{"id":33018467,"uuid":"140663613","full_name":"KnicKnic/WASM-ImageMagick","owner":"KnicKnic","description":"Webassembly compilation of https://github.com/ImageMagick/ImageMagick \u0026 samples","archived":false,"fork":false,"pushed_at":"2023-10-23T19:30:43.000Z","size":2750,"stargazers_count":892,"open_issues_count":76,"forks_count":90,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-04-24T07:54:45.092Z","etag":null,"topics":["image","image-manipulation","image-processing","imagemagick","javascript","pwa","webassembly"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/KnicKnic.png","metadata":{"files":{"readme":"Readme.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2018-07-12T05:07:50.000Z","updated_at":"2025-03-27T15:28:03.000Z","dependencies_parsed_at":"2024-01-07T21:05:01.188Z","dependency_job_id":"6a5181ad-2a89-4929-998e-fc4b86f3805f","html_url":"https://github.com/KnicKnic/WASM-ImageMagick","commit_stats":{"total_commits":159,"total_committers":8,"mean_commits":19.875,"dds":0.5157232704402516,"last_synced_commit":"88ef4c6fb2a11b640669aa06c56df4c4c51566f7"},"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KnicKnic%2FWASM-ImageMagick","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KnicKnic%2FWASM-ImageMagick/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KnicKnic%2FWASM-ImageMagick/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KnicKnic%2FWASM-ImageMagick/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/KnicKnic","download_url":"https://codeload.github.com/KnicKnic/WASM-ImageMagick/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251246394,"owners_count":21558762,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["image","image-manipulation","image-processing","imagemagick","javascript","pwa","webassembly"],"created_at":"2024-08-02T09:01:47.457Z","updated_at":"2025-04-28T03:32:50.778Z","avatar_url":"https://github.com/KnicKnic.png","language":"TypeScript","funding_links":[],"categories":["Image","Misc","TypeScript"],"sub_categories":[],"readme":"# Web assembly ImageMagick [![Build Status](https://dev.azure.com/oneeyedelf1/wasm-imagemagick/_apis/build/status/KnicKnic.WASM-ImageMagick)](https://dev.azure.com/oneeyedelf1/wasm-imagemagick/_build/latest?definitionId=1)\r\nThis project is not affiliated with [ImageMagick](https://www.imagemagick.org) , but is merely recompiling the code to be [WebAssembly](https://webassembly.org/). I did this because I want to bring the power of ImageMagick to the browser.\r\n\r\n**Table of Contents**\r\n\r\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\r\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\r\n- [Demos and examples](#demos-and-examples)\r\n- [Status](#status)\r\n  - [Image formats supported](#image-formats-supported)\r\n  - [Features **not** supported](#features-not-supported)\r\n- [API](#api)\r\n  - [High level API and utilities](#high-level-api-and-utilities)\r\n  - [Accessing stdout, stderr, exitCode](#accessing-stdout-stderr-exitcode)\r\n  - [low-level example](#low-level-example)\r\n- [Importing the library in your project](#importing-the-library-in-your-project)\r\n  - [With npm](#with-npm)\r\n  - [Loading directly from html file](#loading-directly-from-html-file)\r\n    - [Importing it as JavaScript standard module:](#importing-it-as-javascript-standard-module)\r\n    - [Using the UMD bundle in AMD projects (requirejs)](#using-the-umd-bundle-in-amd-projects-requirejs)\r\n    - [Using the UMD bundle without libraries](#using-the-umd-bundle-without-libraries)\r\n- [Build instructions](#build-instructions)\r\n- [Run tests](#run-tests)\r\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\r\n\r\n\r\n## Demos and examples\r\n\r\n * Simplest example. See [samples/rotate#code](samples/rotate#code). A simple webpage (plain javascript) that has image in array and loads magickApi.js to rotate file. Demonstration site [https://knicknic.github.io/imagemagick/rotate/](https://knicknic.github.io/imagemagick/rotate/)\r\n\r\n * Basic playground (React \u0026 TypeScript project): [![Basic playground (React \u0026 TypeScript project)](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/wasm-imagemagick-basic-demo-y00u2).\r\n\r\n * Image Diff Example (React \u0026 TypeScript project): [![Basic playground for image diff (React \u0026 TypeScript project)](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/yvn6rkr16z).\r\n\r\n * [Interactive execute context demo](https://cancerberosgx.github.io/demos/WASM-ImageMagick/interactive-execute-context/). Add images, execute commands using different syntaxes, manage and reuse output/input images, and choose commands examples to learn ImageMagick. [Project lives here](./samples/interactive-execute-context)\r\n\r\n * [Playground with several transformation examples and image formats](https://cancerberosgx.github.io/autumn-leaves/#/convertDemo). It also shows the output of transformations made with ImageMagick in the browser to verify wasm-imagemagick output the right thing.  \r\n\r\n * [Picture Frame editor](https://cancerberosgx.github.io/autumn-leaves/#/imageFrame).\r\n\r\n * [https://knicknic.github.io/imagemagick/](https://knicknic.github.io/imagemagick/) a commandline sample of using ImageMagick\r\n    * For code see [samples/cmdline](samples/cmdline)\r\n\r\n * Used in [Croppy](https://knicknic.github.io/croppy/) to split webcomics from one long vertical strip into many panels.\r\n    * For code see https://github.com/KnicKnic/croppy.\r\n\r\n\r\n\r\n## Status\r\n\r\n### Image formats supported\r\n\r\nSupports PNG, TIFF, JPEG, BMP, GIF, [PhotoShop](https://www.adobe.com/products/photoshop.html), [GIMP](https://www.gimp.org/), and more! \r\n\r\nSee a list of known supported formats in this [demo](https://cancerberosgx.github.io/demos/WASM-ImageMagick/supported-formats/)\r\n\r\n### Features **not** supported \r\n\r\n * [Text](https://www.imagemagick.org/Usage/text/)\r\n * [Fourier Transforms](https://www.imagemagick.org/Usage/fourier/)\r\n * Formats not listed above, particularly webp.\r\n \r\n\r\n\r\n## API\r\n\r\n### Reference API Documentation\r\n\r\n[Reference API Documentation](./apidocs)\r\n\r\n\r\n### High level API and utilities\r\n\r\n`wasm-imagemagick` comes with some easy to use APIs for creating image files from urls, executing multiple commands reusing output images and nicer command syntax, and utilities to handle files, html images, input elements, image comparison, metadata extraction, etc. Refer to [API Reference Documentation](./apidocs) for details.\r\n\r\n```ts\r\nimport { buildInputFile, execute, loadImageElement } from 'wasm-imagemagick'\r\n\r\nconst { outputFiles, exitCode} = await execute({\r\n  inputFiles: [await buildInputFile('http://some-cdn.com/foo/fn.png', 'image1.png')],\r\n  commands: [\r\n    'convert image1.png -rotate 70 image2.gif',\r\n    // heads up: the next command uses 'image2.gif' which was the output of previous command:\r\n    'convert image2.gif -scale 23% image3.jpg',\r\n  ],\r\n})\r\nif(exitCode !== 0)\r\n    await loadImageElement(outputFiles[0], document.getElementById('outputImage'))\r\n```\r\n\r\n### Accessing stdout, stderr, exitCode\r\n\r\nThis other example executes `identify` command to extract information about an image. As you can see, we access `stdout` from the execution result and check for errors using `exitCode` and `stderr`: \r\n\r\n```ts\r\nimport { buildInputFile, execute } from 'wasm-imagemagick'\r\n\r\nconst { stdout, stderr, exitCode } = await execute({\r\n    inputFiles: [await buildInputFile('foo.gif')], \r\n    commands: `identify foo.gif`\r\n})\r\nif(exitCode === 0) \r\n    console.log('foo.gif identify output: ' + stdout.join('\\n'))\r\nelse \r\n    console.error('foo.gif identify command failed: ' + stderr.join('\\n'))\r\n```\r\n\r\n### low-level example\r\n\r\nAs demonstration purposes, the following example doesn't use any helper provided by the library, only the low level `call()` function which only accept one command, in array syntax only:\r\n\r\n```js\r\nimport { call } from 'wasm-imagemagick'\r\n\r\n// build an input file by fetching its content\r\nconst fetchedSourceImage = await fetch(\"assets/rotate.png\")\r\nconst content = new Uint8Array(await fetchedSourceImage.arrayBuffer());\r\nconst image = { name: 'srcFile.png', content }\r\n\r\nconst command = [\"convert\", \"srcFile.png\", '-rotate', '90', '-resize', '200%', 'out.png']\r\nconst result = await call([image], command)\r\n\r\n// is there any errors ?\r\nif(result.exitCode !== 0)\r\n    return alert('There was an error: ' + result.stderr.join('\\n'))\r\n\r\n// response can be multiple files (example split) here we know we just have one\r\nconst outputImage = result.processedFiles[0]\r\n\r\n// render the output image into an existing \u003cimg\u003e element\r\nconst outputImage = document.getElementById('outputImage')\r\noutputImage.src = URL.createObjectURL(outputImage.blob)\r\noutputImage.alt = outputImage.name\r\n```\r\n\r\n\r\n## Importing the library in your project\r\n\r\n### With npm\r\n\r\n```sh\r\nnpm install --save wasm-imagemagick\r\n```\r\n\r\n**IMPORTANT:  \r\n\r\n**Don't forget to copy `magick.wasm` and `magick.js`** files to the folder where your `index.html` is being served:\r\n\r\n```sh\r\ncp node_modules/wasm-imagemagick/dist/magick.wasm .\r\ncp node_modules/wasm-imagemagick/dist/magick.js .\r\n```\r\n\r\nThen you are ready to import the library in your project like this: \r\n\r\n```ts\r\nimport { execute} from 'wasm-imagemagick'\r\n```\r\n\r\nor like this if you are not using standard modules:\r\n\r\n```ts\r\nconst execute = require('wasm-imagemagick').execute\r\n```\r\n\r\n\r\n### Loading directly from html file\r\n\r\nIf you are not working in a npm development environment you can still load the library bundle .js file. It supports being imported as JavaScript standard module or as a UMD module.\r\n\r\n#### Importing magickApi.js as a JavaScript standard module: \r\n\r\nBasic version, just reference online https://knicknic.github.io/wasm-imagemagick/magickApi.js no files needed at all.\r\n\r\nSee [samples/rotate#code](samples/rotate#code).\r\n\r\nRelevant portions called out below `\"...\"` means code is missing from example\r\n```html\r\n  \u003cscript type='module'\u003e\r\n    //import the library to talk to imagemagick\r\n    import * as Magick from 'https://knicknic.github.io/wasm-imagemagick/magickApi.js';\r\n\r\n    // ...\r\n\r\n    // Fetch the image to rotate, and call image magick\r\n    let DoMagickCall = async function () {\r\n      // ....\r\n\r\n      // calling image magick with one source image, and command to rotate \u0026 resize image\r\n      let processedFiles = await Magick.Call([{ 'name': 'srcFile.png', 'content': sourceBytes }], [\"convert\", \"srcFile.png\", \"-rotate\", \"90\", \"-resize\", \"200%\", \"out.png\"]);\r\n\r\n      // ...\r\n    };\r\n    DoMagickCall();\r\n  \u003c/script\u003e\r\n``` \r\n\r\n[Working example source code](samples/rotate/index.html).\r\n\r\n\r\n#### Below examples need additional files coppied: \r\n\r\nCopy `magick.js`, `magick.wasm` in the same folder as your html file.:\r\n\r\n#### Importing a bundle as a JavaScript standard module: \r\n\r\n\r\n```html\r\n\u003cscript type=\"module\"\u003e\r\n    import { execute, loadImageElement, buildInputFile } from '../../dist/bundles/wasm-imagemagick.esm-es2018.js'\r\n    // ... same snippet as before\r\n\u003c/script\u003e\r\n```\r\n\r\n[Working example source code](./tests/bundles/esm-test.html)\r\n\r\n\r\n#### Using the UMD bundle in AMD projects (requirejs)\r\n\r\n```html\r\n\u003cscript src=\"https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js\"\u003e\u003c/script\u003e\r\n\u003cscript src=\"../../dist/bundles/wasm-imagemagick.umd-es5.js\"\u003e\u003c/script\u003e\r\n\u003cscript\u003e\r\nrequire(['wasm-imagemagick'], function (WasmImagemagick) {\r\n    const { execute, loadImageElement, buildInputFile } = WasmImagemagick\r\n    // ... same snippet as before\r\n```\r\n\r\n[Working example source code](./tests/bundles/umd-test-requirejs.html)\r\n\r\n\r\n#### Using the UMD bundle without libraries\r\n\r\n```html\r\n\u003cscript src=\"../../dist/bundles/wasm-imagemagick.umd-es5.js\"\u003e\u003c/script\u003e\r\n\u003cscript\u003e\r\n    const { execute, loadImageElement, buildInputFile } = window['wasm-imagemagick']\r\n    // ... same snippet as before\r\n```\r\n\r\n[Working example source code](./tests/bundles/umd-test-nolibrary.html)\r\n\r\n\r\n\r\n## Build instructions\r\n\r\n```sh\r\ngit clone --recurse-submodules https://github.com/KnicKnic/WASM-ImageMagick.git\r\n\r\ncd WASM-ImageMagick\r\n\r\n#ubuntu instructions\r\n#   install node\r\nsudo snap install --edge node --classic\r\n#   install typescript\r\nsudo npm install typescript -g\r\n#   install docker\r\ncurl -fsSL https://get.docker.com -o get-docker.sh\r\nsh get-docker.sh\r\n#   be sure to add your user to the to the docker group and relogin\r\n\r\n# install and run build\r\nnpm install\r\n\r\n\r\n#windows instructions\r\n# currently broken\r\n# If you really want a build, create a PR, \r\n# a build will get kicked off, click show all checks -\u003e Details -\u003e top right of the details page (in artifcats) \r\n\r\n# docker run --rm -it --workdir /code -v %CD%:/code wasm-imagemagick-build-tools bash ./build.sh\r\n```\r\n\r\nProduces `magick.js`, `magickApi.js`, \u0026 `magick.wasm` in the current folder.\r\n\r\n## Run tests\r\n\r\n`npm test` will run all the tests.\r\n\r\n`npm run test-browser` will run spec in a headless chrome browser. These tests are located at `./spec/`. \r\n\r\n`npm run test-browser-server` will serve the test so you can debug them with a browser. \r\n\r\n`npm run test-browser-start` will run the server and start watching for file changes, recompile and restart the server for agile development.\r\n\r\n`npm test-node` will run some tests with nodejs located at `./tests/rotate`.\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FKnicKnic%2FWASM-ImageMagick","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FKnicKnic%2FWASM-ImageMagick","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FKnicKnic%2FWASM-ImageMagick/lists"}