diff --git a/README.md b/README.md index 0552d15..20a25cf 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,26 @@ jSquash name is inspired by jQuery and Squoosh. It symbolizes the browser suppor ⚠️ All packages are ESM modules. You may need to manually transpile the packages if your build environment still relies on Commonjs formats. +## Usage in the Browser + +You can use the packages directly from the Unpkg CDN and can be the easiest way to get started. + +```js +import { decode } from "https://unpkg.com/@jsquash/jpeg?module"; +import { encode } from "https://unpkg.com/@jsquash/webp?module"; + +const imageResponse = await fetch("https://picsum.photos/200/300.jpg"); +const imageData = await decode(await imageResponse.arrayBuffer()); +const webpImageBuffer = await encode(imageData); +``` + +To target a specific version, you can use the `@version` syntax. +```js +import { encode } from "https://unpkg.com/@jsquash/webp@1.2.0?module"; +``` + +Checkout the [with CDN](/examples/with-cdn) example for a working demo. + ## Usage in Cloudflare Workers Using jSquash modules with Cloudflare Workers requires some additional steps so that the WASM binaries get included. diff --git a/examples/with-cdn/index.html b/examples/with-cdn/index.html new file mode 100644 index 0000000..f0bfa29 --- /dev/null +++ b/examples/with-cdn/index.html @@ -0,0 +1,40 @@ + + + + + + + jSquash with Rollup example + + +

Image Converter

+
+ +

Choose output image type:

+
+ + + + + +
+ +
+

Output Image (Right click to save)

+
+ + + \ No newline at end of file diff --git a/examples/with-cdn/main.js b/examples/with-cdn/main.js new file mode 100644 index 0000000..6b52431 --- /dev/null +++ b/examples/with-cdn/main.js @@ -0,0 +1,83 @@ +import * as avif from 'https://unpkg.com/@jsquash/avif@latest?module'; +import * as jpeg from 'https://unpkg.com/@jsquash/jpeg@latest?module'; +import * as jxl from 'https://unpkg.com/@jsquash/jxl@latest?module'; +import * as png from 'https://unpkg.com/@jsquash/png@latest?module'; +import * as webp from 'https://unpkg.com/@jsquash/webp@latest?module'; + +async function decode (sourceType, fileBuffer) { + switch (sourceType) { + case 'avif': + return await avif.decode(fileBuffer); + case 'jpeg': + return await jpeg.decode(fileBuffer); + case 'jxl': + return await jxl.decode(fileBuffer); + case 'png': + return await png.decode(fileBuffer); + case 'webp': + return await webp.decode(fileBuffer); + default: + throw new Error(`Unknown source type: ${sourceType}`); + } +} + +async function encode (outputType, imageData) { + switch (outputType) { + case 'avif': + return await avif.encode(imageData); + case 'jpeg': + return await jpeg.encode(imageData); + case 'jxl': + return await jxl.encode(imageData); + case 'png': + return await png.encode(imageData); + case 'webp': + return await webp.encode(imageData); + default: + throw new Error(`Unknown output type: ${outputType}`); + } +} + +async function convert (sourceType, outputType, fileBuffer) { + const imageData = await decode(sourceType, fileBuffer); + return encode(outputType, imageData); +} + +function blobToBase64(blob) { + return new Promise((resolve, _) => { + const reader = new FileReader(); + reader.onloadend = () => resolve(reader.result); + reader.readAsDataURL(blob); + }); +} + +async function showOutput (imageBuffer, outputType) { + const preview = document.querySelector('#preview'); + const imageBlob = new Blob([imageBuffer], { type: `image/${outputType}` }); + const base64String = await blobToBase64(imageBlob); + const previewImg = document.createElement('img'); + previewImg.src = base64String; + preview.innerHTML = ''; + preview.appendChild(previewImg); +} + +async function initForm () { + const form = document.querySelector('form'); + + form.addEventListener('submit', async (event) => { + event.preventDefault(); + const formData = new FormData(form); + const file = formData.get('file'); + const sourceType = file.name.endsWith('jxl') ? 'jxl' : file.type.replace('image/', ''); + const outputType = formData.get('outputType'); + const fileBuffer = await file.arrayBuffer(); + const imageBuffer = await convert(sourceType, outputType, fileBuffer); + showOutput(imageBuffer, outputType); + }); +} + +async function main () { + initForm(); +} + +main();