summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/disintegration/imaging/helpers.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/disintegration/imaging/helpers.go')
-rw-r--r--vendor/github.com/disintegration/imaging/helpers.go134
1 files changed, 107 insertions, 27 deletions
diff --git a/vendor/github.com/disintegration/imaging/helpers.go b/vendor/github.com/disintegration/imaging/helpers.go
index d4e73f120..7193e473c 100644
--- a/vendor/github.com/disintegration/imaging/helpers.go
+++ b/vendor/github.com/disintegration/imaging/helpers.go
@@ -1,15 +1,10 @@
-// Package imaging provides basic image manipulation functions (resize, rotate, flip, crop, etc.).
-// This package is based on the standard Go image package and works best along with it.
-//
-// Image manipulation functions provided by the package take any image type
-// that implements `image.Image` interface as an input, and return a new image of
-// `*image.NRGBA` type (32bit RGBA colors, not premultiplied by alpha).
package imaging
import (
"errors"
"image"
"image/color"
+ "image/draw"
"image/gif"
"image/jpeg"
"image/png"
@@ -56,32 +51,48 @@ var (
ErrUnsupportedFormat = errors.New("imaging: unsupported image format")
)
+type fileSystem interface {
+ Create(string) (io.WriteCloser, error)
+ Open(string) (io.ReadCloser, error)
+}
+
+type localFS struct{}
+
+func (localFS) Create(name string) (io.WriteCloser, error) { return os.Create(name) }
+func (localFS) Open(name string) (io.ReadCloser, error) { return os.Open(name) }
+
+var fs fileSystem = localFS{}
+
// Decode reads an image from r.
func Decode(r io.Reader) (image.Image, error) {
img, _, err := image.Decode(r)
- if err != nil {
- return nil, err
- }
- return toNRGBA(img), nil
+ return img, err
}
// Open loads an image from file
func Open(filename string) (image.Image, error) {
- file, err := os.Open(filename)
+ file, err := fs.Open(filename)
if err != nil {
return nil, err
}
defer file.Close()
- img, err := Decode(file)
- return img, err
+ return Decode(file)
}
type encodeConfig struct {
- jpegQuality int
+ jpegQuality int
+ gifNumColors int
+ gifQuantizer draw.Quantizer
+ gifDrawer draw.Drawer
+ pngCompressionLevel png.CompressionLevel
}
var defaultEncodeConfig = encodeConfig{
- jpegQuality: 95,
+ jpegQuality: 95,
+ gifNumColors: 256,
+ gifQuantizer: nil,
+ gifDrawer: nil,
+ pngCompressionLevel: png.DefaultCompression,
}
// EncodeOption sets an optional parameter for the Encode and Save functions.
@@ -95,6 +106,38 @@ func JPEGQuality(quality int) EncodeOption {
}
}
+// GIFNumColors returns an EncodeOption that sets the maximum number of colors
+// used in the GIF-encoded image. It ranges from 1 to 256. Default is 256.
+func GIFNumColors(numColors int) EncodeOption {
+ return func(c *encodeConfig) {
+ c.gifNumColors = numColors
+ }
+}
+
+// GIFQuantizer returns an EncodeOption that sets the quantizer that is used to produce
+// a palette of the GIF-encoded image.
+func GIFQuantizer(quantizer draw.Quantizer) EncodeOption {
+ return func(c *encodeConfig) {
+ c.gifQuantizer = quantizer
+ }
+}
+
+// GIFDrawer returns an EncodeOption that sets the drawer that is used to convert
+// the source image to the desired palette of the GIF-encoded image.
+func GIFDrawer(drawer draw.Drawer) EncodeOption {
+ return func(c *encodeConfig) {
+ c.gifDrawer = drawer
+ }
+}
+
+// PNGCompressionLevel returns an EncodeOption that sets the compression level
+// of the PNG-encoded image. Default is png.DefaultCompression.
+func PNGCompressionLevel(level png.CompressionLevel) EncodeOption {
+ return func(c *encodeConfig) {
+ c.pngCompressionLevel = level
+ }
+}
+
// Encode writes the image img to w in the specified format (JPEG, PNG, GIF, TIFF or BMP).
func Encode(w io.Writer, img image.Image, format Format, opts ...EncodeOption) error {
cfg := defaultEncodeConfig
@@ -122,13 +165,22 @@ func Encode(w io.Writer, img image.Image, format Format, opts ...EncodeOption) e
}
case PNG:
- err = png.Encode(w, img)
+ enc := png.Encoder{CompressionLevel: cfg.pngCompressionLevel}
+ err = enc.Encode(w, img)
+
case GIF:
- err = gif.Encode(w, img, &gif.Options{NumColors: 256})
+ err = gif.Encode(w, img, &gif.Options{
+ NumColors: cfg.gifNumColors,
+ Quantizer: cfg.gifQuantizer,
+ Drawer: cfg.gifDrawer,
+ })
+
case TIFF:
err = tiff.Encode(w, img, &tiff.Options{Compression: tiff.Deflate, Predictor: true})
+
case BMP:
err = bmp.Encode(w, img)
+
default:
err = ErrUnsupportedFormat
}
@@ -163,11 +215,17 @@ func Save(img image.Image, filename string, opts ...EncodeOption) (err error) {
return ErrUnsupportedFormat
}
- file, err := os.Create(filename)
+ file, err := fs.Create(filename)
if err != nil {
return err
}
- defer file.Close()
+
+ defer func() {
+ cerr := file.Close()
+ if err == nil {
+ err = cerr
+ }
+ }()
return Encode(file, img, f, opts...)
}
@@ -185,16 +243,38 @@ func New(width, height int, fillColor color.Color) *image.NRGBA {
return dst
}
- cs := []uint8{c.R, c.G, c.B, c.A}
-
- // fill the first row
+ // Fill the first row.
+ i := 0
for x := 0; x < width; x++ {
- copy(dst.Pix[x*4:(x+1)*4], cs)
- }
- // copy the first row to other rows
- for y := 1; y < height; y++ {
- copy(dst.Pix[y*dst.Stride:y*dst.Stride+width*4], dst.Pix[0:width*4])
+ dst.Pix[i+0] = c.R
+ dst.Pix[i+1] = c.G
+ dst.Pix[i+2] = c.B
+ dst.Pix[i+3] = c.A
+ i += 4
}
+ // Copy the first row to other rows.
+ size := width * 4
+ parallel(1, height, func(ys <-chan int) {
+ for y := range ys {
+ i = y * dst.Stride
+ copy(dst.Pix[i:i+size], dst.Pix[0:size])
+ }
+ })
+
+ return dst
+}
+
+// Clone returns a copy of the given image.
+func Clone(img image.Image) *image.NRGBA {
+ src := newScanner(img)
+ dst := image.NewNRGBA(image.Rect(0, 0, src.w, src.h))
+ size := src.w * 4
+ parallel(0, src.h, func(ys <-chan int) {
+ for y := range ys {
+ i := y * dst.Stride
+ src.scan(0, y, src.w, y+1, dst.Pix[i:i+size])
+ }
+ })
return dst
}