downsize

Reduces an image to a specified file size in bytes.
Also command line tool available.
Installation
$ go get -u github.com/lelenanam/downsize
Usage
import "github.com/lelenanam/downsize"
The downsize
package provides a function downsize.Encode
:
func Encode(w io.Writer, m image.Image, o *Options) error
This function:
- takes any image type that implements
image.Image
interface as an input m
- reduces an image's dimensions to achieve a specified file size
Options.Size
in bytes
- writes result Image
m
to writer w
with the given options
- default parameters are used if a
nil
*Options
is passed
// Options are the encoding parameters.
type Options struct {
// Size is desired output file size in bytes
Size int
// Format is image format to encode
Format string
// JpegOptions are the options for jpeg format
JpegOptions *jpeg.Options
// GifOptions are the options for gif format
GifOptions *gif.Options
}
By default an image encodes with jpeg
format and with the quality DefaultQuality = 80
.
All metadata is stripped after encoding.
const DefaultQuality = 80
var defaultFormat = "jpeg"
var defaultJpegOptions = &jpeg.Options{Quality: DefaultQuality}
var defaultOptions = &Options{Format: defaultFormat, JpegOptions: defaultJpegOptions}
Example
package main
import (
"image"
_ "image/gif"
_ "image/jpeg"
_ "image/png"
"log"
"os"
"github.com/lelenanam/downsize"
)
func main() {
file, err := os.Open("img.png")
if err != nil {
log.Fatal(err)
}
defer func() {
if err := file.Close(); err != nil {
log.Println("Cannot close input file: ", err)
}
}()
img, format, err := image.Decode(file)
if err != nil {
log.Fatalf("Error: %v, cannot decode file %v", err, file.Name())
}
out, err := os.Create("resized.png")
if err != nil {
log.Fatal(err)
}
defer func() {
if err := out.Close(); err != nil {
log.Println("Cannot close output file: ", err)
}
}()
opt := &downsize.Options{Size: 1048576, Format: format}
if err = downsize.Encode(out, img, opt); err != nil {
log.Fatalf("Error: %v, cannot downsize image to size: %v", err, opt.Size)
}
}
Sample
The original jpeg image 2.4 MB
:

Downsize to 200 KB
, png
format and default quality for result image:
opt := &downsize.Options{Size: 204800, Format: "png"}
err = downsize.Encode(out, img, opt)
Resized result 200 KB
:

Downsize to 200 KB
, jpeg
format and default quality for result image:
opt := &downsize.Options{Size: 204800, Format: "jpeg"}
err = downsize.Encode(out, img, opt)
Resized result 200 KB
:

Downsize to 200 KB
, jpeg
format and quality 50
for result image:
opt := &downsize.Options{Size: 204800, Format: "jpeg", JpegOptions: &jpeg.Options{Quality: 50}}
err = downsize.Encode(out, img, opt)
Resized result 200 KB
, quality 50
:

The original image 3.4 MB
:

Downsize to 100 KB
, auto determine format and default quality for result image:
opt := &downsize.Options{Size: 102400}
err = downsize.Encode(out, img, opt)
Resized result 100 KB
:

Downsize to 100 KB
, auto determine format and quality 50
for result image:
opt := &downsize.Options{Size: 102400, JpegOptions: &jpeg.Options{Quality: 50}}
err = downsize.Encode(out, img, opt)
Resized result 100 KB
, quality 50
:

Downsize to 50 KB
, auto determine format and default duality for result image:
opt := &downsize.Options{Size: 51200}
err = downsize.Encode(out, img, opt)
Resized result 50 KB
:

License
MIT License