Skip to content

v3.1.0: WebP, APNG, TGA and TrueType hinting

Choose a tag to compare

@matmen matmen released this 15 Oct 08:52
· 184 commits to master since this release
Immutable release. Only release title and notes can be modified.

This release adds three image formats, crisper small text and a format-independent animation API. Everything is still plain TypeScript without dependencies.

New

WebP (#19, #20)

  • Decoding of lossy, lossless, transparent and animated WebPs. The output is bit-exact with libwebp: every reference image of libwebp's official test suite matches.
    • Still WebPs: Image.decode()
    • Animated WebPs: Animation.decode()
  • Lossless encoding: Image.encodeWebP() and Animation.encodeWebP(). The files are typically 20–30% smaller than PNG.
  • Works in Deno too (jsr:@matmen/imagescript).

Animations and APNG (#6)

  • Animation, the new base class of GIF, works with every animated format:
    • Animation.decode() reads GIF, APNG and WebP; still images become a single frame.
    • encodeGIF(), encodeAPNG() and encodeWebP() write them.
  • APNG decoding and encoding with full alpha. Broken animations fall back to the default image, like browsers do. Image.decode() still returns an APNG's default image.

TGA (#21)

Decoding of color mapped, truecolor and greyscale TGAs, uncompressed or run length encoded, in all four orientations. Image.decode() recognizes them automatically. encodeTGA() writes them.

TrueType hinting (#31)

renderText() now runs the hinting instructions of TrueType fonts, so small text comes out crisp: stems and edges are aligned with the pixel grid, like on Windows. The results match FreeType point for point.

  • Glyphs of hinted fonts are placed on whole pixels.
  • Fonts without hinting instructions (and OpenType/CFF fonts) render exactly as before.

colorToAlpha() (#39)

Makes a color transparent, for example to remove a solid background, like GIMP's "Color to Alpha". Antialiased edges become semi-transparent instead of keeping a fringe of the old background.

  • Without a color, the top left pixel's color is used.
  • Thresholds control how close a color has to be to become fully transparent.

Deprecated

  • GIF: use Animation, which works the same and also handles APNG and WebP:

    Before Now
    new GIF(frames).encode() new Animation(frames).encodeGIF()
    GIF.decode() Animation.decode()

    GIF keeps working in 3.x and will be removed in 4.0.

Fixes

  • Text rendering: glyphs touching the left edge of their bitmap could come out inverted.

Upgrading

No code changes are needed. Text rendered with hinted TrueType fonts looks slightly different (crisper, on whole pixels). To keep the previous rendering, pass {hinting: false}:

Image.renderText(font, size, text, color, layout, {hinting: false})