Support creating thumbnails using the avif command

This commit is contained in:
Trevor Slocum 2021-05-12 14:49:21 -07:00
parent 442e948cec
commit 6b88f0cd4d
8 changed files with 53 additions and 19 deletions

View File

@ -1,4 +1,4 @@
# Should contain src/github.com/Kagami/go-avif
# Should contain src/github.com/kagami/go-avif
export GOPATH = $(PWD)/../../../..
all: build

View File

@ -1,8 +1,8 @@
# go-avif [![Build Status](https://travis-ci.org/Kagami/go-avif.svg?branch=master)](https://travis-ci.org/Kagami/go-avif) [![GoDoc](https://godoc.org/github.com/Kagami/go-avif?status.svg)](https://godoc.org/github.com/Kagami/go-avif)
# go-avif [![Build Status](https://travis-ci.org/kagami/go-avif.svg?branch=master)](https://travis-ci.org/kagami/go-avif) [![GoDoc](https://godoc.org/github.com/kagami/go-avif?status.svg)](https://godoc.org/github.com/kagami/go-avif)
go-avif implements
AVIF ([AV1 Still Image File Format](https://aomediacodec.github.io/av1-avif/))
encoder for Go using libaom, the [high quality](https://github.com/Kagami/av1-bench)
encoder for Go using libaom, the [high quality](https://github.com/kagami/av1-bench)
AV1 codec.
## Requirements
@ -18,16 +18,16 @@ sudo apt-get install libaom-dev
To use go-avif in your Go code:
```go
import "github.com/Kagami/go-avif"
import "github.com/kagami/go-avif"
```
To install go-avif in your $GOPATH:
```bash
go get github.com/Kagami/go-avif
go get github.com/kagami/go-avif
```
For further details see [GoDoc documentation](https://godoc.org/github.com/Kagami/go-avif).
For further details see [GoDoc documentation](https://godoc.org/github.com/kagami/go-avif).
## Example
@ -40,7 +40,7 @@ import (
"log"
"os"
"github.com/Kagami/go-avif"
"github.com/kagami/go-avif"
)
func main() {
@ -81,7 +81,7 @@ PNG files to AVIF:
```bash
# Compile and put avif binary to $GOPATH/bin
go get github.com/Kagami/go-avif/...
go get github.com/kagami/go-avif/...
# Encode JPEG to AVIF with default settings
avif -e cat.jpg -o kitty.avif
@ -92,12 +92,15 @@ avif -e dog.png -o doggy.avif --best -q 15
# Lossless encoding
avif -e pig.png -o piggy.avif --lossless
# Create thumbnail
avif -e horse.png -o horsey.avif --thumb=640:480
# Show help
avif -h
```
Static 64-bit builds for Windows, macOS and Linux are available at
[releases page](https://github.com/Kagami/go-avif/releases). They include
[releases page](https://github.com/kagami/go-avif/releases). They include
latest libaom from git at the moment of build.
## Display

View File

@ -55,6 +55,7 @@ func (e OptionsError) Error() string {
// An EncoderError reports that the encoder error has occured.
type EncoderError int
// ToString returns the string representation of an EncoderError.
func (e EncoderError) ToString() string {
switch e {
case C.AVIF_ERROR_GENERAL:

View File

@ -1,19 +1,23 @@
package main
import (
"errors"
"fmt"
"image"
_ "image/jpeg"
_ "image/png"
"io"
"os"
"strconv"
"strings"
"github.com/Kagami/go-avif"
"github.com/docopt/docopt-go"
"github.com/kagami/go-avif"
"github.com/nfnt/resize"
)
const VERSION = "0.0.0"
const USAGE = `
const version = "0.0.0"
const usage = `
Usage: avif [options] -e src_filename -o dst_filename
AVIF encoder
@ -23,6 +27,7 @@ Options:
-V, --version Display version number
-e <src>, --encode=<src> Source filename
-o <dst>, --output=<dst> Destination filename
-b <w:h>, --thumb=<w:h> Maximum image dimensions
-q <qp>, --quality=<qp> Compression level (0..63), [default: 25]
-s <spd>, --speed=<spd> Compression speed (0..8), [default: 4]
-t <td>, --threads=<td> Number of threads (0..64, 0 for all available cores), [default: 0]
@ -34,6 +39,7 @@ Options:
type config struct {
Encode string
Output string
Thumb string
Quality int
Speed int
Threads int
@ -58,7 +64,7 @@ func check(cond bool, errStr string) {
func main() {
var conf config
opts, err := docopt.ParseArgs(USAGE, nil, VERSION)
opts, err := docopt.ParseArgs(usage, nil, version)
checkErr(err)
err = opts.Bind(&conf)
checkErr(err)
@ -103,6 +109,19 @@ func main() {
img, _, err := image.Decode(src)
checkErr(err)
if conf.Thumb != "" {
split := strings.Split(conf.Thumb, ":")
if len(split) != 2 {
checkErr(errors.New("failed to create thumbnail: invalid dimensions, must be in w:h format"))
}
w, err := strconv.Atoi(split[0])
checkErr(err)
h, err := strconv.Atoi(split[1])
checkErr(err)
img = resize.Thumbnail(uint(w), uint(h), img, resize.Lanczos3)
}
err = avif.Encode(dst, img, &avifOpts)
checkErr(err)
}

View File

@ -6,7 +6,7 @@ import (
"log"
"os"
"github.com/Kagami/go-avif"
"github.com/kagami/go-avif"
)
const usageHelp = "Usage: %s src.jpg dst.avif"

8
go.mod Normal file
View File

@ -0,0 +1,8 @@
module github.com/kagami/go-avif
go 1.16
require (
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
)

4
go.sum Normal file
View File

@ -0,0 +1,4 @@
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815 h1:bWDMxwH3px2JBh6AyO7hdCn/PkvCZXii8TGj7sbtEbQ=
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=

9
mp4.go
View File

@ -41,9 +41,8 @@ func ulen(s string) uint32 {
func bflag(b bool, pos uint8) uint8 {
if b {
return 1 << (pos - 1)
} else {
return 0
}
return 0
}
func writeAll(w io.Writer, writers ...io.WriterTo) (err error) {
@ -744,7 +743,7 @@ func muxFrame(w io.Writer, m image.Image, subsampling image.YCbCrSubsampleRatio,
lengthSize: 4,
baseOffsetSize: 4,
items: []boxILOCItem{
boxILOCItem{
{
itemID: 1,
extents: []boxILOCItemExtent{{}},
},
@ -752,7 +751,7 @@ func muxFrame(w io.Writer, m image.Image, subsampling image.YCbCrSubsampleRatio,
},
itemInfos: boxIINF{
itemInfos: []boxINFEv2{
boxINFEv2{
{
itemID: 1,
itemType: itemTypeAV01,
itemName: "Image",
@ -776,7 +775,7 @@ func muxFrame(w io.Writer, m image.Image, subsampling image.YCbCrSubsampleRatio,
},
association: boxIPMA{
entries: []boxIPMAAssociation{
boxIPMAAssociation{
{
itemID: 1,
props: []boxIPMAAssociationProperty{
{false, 1}, // non-essential width/height