3bl3gamer / wasm-mozjpeg

WebAssembly MozJPEG encoder
MIT License
2 stars 0 forks source link

WebAssembly MozJPEG encoder.

Inspired by cyrilwanner/wasm-codecs, saschazar21/webassembly/mozjpeg and the thirst for adventures.

Examples

Features

Installation

npm install https://github.com/3bl3gamer/wasm-mozjpeg

Usage

Basic

import { loadWebModule, compressSimpleRGBA } from 'wasm-mozjpeg'

loadWebModule().then(mozJpeg => {
    const quality = 75
    const iData = someCanvas.getContext('2d').getImageData(0, 0, 320, 240)

    const jpegChunks = compressSimpleRGBA(mozJpeg, iData.width, iData.height, quality, iData.data)
    const blob = new Blob(jpegChunks, { type: 'image/jpeg' })

    const img = new Image()
    img.src = URL.createObjectURL(blob)
    document.body.appendChild(img)
})

Advanced

import { loadWebModule, initCompressSimple, writeRowsSimple,
    JCS_EXT_RGBA, JCS_YCbCr } from 'wasm-mozjpeg'

loadWebModule().then(mozJpeg => {
    const iData = someCanvas.getContext('2d').getImageData(0, 0, 320, 240)

    const channels = 4 //R, G, B and A
    let { rowBufLocation, imgChunks } =
        initCompressSimple(mozJpeg, iData.width, iData.height, JCS_EXT_RGBA, channels)

    mozJpeg.cinfo_set_out_color_space(JCS_YCbCr)
    mozJpeg.cinfo_set_quant_table(3)
    mozJpeg.cinfo_set_quality(95, -1)
    mozJpeg.cinfo_set_optimize_coding(true)
    mozJpeg.cinfo_set_chroma_subsample(2, 2)
    mozJpeg.cinfo_set_smoothing_factor(0)
    mozJpeg.cinfo_disable_progression()
    mozJpeg.cinfo_set_trellis(10, true, true, true)

    mozJpeg.start_compress()
    writeRowsSimple(mozJpeg, rowBufLocation, iData.data, iData.height, iData.width * channels)
    mozJpeg.finish_compress()
    const blob = new Blob(imgChunks, { type: 'image/jpeg' })

    const img = new Image()
    img.src = URL.createObjectURL(blob)
    document.body.appendChild(img)
})

Color spaces

Different in/out color spaces may be used (see features). Just ensure MozJPEG can handle required color transformation.

For example, if input color data is already in YCbCr, it may be encoded directly:

// buffer should have length = width * wheight * 3
const { widht, height, buffer } = getYCbCrPixels()

const channels = 3
let { rowBufLocation, imgChunks } =
    initCompressSimple(mozJpeg, width, height, JCS_YCbCr, channels)

mozJpeg.cinfo_set_out_color_space(JCS_YCbCr)
//...
mozJpeg.start_compress()
writeRowsSimple(mozJpeg, rowBufLocation, buffer, height, width * channels)
mozJpeg.finish_compress()
//...

More info in index.d.ts, mozjpeg/libjpeg.txt and mozjpeg/README-mozilla.txt.

Bulding

./build_wasm.sh — rebuilds mozjpeg.wasm, generates const.js, requires Emscripten.

./generate_types.sh — generates .d.ts files by JSDoc annotations.