-
-
Notifications
You must be signed in to change notification settings - Fork 762
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add webp, avid, png, jpeg WASM format plugin (#1324)
* fix import error * export default plugins/formats * don't print noisy exif error * add webp plugin * add docs * add wasm-png/jpeg * add options to webp * add options to jpeg * add avif * add png optimization * get build owrking
- Loading branch information
1 parent
3d90ad8
commit 3bed692
Showing
30 changed files
with
1,172 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import React, { useEffect, useState } from "react"; | ||
|
||
import { defaultFormats, defaultPlugins } from "jimp"; | ||
import webp from "@jimp/wasm-webp"; | ||
import { createJimp } from "@jimp/core"; | ||
|
||
const Jimp = createJimp({ | ||
formats: [...defaultFormats, webp], | ||
plugins: defaultPlugins, | ||
}); | ||
|
||
export function WebpExample() { | ||
const [selectedFile, setSelectedFile] = useState(""); | ||
const [output, setOutput] = React.useState(""); | ||
|
||
function handleFile(e: React.ChangeEvent<HTMLInputElement>) { | ||
const file = e.target.files?.[0]; | ||
|
||
if (!file) { | ||
return; | ||
} | ||
|
||
const reader = new FileReader(); | ||
|
||
reader.onload = async (e) => { | ||
const data = e.target?.result; | ||
|
||
if (!data || !(data instanceof ArrayBuffer)) { | ||
return; | ||
} | ||
|
||
// Manipulate images uploaded directly from the website. | ||
const image = await Jimp.fromBuffer(data); | ||
image.quantize({ colors: 16 }).blur(8).pixelate(8); | ||
setSelectedFile(URL.createObjectURL(file)); | ||
setOutput(await image.getBase64("image/webp")); | ||
}; | ||
|
||
reader.readAsArrayBuffer(file); | ||
} | ||
|
||
useEffect(() => { | ||
// Or load images hosted on the same domain. | ||
Jimp.read("/jimp/tree.webp").then(async (image) => { | ||
setSelectedFile(await image.getBase64("image/png")); | ||
image.quantize({ colors: 16 }).blur(8).pixelate(8); | ||
setOutput(await image.getBase64("image/png")); | ||
}); | ||
}, []); | ||
|
||
return ( | ||
<div> | ||
{/* A file input that takes a png/jpeg */} | ||
<input type="file" accept="image/webp" onChange={handleFile} /> | ||
|
||
<div | ||
style={{ | ||
display: "flex", | ||
alignItems: "center", | ||
gap: 20, | ||
width: "100%", | ||
}} | ||
> | ||
{selectedFile && ( | ||
<img | ||
style={{ flex: 1, minWidth: 0, objectFit: "contain", margin: 0 }} | ||
src={selectedFile} | ||
alt="Input" | ||
/> | ||
)} | ||
{output && ( | ||
<img | ||
style={{ flex: 1, minWidth: 0, objectFit: "contain", margin: 0 }} | ||
src={output} | ||
alt="Output" | ||
/> | ||
)} | ||
</div> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
--- | ||
title: Using WEBP (And other WASM plugins) | ||
description: How to use Jimp WebP and other WASM plugins. | ||
--- | ||
|
||
import { WebpExample } from "../../../components/webp-example"; | ||
import WebpExampleCode from "../../../components/webp-example?raw"; | ||
import { Code } from "@astrojs/starlight/components"; | ||
|
||
The default build of Jimp only includes image formats written in javascript. | ||
To utilize webp (and anything else we don't have a JS implementation for) we need to use format plugins and create a custom jimp. | ||
|
||
```ts | ||
import { createJimp } from "@jimp/core"; | ||
import { defaultFormats, defaultPlugins } from "jimp"; | ||
import webp from "@jimp/wasm-webp"; | ||
|
||
// A custom jimp that supports webp | ||
const Jimp = createJimp({ | ||
formats: [...defaultFormats, webp], | ||
plugins: defaultPlugins, | ||
}); | ||
``` | ||
|
||
<br /> | ||
<WebpExample client:load /> | ||
|
||
<details> | ||
<summary>Full code for example</summary> | ||
|
||
<Code code={WebpExampleCode} lang="ts" title="example.jsx" /> | ||
|
||
</details> | ||
|
||
## Browser Usage | ||
|
||
Since you're no longer using a pre-bundled version of jimp you need configure your bundler to handle the node code. | ||
|
||
For example in vite/astro you can use `vite-plugin-node-polyfills`. | ||
|
||
```js | ||
|
||
import { nodePolyfills } from "vite-plugin-node-polyfills"; | ||
|
||
export default defineConfig({ | ||
plugins: [ | ||
// You only need to polyfill buffer if you're using a browser | ||
plugins: [nodePolyfills({ include: ["buffer"] })], | ||
], | ||
}); | ||
``` | ||
|
||
## All WASM Plugins | ||
|
||
- [@jimp/wasm-avif](https://github.com/jimp-dev/jimp/tree/main/plugins/wasm-avif) | ||
- [@jimp/wasm-jpeg](https://github.com/jimp-dev/jimp/tree/main/plugins/wasm-jpeg) | ||
- [@jimp/wasm-png](https://github.com/jimp-dev/jimp/tree/main/plugins/wasm-png) | ||
- [@jimp/wasm-webp](https://github.com/jimp-dev/jimp/tree/main/plugins/wasm-webp) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# `@jimp/wasm-avif` | ||
|
||
A format plugin for Jimp that adds support for AVIF images using the [libavif](https://github.com/AOMediaCodec/libavif). | ||
|
||
> NOTE: Only works in esm environments. | ||
## Usage | ||
|
||
```ts | ||
import { createJimp } from "@jimp/core"; | ||
import { defaultPlugins } from "jimp"; | ||
import avif from "@jimp/wasm-avif"; | ||
|
||
// A custom jimp that supports webp | ||
const Jimp = createJimp({ | ||
formats: [avif], | ||
plugins: defaultPlugins, | ||
}); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
import shared from "@jimp/config-eslint/base.js"; | ||
export default [...shared]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
{ | ||
"name": "@jimp/wasm-avif", | ||
"version": "1.0.1", | ||
"repository": "jimp-dev/jimp", | ||
"engines": { | ||
"node": ">=18" | ||
}, | ||
"scripts": { | ||
"lint": "eslint .", | ||
"build": "tshy", | ||
"dev": "tshy --watch", | ||
"clean": "rm -rf node_modules .tshy .tshy-build dist .turbo" | ||
}, | ||
"author": "Andrew Lisowski <[email protected]>", | ||
"license": "MIT", | ||
"devDependencies": { | ||
"@jimp/config-eslint": "workspace:*", | ||
"@jimp/config-typescript": "workspace:*", | ||
"@jimp/core": "workspace:*", | ||
"@jimp/plugin-color": "workspace:*", | ||
"@jimp/test-utils": "workspace:*", | ||
"@jimp/types": "workspace:*", | ||
"@types/node": "^18.19.48", | ||
"eslint": "^9.9.1", | ||
"tshy": "^3.0.2", | ||
"typescript": "^5.5.4", | ||
"vitest": "^2.0.5" | ||
}, | ||
"tshy": { | ||
"exclude": [ | ||
"**/*.test.ts" | ||
], | ||
"dialects": [ | ||
"esm" | ||
], | ||
"exports": { | ||
"./package.json": "./package.json", | ||
".": "./src/index.ts" | ||
} | ||
}, | ||
"exports": { | ||
"./package.json": "./package.json", | ||
".": { | ||
"import": { | ||
"types": "./dist/esm/index.d.ts", | ||
"default": "./dist/esm/index.js" | ||
} | ||
} | ||
}, | ||
"type": "module", | ||
"publishConfig": { | ||
"access": "public" | ||
}, | ||
"sideEffects": false, | ||
"dependencies": { | ||
"@jsquash/avif": "^1.3.0", | ||
"zod": "^3.23.8" | ||
}, | ||
"module": "./dist/esm/index.js" | ||
} |
Oops, something went wrong.