Support creating thumbnails using the avif command
This commit is contained in:
parent
442e948cec
commit
6b88f0cd4d
2
Makefile
2
Makefile
|
@ -1,4 +1,4 @@
|
||||||
# Should contain src/github.com/Kagami/go-avif
|
# Should contain src/github.com/kagami/go-avif
|
||||||
export GOPATH = $(PWD)/../../../..
|
export GOPATH = $(PWD)/../../../..
|
||||||
|
|
||||||
all: build
|
all: build
|
||||||
|
|
19
README.md
19
README.md
|
@ -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
|
go-avif implements
|
||||||
AVIF ([AV1 Still Image File Format](https://aomediacodec.github.io/av1-avif/))
|
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.
|
AV1 codec.
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
@ -18,16 +18,16 @@ sudo apt-get install libaom-dev
|
||||||
To use go-avif in your Go code:
|
To use go-avif in your Go code:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import "github.com/Kagami/go-avif"
|
import "github.com/kagami/go-avif"
|
||||||
```
|
```
|
||||||
|
|
||||||
To install go-avif in your $GOPATH:
|
To install go-avif in your $GOPATH:
|
||||||
|
|
||||||
```bash
|
```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
|
## Example
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/Kagami/go-avif"
|
"github.com/kagami/go-avif"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -81,7 +81,7 @@ PNG files to AVIF:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Compile and put avif binary to $GOPATH/bin
|
# 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
|
# Encode JPEG to AVIF with default settings
|
||||||
avif -e cat.jpg -o kitty.avif
|
avif -e cat.jpg -o kitty.avif
|
||||||
|
@ -92,12 +92,15 @@ avif -e dog.png -o doggy.avif --best -q 15
|
||||||
# Lossless encoding
|
# Lossless encoding
|
||||||
avif -e pig.png -o piggy.avif --lossless
|
avif -e pig.png -o piggy.avif --lossless
|
||||||
|
|
||||||
|
# Create thumbnail
|
||||||
|
avif -e horse.png -o horsey.avif --thumb=640:480
|
||||||
|
|
||||||
# Show help
|
# Show help
|
||||||
avif -h
|
avif -h
|
||||||
```
|
```
|
||||||
|
|
||||||
Static 64-bit builds for Windows, macOS and Linux are available at
|
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.
|
latest libaom from git at the moment of build.
|
||||||
|
|
||||||
## Display
|
## Display
|
||||||
|
|
1
avif.go
1
avif.go
|
@ -55,6 +55,7 @@ func (e OptionsError) Error() string {
|
||||||
// An EncoderError reports that the encoder error has occured.
|
// An EncoderError reports that the encoder error has occured.
|
||||||
type EncoderError int
|
type EncoderError int
|
||||||
|
|
||||||
|
// ToString returns the string representation of an EncoderError.
|
||||||
func (e EncoderError) ToString() string {
|
func (e EncoderError) ToString() string {
|
||||||
switch e {
|
switch e {
|
||||||
case C.AVIF_ERROR_GENERAL:
|
case C.AVIF_ERROR_GENERAL:
|
||||||
|
|
|
@ -1,19 +1,23 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
_ "image/jpeg"
|
_ "image/jpeg"
|
||||||
_ "image/png"
|
_ "image/png"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/Kagami/go-avif"
|
|
||||||
"github.com/docopt/docopt-go"
|
"github.com/docopt/docopt-go"
|
||||||
|
"github.com/kagami/go-avif"
|
||||||
|
"github.com/nfnt/resize"
|
||||||
)
|
)
|
||||||
|
|
||||||
const VERSION = "0.0.0"
|
const version = "0.0.0"
|
||||||
const USAGE = `
|
const usage = `
|
||||||
Usage: avif [options] -e src_filename -o dst_filename
|
Usage: avif [options] -e src_filename -o dst_filename
|
||||||
|
|
||||||
AVIF encoder
|
AVIF encoder
|
||||||
|
@ -23,6 +27,7 @@ Options:
|
||||||
-V, --version Display version number
|
-V, --version Display version number
|
||||||
-e <src>, --encode=<src> Source filename
|
-e <src>, --encode=<src> Source filename
|
||||||
-o <dst>, --output=<dst> Destination 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]
|
-q <qp>, --quality=<qp> Compression level (0..63), [default: 25]
|
||||||
-s <spd>, --speed=<spd> Compression speed (0..8), [default: 4]
|
-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]
|
-t <td>, --threads=<td> Number of threads (0..64, 0 for all available cores), [default: 0]
|
||||||
|
@ -34,6 +39,7 @@ Options:
|
||||||
type config struct {
|
type config struct {
|
||||||
Encode string
|
Encode string
|
||||||
Output string
|
Output string
|
||||||
|
Thumb string
|
||||||
Quality int
|
Quality int
|
||||||
Speed int
|
Speed int
|
||||||
Threads int
|
Threads int
|
||||||
|
@ -58,7 +64,7 @@ func check(cond bool, errStr string) {
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var conf config
|
var conf config
|
||||||
opts, err := docopt.ParseArgs(USAGE, nil, VERSION)
|
opts, err := docopt.ParseArgs(usage, nil, version)
|
||||||
checkErr(err)
|
checkErr(err)
|
||||||
err = opts.Bind(&conf)
|
err = opts.Bind(&conf)
|
||||||
checkErr(err)
|
checkErr(err)
|
||||||
|
@ -103,6 +109,19 @@ func main() {
|
||||||
img, _, err := image.Decode(src)
|
img, _, err := image.Decode(src)
|
||||||
checkErr(err)
|
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)
|
err = avif.Encode(dst, img, &avifOpts)
|
||||||
checkErr(err)
|
checkErr(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/Kagami/go-avif"
|
"github.com/kagami/go-avif"
|
||||||
)
|
)
|
||||||
|
|
||||||
const usageHelp = "Usage: %s src.jpg dst.avif"
|
const usageHelp = "Usage: %s src.jpg dst.avif"
|
||||||
|
|
|
@ -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
|
||||||
|
)
|
|
@ -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
9
mp4.go
|
@ -41,9 +41,8 @@ func ulen(s string) uint32 {
|
||||||
func bflag(b bool, pos uint8) uint8 {
|
func bflag(b bool, pos uint8) uint8 {
|
||||||
if b {
|
if b {
|
||||||
return 1 << (pos - 1)
|
return 1 << (pos - 1)
|
||||||
} else {
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeAll(w io.Writer, writers ...io.WriterTo) (err error) {
|
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,
|
lengthSize: 4,
|
||||||
baseOffsetSize: 4,
|
baseOffsetSize: 4,
|
||||||
items: []boxILOCItem{
|
items: []boxILOCItem{
|
||||||
boxILOCItem{
|
{
|
||||||
itemID: 1,
|
itemID: 1,
|
||||||
extents: []boxILOCItemExtent{{}},
|
extents: []boxILOCItemExtent{{}},
|
||||||
},
|
},
|
||||||
|
@ -752,7 +751,7 @@ func muxFrame(w io.Writer, m image.Image, subsampling image.YCbCrSubsampleRatio,
|
||||||
},
|
},
|
||||||
itemInfos: boxIINF{
|
itemInfos: boxIINF{
|
||||||
itemInfos: []boxINFEv2{
|
itemInfos: []boxINFEv2{
|
||||||
boxINFEv2{
|
{
|
||||||
itemID: 1,
|
itemID: 1,
|
||||||
itemType: itemTypeAV01,
|
itemType: itemTypeAV01,
|
||||||
itemName: "Image",
|
itemName: "Image",
|
||||||
|
@ -776,7 +775,7 @@ func muxFrame(w io.Writer, m image.Image, subsampling image.YCbCrSubsampleRatio,
|
||||||
},
|
},
|
||||||
association: boxIPMA{
|
association: boxIPMA{
|
||||||
entries: []boxIPMAAssociation{
|
entries: []boxIPMAAssociation{
|
||||||
boxIPMAAssociation{
|
{
|
||||||
itemID: 1,
|
itemID: 1,
|
||||||
props: []boxIPMAAssociationProperty{
|
props: []boxIPMAAssociationProperty{
|
||||||
{false, 1}, // non-essential width/height
|
{false, 1}, // non-essential width/height
|
||||||
|
|
Loading…
Reference in New Issue