Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
wasm-imagemagick
Advanced tools
This project is not affiliated with ImageMagick , but is merely recompiling the code to be WebAssembly. I did this because I want to bring the power of ImageMagick to the browser.
Table of Contents
Simplest example. See 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/
Interactive execute context demo. Add images, execute commands using different syntaxes, manage and reuse output/input images, and choose commands examples to learn ImageMagick. Project lives here
Playground with several transformation examples and image formats. It also shows the output of transformations made with ImageMagick in the browser to verify wasm-imagemagick output the right thing.
https://knicknic.github.io/imagemagick/ a commandline sample of using ImageMagick
Used in Croppy to split webcomics from one long vertical strip into many panels.
Supports PNG, TIFF, JPEG, BMP, GIF, PhotoShop, GIMP, and more!
See a list of known supported formats in this demo
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 for details.
import { buildInputFile, execute, loadImageElement } from 'wasm-imagemagick'
const { outputFiles, exitCode} = await execute({
inputFiles: [await buildInputFile('http://some-cdn.com/foo/fn.png', 'image1.png')],
commands: [
'convert image1.png -rotate 70 image2.gif',
// heads up: the next command uses 'image2.gif' which was the output of previous command:
'convert image2.gif -scale 23% image3.jpg',
],
})
if(exitCode !== 0)
await loadImageElement(outputFiles[0], document.getElementById('outputImage'))
This 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
:
import { buildInputFile, execute } from 'wasm-imagemagick'
const { stdout, stderr, exitCode } = await execute({
inputFiles: [await buildInputFile('foo.gif')],
commands: `identify foo.gif`
})
if(exitCode === 0)
console.log('foo.gif identify output: ' + stdout.join('\n'))
else
console.error('foo.gif identify command failed: ' + stderr.join('\n'))
As 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:
import { call } from 'wasm-imagemagick'
// build an input file by fetching its content
const fetchedSourceImage = await fetch("assets/rotate.png")
const content = new Uint8Array(await fetchedSourceImage.arrayBuffer());
const image = { name: 'srcFile.png', content }
const command = ["convert", "srcFile.png", '-rotate', '90', '-resize', '200%', 'out.png']
const result = await call([image], command)
// is there any errors ?
if(result.exitCode !== 0)
return alert('There was an error: ' + result.stderr.join('\n'))
// response can be multiple files (example split) here we know we just have one
const outputImage = result.processedFiles[0]
// render the output image into an existing <img> element
const outputImage = document.getElementById('outputImage')
outputImage.src = URL.createObjectURL(outputImage.blob)
outputImage.alt = outputImage.name
npm install --save wasm-imagemagick
**IMPORTANT:
Don't forget to copy magick.wasm
and magick.js
files to the folder where your index.html
is being served:
cp node_modules/wasm-imagemagick/dist/magick.wasm .
cp node_modules/wasm-imagemagick/dist/magick.js .
Then you are ready to import the library in your project like this:
import { execute} from 'wasm-imagemagick'
or like this if you are not using standard modules:
const execute = require('wasm-imagemagick').execute
If 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.
Basic version, just reference online https://knicknic.github.io/wasm-imagemagick/magickApi.js no files needed at all.
See samples/rotate#code.
Relevant portions called out below "..."
means code is missing from example
<script type='module'>
//import the library to talk to imagemagick
import * as Magick from 'https://knicknic.github.io/wasm-imagemagick/magickApi.js';
// ...
// Fetch the image to rotate, and call image magick
let DoMagickCall = async function () {
// ....
// calling image magick with one source image, and command to rotate & resize image
let processedFiles = await Magick.Call([{ 'name': 'srcFile.png', 'content': sourceBytes }], ["convert", "srcFile.png", "-rotate", "90", "-resize", "200%", "out.png"]);
// ...
};
DoMagickCall();
</script>
Copy magick.js
, magick.wasm
in the same folder as your html file.:
<script type="module">
import { execute, loadImageElement, buildInputFile } from '../../dist/bundles/wasm-imagemagick.esm-es2018.js'
// ... same snippet as before
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js"></script>
<script src="../../dist/bundles/wasm-imagemagick.umd-es5.js"></script>
<script>
require(['wasm-imagemagick'], function (WasmImagemagick) {
const { execute, loadImageElement, buildInputFile } = WasmImagemagick
// ... same snippet as before
<script src="../../dist/bundles/wasm-imagemagick.umd-es5.js"></script>
<script>
const { execute, loadImageElement, buildInputFile } = window['wasm-imagemagick']
// ... same snippet as before
git clone --recurse-submodules https://github.com/KnicKnic/WASM-ImageMagick.git
cd WASM-ImageMagick
#ubuntu instructions
# install node
sudo snap install --edge node --classic
# install typescript
sudo npm install typescript -g
# install docker
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh
# be sure to add your user to the to the docker group and relogin
# install and run build
npm install
#windows instructions
# currently broken
# If you really want a build, create a PR,
# a build will get kicked off, click show all checks -> Details -> top right of the details page (in artifcats)
# docker run --rm -it --workdir /code -v %CD%:/code wasm-imagemagick-build-tools bash ./build.sh
Produces magick.js
, magickApi.js
, & magick.wasm
in the current folder.
npm test
will run all the tests.
npm run test-browser
will run spec in a headless chrome browser. These tests are located at ./spec/
.
npm run test-browser-server
will serve the test so you can debug them with a browser.
npm run test-browser-start
will run the server and start watching for file changes, recompile and restart the server for agile development.
npm test-node
will run some tests with nodejs located at ./tests/rotate
.
FAQs
Webassembly compilation of ImageMagick
The npm package wasm-imagemagick receives a total of 46,311 weekly downloads. As such, wasm-imagemagick popularity was classified as popular.
We found that wasm-imagemagick demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.