Merge branch 'release/0.0.2'

This commit is contained in:
Ralph Slooten 2019-08-24 23:31:58 +12:00
commit ee6aa69087
5 changed files with 72 additions and 43 deletions

View File

@ -1,5 +1,10 @@
# Changelog # Changelog
## [dev]
- Switch to [pflag](https://github.com/spf13/pflag) for better flag management
## [0.0.1] ## [0.0.1]
- Initial release - Initial release

View File

@ -6,7 +6,7 @@ build = echo "\n\nBuilding $(1)-$(2)" && GOOS=$(1) GOARCH=$(2) go build ${LDFLAG
&& bzip2 dist/goptimize_${VERSION}_$(1)_$(2) && bzip2 dist/goptimize_${VERSION}_$(1)_$(2)
goptimize: *.go goptimize: *.go
go get github.com/disintegration/imaging go get github.com/disintegration/imaging golang.org/x/image/bmp golang.org/x/image/tiff github.com/axllent/gitrel github.com/spf13/pflag
go build ${LDFLAGS} -o goptimize go build ${LDFLAGS} -o goptimize
rm -rf /tmp/go-* rm -rf /tmp/go-*
@ -16,6 +16,7 @@ clean:
release: release:
mkdir -p dist mkdir -p dist
rm -f dist/goptimize_${VERSION}_* rm -f dist/goptimize_${VERSION}_*
go get github.com/disintegration/imaging golang.org/x/image/bmp golang.org/x/image/tiff github.com/axllent/gitrel github.com/spf13/pflag
$(call build,linux,amd64) $(call build,linux,amd64)
$(call build,linux,386) $(call build,linux,386)
$(call build,linux,arm) $(call build,linux,arm)

View File

@ -1,8 +1,8 @@
# Goptimizer - downscales and optimizes images # Goptimizer - downscales and optimizes images
Goptimizer is a commandline utility written in Golang. It downscales and optimize existing images JPEG, PNG and Gif files. Goptimizer is a commandline utility written in Golang. It downscales and optimizes JPEG, PNG and Gif files.
Image downscaling is done within Goptimize (`-m <width>x<height>`, see [Usage](#usage-options)), however optimization is done using the following additional tools (if they are installed): Image downscaling/rotation is done within goptimize (`-m <width>x<height>`, see [Usage](#usage-options)), however optimization is done using the following additional tools (if they are installed):
- jpegoptim - jpegoptim
- jpegtran (`libjpeg-turbo-progs`) - jpegtran (`libjpeg-turbo-progs`)
@ -28,23 +28,18 @@ It will also preserve (by default) the file's original modification times (`-p=f
Usage: ./goptimize [options] <images> Usage: ./goptimize [options] <images>
Options: Options:
-gifsicle string -q, --quality int quality, JPEG only (default 75)
gifsicle binary (default "gifsicle") -m, --max string downscale to a maximum width & height in pixels (<width>x<height>)
-jpegoptim string -o, --out string output directory (default overwrites original)
jpegoptim binary (default "jpegoptim") -p, --preserve preserve file modification times (default true)
-jpegtran string -u, --update update to latest release
jpegtran binary (default "jpegtran") -v, --version show version number
-m string -h, --help show help
downscale to a maximum width & height in pixels (<width>x<height>) --jpegtran string jpegtran binary (default "jpegtran")
-o string --jpegoptim string jpegoptim binary (default "jpegoptim")
output directory (default overwrites original) --gifsicle string gifsicle binary (default "gifsicle")
-optipng string --pngquant string pngquant binary (default "pngquant")
optipng binary (default "optipng") --optipng string optipng binary (default "optipng")
-p preserve file modification times (default true)
-pngquant string
pngquant binary (default "pngquant")
-q int
quality - JPEG only (default 75)
``` ```
@ -54,3 +49,19 @@ Options:
- `./goptimize -m 800x800 *` - optimize and downscale all image files to a maximum size of 800x800px - `./goptimize -m 800x800 *` - optimize and downscale all image files to a maximum size of 800x800px
- `./goptimize -m 1200x0 image.jpg` - optimize and downscale a JPG file to a maximum size of width of 1200px - `./goptimize -m 1200x0 image.jpg` - optimize and downscale a JPG file to a maximum size of width of 1200px
- `./goptimize -o out/ image.jpg` - optimize a JPG file and save it to `out/` - `./goptimize -o out/ image.jpg` - optimize a JPG file and save it to `out/`
## Install
Download the appropriate binary from the [releases](https://github.com/axllent/goptimize/releases/latest), or if you have golang installed
```
go get github.com/axllent/goptimize
```
## TODO
Some ideas for the future:
- Dry run
- Option to copy exif data (how?)

View File

@ -32,7 +32,7 @@ func Goptimize(file string) {
return return
} }
// open original, rotate if neccesary // open original, rotate if necessary
src, err := imaging.Open(file, imaging.AutoOrientation(true)) src, err := imaging.Open(file, imaging.AutoOrientation(true))
if err != nil { if err != nil {
@ -116,19 +116,19 @@ func Goptimize(file string) {
if format.String() == "JPEG" { if format.String() == "JPEG" {
// run one or the other, running both has no advantage // run one or the other, running both has no advantage
if jpegtran != "" { if jpegtran != "" {
RunOptimiser(tmpFilename, true, jpegtran, "-optimize", "-outfile") RunOptimizer(tmpFilename, true, jpegtran, "-optimize", "-outfile")
} else if jpegoptim != "" { } else if jpegoptim != "" {
RunOptimiser(tmpFilename, false, jpegoptim, "-f", "-s", "-o") RunOptimizer(tmpFilename, false, jpegoptim, "-f", "-s", "-o")
} }
} else if format.String() == "PNG" { } else if format.String() == "PNG" {
if pngquant != "" { if pngquant != "" {
RunOptimiser(tmpFilename, true, pngquant, "-f", "--output") RunOptimizer(tmpFilename, true, pngquant, "-f", "--output")
} }
if optipng != "" { if optipng != "" {
RunOptimiser(tmpFilename, true, optipng, "-out") RunOptimizer(tmpFilename, true, optipng, "-out")
} }
} else if format.String() == "GIF" && gifsicle != "" { } else if format.String() == "GIF" && gifsicle != "" {
RunOptimiser(tmpFilename, true, gifsicle, "-o") RunOptimizer(tmpFilename, true, gifsicle, "-o")
} }
// re-open modified temporary file // re-open modified temporary file
@ -166,7 +166,7 @@ func Goptimize(file string) {
defer out.Close() defer out.Close()
if _, err := io.Copy(out, tmpFile); err != nil { if _, err := io.Copy(out, tmpFile); err != nil {
fmt.Printf("Error ovewriting original file: %v\n", err) fmt.Printf("Error overwriting original file: %v\n", err)
return return
} }
@ -215,9 +215,9 @@ func Goptimize(file string) {
} }
// RunOptimiser will run the specified command on a copy of the temporary file, // RunOptimizer will run the specified command on a copy of the temporary file,
// and overwrite it if the output is smaller than the original // and overwrite it if the output is smaller than the original
func RunOptimiser(src string, outFileArg bool, args ...string) { func RunOptimizer(src string, outFileArg bool, args ...string) {
// create a new temp file // create a new temp file
tmpFile, err := ioutil.TempFile(os.TempDir(), "Goptimized-") tmpFile, err := ioutil.TempFile(os.TempDir(), "Goptimized-")

40
main.go
View File

@ -1,7 +1,6 @@
package main package main
import ( import (
"flag"
"fmt" "fmt"
"os" "os"
"os/exec" "os/exec"
@ -9,6 +8,7 @@ import (
"strconv" "strconv"
"github.com/axllent/gitrel" "github.com/axllent/gitrel"
"github.com/spf13/pflag"
) )
var ( var (
@ -26,11 +26,15 @@ var (
) )
func main() { func main() {
// set up new flag instance
flag := pflag.NewFlagSet(os.Args[0], pflag.ExitOnError)
// set the default help // set the default help
flag.Usage = func() { flag.Usage = func() {
fmt.Println("Goptimize - downscales and optimizes images") fmt.Println("Goptimize - downscales and optimizes images")
fmt.Printf("\nUsage: %s [options] <images>\n", os.Args[0]) fmt.Printf("\nUsage: %s [options] <images>\n", os.Args[0])
fmt.Println("\nOptions:") fmt.Println("\nOptions:")
flag.SortFlags = false
flag.PrintDefaults() flag.PrintDefaults()
fmt.Println("\nExamples:") fmt.Println("\nExamples:")
fmt.Printf(" %s image.png\n", os.Args[0]) fmt.Printf(" %s image.png\n", os.Args[0])
@ -47,24 +51,27 @@ func main() {
} }
var maxSizes string var maxSizes string
var update, showversion bool var update, showversion, showhelp bool
flag.IntVar(&quality, "q", 75, "quality - JPEG only") flag.IntVarP(&quality, "quality", "q", 75, "quality, JPEG only")
flag.StringVar(&outputDir, "o", "", "output directory (default overwrites original)") flag.StringVarP(&maxSizes, "max", "m", "", "downscale to a maximum width & height in pixels (<width>x<height>)")
flag.BoolVar(&preserveModTimes, "p", true, "preserve file modification times") flag.StringVarP(&outputDir, "out", "o", "", "output directory (default overwrites original)")
flag.StringVar(&maxSizes, "m", "", "downscale to a maximum width & height in pixels (<width>x<height>)") flag.BoolVarP(&preserveModTimes, "preserve", "p", true, "preserve file modification times")
flag.BoolVar(&update, "u", false, "update to latest release") flag.BoolVarP(&update, "update", "u", false, "update to latest release")
flag.BoolVar(&showversion, "v", false, "show version number") flag.BoolVarP(&showversion, "version", "v", false, "show version number")
flag.BoolVarP(&showhelp, "help", "h", false, "show help")
// third-party optimizers // third-party optimizers
flag.StringVar(&gifsicle, "gifsicle", "gifsicle", "gifsicle binary")
flag.StringVar(&jpegoptim, "jpegoptim", "jpegoptim", "jpegoptim binary")
flag.StringVar(&jpegtran, "jpegtran", "jpegtran", "jpegtran binary") flag.StringVar(&jpegtran, "jpegtran", "jpegtran", "jpegtran binary")
flag.StringVar(&optipng, "optipng", "optipng", "optipng binary") flag.StringVar(&jpegoptim, "jpegoptim", "jpegoptim", "jpegoptim binary")
flag.StringVar(&gifsicle, "gifsicle", "gifsicle", "gifsicle binary")
flag.StringVar(&pngquant, "pngquant", "pngquant", "pngquant binary") flag.StringVar(&pngquant, "pngquant", "pngquant", "pngquant binary")
flag.StringVar(&optipng, "optipng", "optipng", "optipng binary")
// parse flags flag.SortFlags = false
flag.Parse()
// parse args excluding os.Args[0]
flag.Parse(os.Args[1:])
// detect optimizer paths // detect optimizer paths
gifsicle, _ = exec.LookPath(gifsicle) gifsicle, _ = exec.LookPath(gifsicle)
@ -73,6 +80,11 @@ func main() {
optipng, _ = exec.LookPath(optipng) optipng, _ = exec.LookPath(optipng)
pngquant, _ = exec.LookPath(pngquant) pngquant, _ = exec.LookPath(pngquant)
if showhelp {
flag.Usage()
os.Exit(1)
}
if showversion { if showversion {
fmt.Println(fmt.Sprintf("Version: %s", version)) fmt.Println(fmt.Sprintf("Version: %s", version))
latest, _, _, err := gitrel.Latest("axllent/goptimize", "goptimize") latest, _, _, err := gitrel.Latest("axllent/goptimize", "goptimize")
@ -88,7 +100,7 @@ func main() {
fmt.Println(err) fmt.Println(err)
os.Exit(1) os.Exit(1)
} }
fmt.Printf("Updated %s to version %s", os.Args[0], rel) fmt.Printf("Updated %s to version %s\n", os.Args[0], rel)
return return
} }