pixbooster

package module
v0.0.0-...-3cc8a80 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 20, 2024 License: LGPL-2.1 Imports: 24 Imported by: 0

README

Caddy Pixbooster

On-the-fly image conversion for maximal network performances

DO NOT USE IN PRODUCTION!

This work is at its very early stages and should only be used for testing.

Desription

Pixbooster does two things:

  1. it adds modern files format sources (WebP, AVIF and JXL) to the HTML,
  2. it serve those files by converting the orignal ones on the fly, from saved files after.
How <img> is handled

When Pixbooster meet a <img> tag out of any picture tag, it wrap this <img> in a new <picture> and add <source> tags for each modern formats.

So:

<img src="test.jpg" style="width: 100px" title="test" alt="alt">

became:

<picture style="width: 100px" title="test"><source srcset="test.jpg.pixbooster.jxl" type="image/jxl"/><source srcset="test.jpg.pixbooster.avif" type="image/avif"/><source srcset="test.jpg.pixbooster.webp" type="image/webp"/><img src="test.jpg" style="width: 100px" title="test" alt="alt"/></picture>

The pixbooster is afterward used by Pixbooster to know which files it have to generate.

How <picture> is handled

When Pixbooster met a <picture>, it generate a new <source> for each <source> it contains and for each modern formats.

So:

<picture>
    <source srcset="test3.png" type="image/png"  media="(min-width: 800px)">
    <img src="test2.png" style="width: 100px" title="test" alt="alt">
</picture>

became:

<picture>
    <source media="(min-width: 800px)" srcset="test3.png.pixbooster.jxl" type="image/jxl"/><source media="(min-width: 800px)" srcset="test3.png.pixbooster.avif" type="image/avif"/><source media="(min-width: 800px)" srcset="test3.png.pixbooster.webp" type="image/webp"/><source srcset="test3.png" type="image/png" media="(min-width: 800px)"/>
    <img src="test2.png" style="width: 100px" title="test" alt="alt"/>
</picture>

How to test

Clone
$ git clone https://github.com/PixyBlue/caddy-pixbooster.git
$ cd caddy-pixbooster
Configure

Here is a Caddyfile sample for tests:

{
    debug
}

http://localhost:8080 {
    root ./public
    route {
        pixbooster
    }
    file_server
}

pixbooster accept some options to disable some image formats to be treaten or to be produce:

  • nojpg, nopng, nowebpinput make Pixbooster ignore respectively JPEG, PNG and WebP files in the incomming HTML,
  • nowebpouput, noavif, nojxl disable adding sources respectively for WebP, AVIF and JXL formats in the incomming HTML and avoid the conversion of such files from request URL.
Provide some contents
$ mkdir public
$ echo '<!DOCTYPE html>
<html>

<head>
    <title>Foo</title>
</head>

<body>
    <img src="test.jpg" style="width: 100px" title="test" alt="alt">
    <img src="test5.png" srcset="test6.png 2x, test7.png 1x" style="width: 100px" title="test" alt="alt">
    <picture>
        <source srcset="test3.png" type="image/png" media="(min-width: 800px)">
        <img src="test2.png" style="width: 100px" title="test" alt="alt">
    </picture>
</body>

</html>' > public/index.html

Add needed picture files to public.

Build & Run
$ CGO_ENABLED=1 xcaddy run --config Caddyfile #CGO is required to enable convertion to the WebP format
See the magic
$ curl http://localhost:8080

Detailed configuration

Syntax
pixbooster [nowebpoutput|noavif|nojxl|nojpg|nopng] {
	[nowebpoutput|noavif|nojxl|nojpg|nopng]
	quality <integer between 0 and 100>
    storage <path where to store optimized files>
	webp {
		quality <integer between 0 and 100>
		lossless
		exact
	}
	avif {
		quality <integer between 0 and 100>
		qualityalpha <integer between 0 and 100>
		speed <integer between 0 and 10>
	}
	jxl {
		quality <integer between 0 and 100>
		effort <integer between 0 and 10>
	}
}

Pixbooster must be enabled in a route directive.

Samples

The Caddfyfile configuration enable you to access to all options offered by the libraries we use. Here is a complete sample:

http://localhost:8080 {
    route {
        pixbooster {
            nowebpoutput
            nojxl
            avif {
                quality 65
                speed 7
            }
        }
    }
}

TODO ?

  • Provide JXL polyfill
  • Add data-pixbooster-quality html attribute to force quality setting on individual picture
  • Handle CSS
  • Completly avoid CGO to support WebP output

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ImgFormat

type ImgFormat struct {
	// contains filtered or unexported fields
}

type Pixbooster

type Pixbooster struct {
	CGOEnabled bool

	Storage string

	Nowebpoutput bool
	Nowebpinput  bool
	Noavif       bool
	Nojxl        bool
	Nojpeg       bool
	Nopng        bool

	Quality    int
	WebpConfig WebpConfig
	AvifConfig avif.Options
	JxlConfig  jpegxl.Options
	// contains filtered or unexported fields
}

func (*Pixbooster) AddSourceNode

func (p *Pixbooster) AddSourceNode(n *html.Node, srcset string, mimeType string, copyAttr bool)

func (*Pixbooster) AddSourcesToPicture

func (p *Pixbooster) AddSourcesToPicture(picture *html.Node, copyAttr bool)

func (*Pixbooster) AddSourcesToSource

func (p *Pixbooster) AddSourcesToSource(source *html.Node, copyAttr bool)

func (Pixbooster) CaddyModule

func (Pixbooster) CaddyModule() caddy.ModuleInfo

func (*Pixbooster) CollectImgs

func (p *Pixbooster) CollectImgs(n *html.Node, imgs []*html.Node) []*html.Node

func (*Pixbooster) CollectPictures

func (p *Pixbooster) CollectPictures(n *html.Node, pictures []*html.Node) []*html.Node

func (*Pixbooster) ConfigureCGO

func (p *Pixbooster) ConfigureCGO()

func (*Pixbooster) ConvertImageToFormat

func (p *Pixbooster) ConvertImageToFormat(imgURL string, format ImgFormat) (io.Reader, error)

func (*Pixbooster) GetAttr

func (p *Pixbooster) GetAttr(n *html.Node, attribute string) string

func (*Pixbooster) GetOptimizedImageURL

func (p *Pixbooster) GetOptimizedImageURL(originalURL string, format ImgFormat) string

func (*Pixbooster) GetOptimizedSrcset

func (p *Pixbooster) GetOptimizedSrcset(srcset string, format ImgFormat) string

func (*Pixbooster) GetOriginalImageURL

func (p *Pixbooster) GetOriginalImageURL(optimizedURL string) string

func (*Pixbooster) GetRootUrl

func (p *Pixbooster) GetRootUrl(r *http.Request) string

func (*Pixbooster) HasAttr

func (p *Pixbooster) HasAttr(n *html.Node, name string) bool

func (*Pixbooster) IsImageInsidePicture

func (p *Pixbooster) IsImageInsidePicture(img *html.Node) bool

func (*Pixbooster) IsOptimizedUrl

func (p *Pixbooster) IsOptimizedUrl(myurl string) bool

func (*Pixbooster) IsSameSite

func (p *Pixbooster) IsSameSite(imageURL string) bool

func (*Pixbooster) Provision

func (p *Pixbooster) Provision(ctx caddy.Context) error

func (Pixbooster) ServeHTTP

func (p Pixbooster) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error

func (*Pixbooster) UnmarshalCaddyfile

func (p *Pixbooster) UnmarshalCaddyfile(d *caddyfile.Dispenser) error

UnmarshalCaddyfile implements caddyfile.Unmarshaler. Syntax:

pixbooster [nowebpoutput|noavif|nojxl|nojpg|nopng] {
	[nowebpoutput|noavif|nojxl|nojpg|nopng]
	quality <integer between 0 and 100>
	storage <directory> Path to the directory where to store generated picture files
	webp {
		quality <integer between 0 and 100>
		lossless
		exact
	}
	avif {
		quality <integer between 0 and 100>
		qualityalpha <integer between 0 and 100>
		speed <integer between 0 and 10>
	}
	jxl {
		quality <integer between 0 and 100>
		effort <integer between 0 and 10>
	}
}

The 'quality' value is inherited by webp.quality, avif.quality, and jxl.quality if not specified. The 'speed' and 'effort' values should be integers between 0 and 10. The 'lossless' and 'exact' flags are set to true if specified. All directives are optional.

func (*Pixbooster) WrapImgWithPicture

func (p *Pixbooster) WrapImgWithPicture(n *html.Node)

type WebpConfig

type WebpConfig struct {
	Quality  int
	Lossless bool
	Exact    bool
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL