Upgrading server dependancies (#6215)
1
vendor/github.com/disintegration/imaging/.travis.yml
сгенерированный
поставляемый
@@ -9,6 +9,7 @@ go:
|
||||
- 1.5
|
||||
- 1.6
|
||||
- 1.7
|
||||
- 1.8
|
||||
|
||||
before_install:
|
||||
- go get golang.org/x/tools/cmd/cover
|
||||
|
||||
2
vendor/github.com/disintegration/imaging/LICENSE
сгенерированный
поставляемый
@@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2012-2014 Grigory Dryapak
|
||||
Copyright (c) 2012-2017 Grigory Dryapak
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
181
vendor/github.com/disintegration/imaging/README.md
сгенерированный
поставляемый
@@ -26,17 +26,18 @@ http://godoc.org/github.com/disintegration/imaging
|
||||
A few usage examples can be found below. See the documentation for the full list of supported functions.
|
||||
|
||||
### Image resizing
|
||||
|
||||
```go
|
||||
// resize srcImage to size = 128x128px using the Lanczos filter
|
||||
// Resize srcImage to size = 128x128px using the Lanczos filter.
|
||||
dstImage128 := imaging.Resize(srcImage, 128, 128, imaging.Lanczos)
|
||||
|
||||
// resize srcImage to width = 800px preserving the aspect ratio
|
||||
// Resize srcImage to width = 800px preserving the aspect ratio.
|
||||
dstImage800 := imaging.Resize(srcImage, 800, 0, imaging.Lanczos)
|
||||
|
||||
// scale down srcImage to fit the 800x600px bounding box
|
||||
// Scale down srcImage to fit the 800x600px bounding box.
|
||||
dstImageFit := imaging.Fit(srcImage, 800, 600, imaging.Lanczos)
|
||||
|
||||
// resize and crop the srcImage to fill the 100x100px area
|
||||
// Resize and crop the srcImage to fill the 100x100px area.
|
||||
dstImageFill := imaging.Fill(srcImage, 100, 100, imaging.Center, imaging.Lanczos)
|
||||
```
|
||||
|
||||
@@ -53,146 +54,138 @@ The full list of supported filters: NearestNeighbor, Box, Linear, Hermite, Mitc
|
||||
|
||||
**Resampling filters comparison**
|
||||
|
||||
Original image. Will be resized from 512x512px to 128x128px.
|
||||
The original image.
|
||||
|
||||

|
||||

|
||||
|
||||
Filter | Resize result
|
||||
---|---
|
||||
`imaging.NearestNeighbor` | 
|
||||
`imaging.Box` | 
|
||||
`imaging.Linear` | 
|
||||
`imaging.MitchellNetravali` | 
|
||||
`imaging.CatmullRom` | 
|
||||
`imaging.Gaussian` | 
|
||||
`imaging.Lanczos` | 
|
||||
The same image resized from 512x512px to 128x128px using different resampling filters.
|
||||
From faster (lower quality) to slower (higher quality):
|
||||
|
||||
**Resize functions comparison**
|
||||
Filter | Resize result
|
||||
--------------------------|---------------------------------------------
|
||||
`imaging.NearestNeighbor` | 
|
||||
`imaging.Linear` | 
|
||||
`imaging.CatmullRom` | 
|
||||
`imaging.Lanczos` | 
|
||||
|
||||
Original image:
|
||||
|
||||

|
||||
|
||||
Resize the image to width=100px and height=100px:
|
||||
|
||||
```go
|
||||
dstImage := imaging.Resize(srcImage, 100, 100, imaging.Lanczos)
|
||||
```
|
||||

|
||||
|
||||
Resize the image to width=100px preserving the aspect ratio:
|
||||
|
||||
```go
|
||||
dstImage := imaging.Resize(srcImage, 100, 0, imaging.Lanczos)
|
||||
```
|
||||

|
||||
|
||||
Resize the image to fit the 100x100px boundng box preserving the aspect ratio:
|
||||
|
||||
```go
|
||||
dstImage := imaging.Fit(srcImage, 100, 100, imaging.Lanczos)
|
||||
```
|
||||

|
||||
|
||||
Resize and crop the image with a center anchor point to fill the 100x100px area:
|
||||
|
||||
```go
|
||||
dstImage := imaging.Fill(srcImage, 100, 100, imaging.Center, imaging.Lanczos)
|
||||
```
|
||||

|
||||
|
||||
### Gaussian Blur
|
||||
|
||||
```go
|
||||
dstImage := imaging.Blur(srcImage, 0.5)
|
||||
```
|
||||
|
||||
Sigma parameter allows to control the strength of the blurring effect.
|
||||
|
||||
Original image | Sigma = 0.5 | Sigma = 1.5
|
||||
---|---|---
|
||||
 |  | 
|
||||
Original image | Sigma = 0.5 | Sigma = 1.5
|
||||
-----------------------------------|----------------------------------------|---------------------------------------
|
||||
 |  | 
|
||||
|
||||
### Sharpening
|
||||
|
||||
```go
|
||||
dstImage := imaging.Sharpen(srcImage, 0.5)
|
||||
```
|
||||
|
||||
Uses gaussian function internally. Sigma parameter allows to control the strength of the sharpening effect.
|
||||
`Sharpen` uses gaussian function internally. Sigma parameter allows to control the strength of the sharpening effect.
|
||||
|
||||
Original image | Sigma = 0.5 | Sigma = 1.5
|
||||
---|---|---
|
||||
 |  | 
|
||||
Original image | Sigma = 0.5 | Sigma = 1.5
|
||||
-----------------------------------|-------------------------------------------|------------------------------------------
|
||||
 |  | 
|
||||
|
||||
### Gamma correction
|
||||
|
||||
```go
|
||||
dstImage := imaging.AdjustGamma(srcImage, 0.75)
|
||||
```
|
||||
|
||||
Original image | Gamma = 0.75 | Gamma = 1.25
|
||||
---|---|---
|
||||
 |  | 
|
||||
Original image | Gamma = 0.75 | Gamma = 1.25
|
||||
-----------------------------------|------------------------------------------|-----------------------------------------
|
||||
 |  | 
|
||||
|
||||
### Contrast adjustment
|
||||
|
||||
```go
|
||||
dstImage := imaging.AdjustContrast(srcImage, 20)
|
||||
```
|
||||
|
||||
Original image | Contrast = 20 | Contrast = -20
|
||||
---|---|---
|
||||
 |  | 
|
||||
Original image | Contrast = 10 | Contrast = -10
|
||||
-----------------------------------|--------------------------------------------|-------------------------------------------
|
||||
 |  | 
|
||||
|
||||
### Brightness adjustment
|
||||
|
||||
```go
|
||||
dstImage := imaging.AdjustBrightness(srcImage, 20)
|
||||
```
|
||||
|
||||
Original image | Brightness = 20 | Brightness = -20
|
||||
---|---|---
|
||||
 |  | 
|
||||
Original image | Brightness = 10 | Brightness = -10
|
||||
-----------------------------------|----------------------------------------------|---------------------------------------------
|
||||
 |  | 
|
||||
|
||||
|
||||
### Complete code example
|
||||
Here is the code example that loads several images, makes thumbnails of them
|
||||
and combines them together side-by-side.
|
||||
## Example code
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"image"
|
||||
"image/color"
|
||||
|
||||
"github.com/disintegration/imaging"
|
||||
"image"
|
||||
"image/color"
|
||||
"log"
|
||||
|
||||
"github.com/disintegration/imaging"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Open the test image.
|
||||
src, err := imaging.Open("testdata/lena_512.png")
|
||||
if err != nil {
|
||||
log.Fatalf("Open failed: %v", err)
|
||||
}
|
||||
|
||||
// input files
|
||||
files := []string{"01.jpg", "02.jpg", "03.jpg"}
|
||||
// Crop the original image to 350x350px size using the center anchor.
|
||||
src = imaging.CropAnchor(src, 350, 350, imaging.Center)
|
||||
|
||||
// load images and make 100x100 thumbnails of them
|
||||
var thumbnails []image.Image
|
||||
for _, file := range files {
|
||||
img, err := imaging.Open(file)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
thumb := imaging.Thumbnail(img, 100, 100, imaging.CatmullRom)
|
||||
thumbnails = append(thumbnails, thumb)
|
||||
}
|
||||
// Resize the cropped image to width = 256px preserving the aspect ratio.
|
||||
src = imaging.Resize(src, 256, 0, imaging.Lanczos)
|
||||
|
||||
// create a new blank image
|
||||
dst := imaging.New(100*len(thumbnails), 100, color.NRGBA{0, 0, 0, 0})
|
||||
// Create a blurred version of the image.
|
||||
img1 := imaging.Blur(src, 2)
|
||||
|
||||
// paste thumbnails into the new image side by side
|
||||
for i, thumb := range thumbnails {
|
||||
dst = imaging.Paste(dst, thumb, image.Pt(i*100, 0))
|
||||
}
|
||||
// Create a grayscale version of the image with higher contrast and sharpness.
|
||||
img2 := imaging.Grayscale(src)
|
||||
img2 = imaging.AdjustContrast(img2, 20)
|
||||
img2 = imaging.Sharpen(img2, 2)
|
||||
|
||||
// save the combined image to file
|
||||
err := imaging.Save(dst, "dst.jpg")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Create an inverted version of the image.
|
||||
img3 := imaging.Invert(src)
|
||||
|
||||
// Create an embossed version of the image using a convolution filter.
|
||||
img4 := imaging.Convolve3x3(
|
||||
src,
|
||||
[9]float64{
|
||||
-1, -1, 0,
|
||||
-1, 1, 1,
|
||||
0, 1, 1,
|
||||
},
|
||||
nil,
|
||||
)
|
||||
|
||||
// Create a new image and paste the four produced images into it.
|
||||
dst := imaging.New(512, 512, color.NRGBA{0, 0, 0, 0})
|
||||
dst = imaging.Paste(dst, img1, image.Pt(0, 0))
|
||||
dst = imaging.Paste(dst, img2, image.Pt(0, 256))
|
||||
dst = imaging.Paste(dst, img3, image.Pt(256, 0))
|
||||
dst = imaging.Paste(dst, img4, image.Pt(256, 256))
|
||||
|
||||
// Save the resulting image using JPEG format.
|
||||
err = imaging.Save(dst, "testdata/out_example.jpg")
|
||||
if err != nil {
|
||||
log.Fatalf("Save failed: %v", err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||

|
||||
60
vendor/github.com/disintegration/imaging/adjust_test.go
сгенерированный
поставляемый
@@ -206,6 +206,26 @@ func TestAdjustContrast(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAdjustContrastGolden(t *testing.T) {
|
||||
src, err := Open("testdata/lena_128.png")
|
||||
if err != nil {
|
||||
t.Errorf("Open: %v", err)
|
||||
}
|
||||
for name, p := range map[string]float64{
|
||||
"out_contrast_m10.png": -10,
|
||||
"out_contrast_p10.png": 10,
|
||||
} {
|
||||
got := AdjustContrast(src, p)
|
||||
want, err := Open("testdata/" + name)
|
||||
if err != nil {
|
||||
t.Errorf("Open: %v", err)
|
||||
}
|
||||
if !compareNRGBA(got, toNRGBA(want), 0) {
|
||||
t.Errorf("resulting image differs from golden: %s", name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAdjustBrightness(t *testing.T) {
|
||||
td := []struct {
|
||||
desc string
|
||||
@@ -333,6 +353,26 @@ func TestAdjustBrightness(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAdjustBrightnessGolden(t *testing.T) {
|
||||
src, err := Open("testdata/lena_128.png")
|
||||
if err != nil {
|
||||
t.Errorf("Open: %v", err)
|
||||
}
|
||||
for name, p := range map[string]float64{
|
||||
"out_brightness_m10.png": -10,
|
||||
"out_brightness_p10.png": 10,
|
||||
} {
|
||||
got := AdjustBrightness(src, p)
|
||||
want, err := Open("testdata/" + name)
|
||||
if err != nil {
|
||||
t.Errorf("Open: %v", err)
|
||||
}
|
||||
if !compareNRGBA(got, toNRGBA(want), 0) {
|
||||
t.Errorf("resulting image differs from golden: %s", name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAdjustGamma(t *testing.T) {
|
||||
td := []struct {
|
||||
desc string
|
||||
@@ -416,6 +456,26 @@ func TestAdjustGamma(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAdjustGammaGolden(t *testing.T) {
|
||||
src, err := Open("testdata/lena_128.png")
|
||||
if err != nil {
|
||||
t.Errorf("Open: %v", err)
|
||||
}
|
||||
for name, g := range map[string]float64{
|
||||
"out_gamma_0.75.png": 0.75,
|
||||
"out_gamma_1.25.png": 1.25,
|
||||
} {
|
||||
got := AdjustGamma(src, g)
|
||||
want, err := Open("testdata/" + name)
|
||||
if err != nil {
|
||||
t.Errorf("Open: %v", err)
|
||||
}
|
||||
if !compareNRGBA(got, toNRGBA(want), 0) {
|
||||
t.Errorf("resulting image differs from golden: %s", name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAdjustSigmoid(t *testing.T) {
|
||||
td := []struct {
|
||||
desc string
|
||||
|
||||
148
vendor/github.com/disintegration/imaging/convolution.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,148 @@
|
||||
package imaging
|
||||
|
||||
import (
|
||||
"image"
|
||||
)
|
||||
|
||||
// ConvolveOptions are convolution parameters.
|
||||
type ConvolveOptions struct {
|
||||
// If Normalize is true the kernel is normalized before convolution.
|
||||
Normalize bool
|
||||
|
||||
// If Abs is true the absolute value of each color channel is taken after convolution.
|
||||
Abs bool
|
||||
|
||||
// Bias is added to each color channel value after convolution.
|
||||
Bias int
|
||||
}
|
||||
|
||||
// Convolve3x3 convolves the image with the specified 3x3 convolution kernel.
|
||||
// Default parameters are used if a nil *ConvolveOptions is passed.
|
||||
func Convolve3x3(img image.Image, kernel [9]float64, options *ConvolveOptions) *image.NRGBA {
|
||||
return convolve(img, kernel[:], options)
|
||||
}
|
||||
|
||||
// Convolve5x5 convolves the image with the specified 5x5 convolution kernel.
|
||||
// Default parameters are used if a nil *ConvolveOptions is passed.
|
||||
func Convolve5x5(img image.Image, kernel [25]float64, options *ConvolveOptions) *image.NRGBA {
|
||||
return convolve(img, kernel[:], options)
|
||||
}
|
||||
|
||||
func convolve(img image.Image, kernel []float64, options *ConvolveOptions) *image.NRGBA {
|
||||
src := toNRGBA(img)
|
||||
w := src.Bounds().Max.X
|
||||
h := src.Bounds().Max.Y
|
||||
dst := image.NewNRGBA(image.Rect(0, 0, w, h))
|
||||
|
||||
if w < 1 || h < 1 {
|
||||
return dst
|
||||
}
|
||||
|
||||
if options == nil {
|
||||
options = &ConvolveOptions{}
|
||||
}
|
||||
|
||||
if options.Normalize {
|
||||
normalizeKernel(kernel)
|
||||
}
|
||||
|
||||
type coef struct {
|
||||
x, y int
|
||||
k float64
|
||||
}
|
||||
var coefs []coef
|
||||
var m int
|
||||
|
||||
switch len(kernel) {
|
||||
case 9:
|
||||
m = 1
|
||||
case 25:
|
||||
m = 2
|
||||
default:
|
||||
return dst
|
||||
}
|
||||
|
||||
i := 0
|
||||
for y := -m; y <= m; y++ {
|
||||
for x := -m; x <= m; x++ {
|
||||
if kernel[i] != 0 {
|
||||
coefs = append(coefs, coef{x: x, y: y, k: kernel[i]})
|
||||
}
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
parallel(h, func(partStart, partEnd int) {
|
||||
for y := partStart; y < partEnd; y++ {
|
||||
for x := 0; x < w; x++ {
|
||||
var r, g, b float64
|
||||
for _, c := range coefs {
|
||||
ix := x + c.x
|
||||
if ix < 0 {
|
||||
ix = 0
|
||||
} else if ix >= w {
|
||||
ix = w - 1
|
||||
}
|
||||
|
||||
iy := y + c.y
|
||||
if iy < 0 {
|
||||
iy = 0
|
||||
} else if iy >= h {
|
||||
iy = h - 1
|
||||
}
|
||||
|
||||
off := iy*src.Stride + ix*4
|
||||
r += float64(src.Pix[off+0]) * c.k
|
||||
g += float64(src.Pix[off+1]) * c.k
|
||||
b += float64(src.Pix[off+2]) * c.k
|
||||
}
|
||||
|
||||
if options.Abs {
|
||||
if r < 0 {
|
||||
r = -r
|
||||
}
|
||||
if g < 0 {
|
||||
g = -g
|
||||
}
|
||||
if b < 0 {
|
||||
b = -b
|
||||
}
|
||||
}
|
||||
|
||||
if options.Bias != 0 {
|
||||
r += float64(options.Bias)
|
||||
g += float64(options.Bias)
|
||||
b += float64(options.Bias)
|
||||
}
|
||||
|
||||
srcOff := y*src.Stride + x*4
|
||||
dstOff := y*dst.Stride + x*4
|
||||
dst.Pix[dstOff+0] = clamp(r)
|
||||
dst.Pix[dstOff+1] = clamp(g)
|
||||
dst.Pix[dstOff+2] = clamp(b)
|
||||
dst.Pix[dstOff+3] = src.Pix[srcOff+3]
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return dst
|
||||
}
|
||||
|
||||
func normalizeKernel(kernel []float64) {
|
||||
var sum, sumpos float64
|
||||
for i := range kernel {
|
||||
sum += kernel[i]
|
||||
if kernel[i] > 0 {
|
||||
sumpos += kernel[i]
|
||||
}
|
||||
}
|
||||
if sum != 0 {
|
||||
for i := range kernel {
|
||||
kernel[i] /= sum
|
||||
}
|
||||
} else if sumpos != 0 {
|
||||
for i := range kernel {
|
||||
kernel[i] /= sumpos
|
||||
}
|
||||
}
|
||||
}
|
||||
275
vendor/github.com/disintegration/imaging/convolution_test.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,275 @@
|
||||
package imaging
|
||||
|
||||
import (
|
||||
"image"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestConvolve3x3(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
src image.Image
|
||||
kernel [9]float64
|
||||
options *ConvolveOptions
|
||||
want *image.NRGBA
|
||||
}{
|
||||
{
|
||||
"Convolve3x3 0x0",
|
||||
&image.NRGBA{
|
||||
Rect: image.Rect(0, 0, 0, 0),
|
||||
Stride: 0,
|
||||
Pix: []uint8{},
|
||||
},
|
||||
[9]float64{
|
||||
0, 0, 0,
|
||||
0, 1, 0,
|
||||
0, 0, 0,
|
||||
},
|
||||
nil,
|
||||
&image.NRGBA{Rect: image.Rect(0, 0, 0, 0)},
|
||||
},
|
||||
{
|
||||
"Convolve3x3 4x4 identity",
|
||||
&image.NRGBA{
|
||||
Rect: image.Rect(-1, -1, 3, 3),
|
||||
Stride: 4 * 4,
|
||||
Pix: []uint8{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
},
|
||||
},
|
||||
[9]float64{
|
||||
0, 0, 0,
|
||||
0, 1, 0,
|
||||
0, 0, 0,
|
||||
},
|
||||
nil,
|
||||
&image.NRGBA{
|
||||
Rect: image.Rect(0, 0, 4, 4),
|
||||
Stride: 4 * 4,
|
||||
Pix: []uint8{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"Convolve3x3 4x4 abs",
|
||||
&image.NRGBA{
|
||||
Rect: image.Rect(-1, -1, 3, 3),
|
||||
Stride: 4 * 4,
|
||||
Pix: []uint8{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
},
|
||||
},
|
||||
[9]float64{
|
||||
0, 0, 0,
|
||||
0, -1, 0,
|
||||
0, 0, 0,
|
||||
},
|
||||
&ConvolveOptions{Abs: true},
|
||||
&image.NRGBA{
|
||||
Rect: image.Rect(0, 0, 4, 4),
|
||||
Stride: 4 * 4,
|
||||
Pix: []uint8{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"Convolve3x3 4x4 bias",
|
||||
&image.NRGBA{
|
||||
Rect: image.Rect(-1, -1, 3, 3),
|
||||
Stride: 4 * 4,
|
||||
Pix: []uint8{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
},
|
||||
},
|
||||
[9]float64{
|
||||
0, 0, 0,
|
||||
0, 1, 0,
|
||||
0, 0, 0,
|
||||
},
|
||||
&ConvolveOptions{Bias: 0x10},
|
||||
&image.NRGBA{
|
||||
Rect: image.Rect(0, 0, 4, 4),
|
||||
Stride: 4 * 4,
|
||||
Pix: []uint8{
|
||||
0x10, 0x11, 0x12, 0x03, 0x14, 0x15, 0x16, 0x07, 0x18, 0x19, 0x1a, 0x0b, 0x1c, 0x1d, 0x1e, 0x0f,
|
||||
0x20, 0x21, 0x22, 0x13, 0x24, 0x25, 0x26, 0x17, 0x28, 0x29, 0x2a, 0x1b, 0x2c, 0x2d, 0x2e, 0x1f,
|
||||
0x30, 0x31, 0x32, 0x23, 0x34, 0x35, 0x36, 0x27, 0x38, 0x39, 0x3a, 0x2b, 0x3c, 0x3d, 0x3e, 0x2f,
|
||||
0x40, 0x41, 0x42, 0x33, 0x44, 0x45, 0x46, 0x37, 0x48, 0x49, 0x4a, 0x3b, 0x4c, 0x4d, 0x4e, 0x3f,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"Convolve3x3 4x4 norm",
|
||||
&image.NRGBA{
|
||||
Rect: image.Rect(-1, -1, 3, 3),
|
||||
Stride: 4 * 4,
|
||||
Pix: []uint8{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
},
|
||||
},
|
||||
[9]float64{
|
||||
1, 1, 1,
|
||||
1, 1, 1,
|
||||
1, 1, 1,
|
||||
},
|
||||
&ConvolveOptions{Normalize: true},
|
||||
&image.NRGBA{
|
||||
Rect: image.Rect(0, 0, 4, 4),
|
||||
Stride: 4 * 4,
|
||||
Pix: []uint8{
|
||||
0x07, 0x08, 0x09, 0x03, 0x09, 0x0a, 0x0b, 0x07, 0x0d, 0x0e, 0x0f, 0x0b, 0x10, 0x11, 0x12, 0x0f,
|
||||
0x11, 0x12, 0x13, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1b, 0x1c, 0x1d, 0x1f,
|
||||
0x21, 0x22, 0x23, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2b, 0x2c, 0x2d, 0x2f,
|
||||
0x2c, 0x2d, 0x2e, 0x33, 0x2f, 0x30, 0x31, 0x37, 0x33, 0x34, 0x35, 0x3b, 0x35, 0x36, 0x37, 0x3f,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"Convolve3x3 3x3 laplacian",
|
||||
&image.NRGBA{
|
||||
Rect: image.Rect(-1, -1, 2, 2),
|
||||
Stride: 3 * 4,
|
||||
Pix: []uint8{
|
||||
0x00, 0x01, 0x01, 0xff, 0x00, 0x01, 0x02, 0xff, 0x00, 0x01, 0x03, 0xff,
|
||||
0x00, 0x01, 0x04, 0xff, 0x10, 0x10, 0x10, 0xff, 0x00, 0x01, 0x05, 0xff,
|
||||
0x00, 0x01, 0x06, 0xff, 0x00, 0x01, 0x07, 0xff, 0x00, 0x01, 0x08, 0xff,
|
||||
},
|
||||
},
|
||||
[9]float64{
|
||||
-1, -1, -1,
|
||||
-1, 8, -1,
|
||||
-1, -1, -1,
|
||||
},
|
||||
nil,
|
||||
&image.NRGBA{
|
||||
Rect: image.Rect(0, 0, 3, 3),
|
||||
Stride: 3 * 4,
|
||||
Pix: []uint8{
|
||||
0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
|
||||
0x00, 0x00, 0x00, 0xff, 0x80, 0x78, 0x5c, 0xff, 0x00, 0x00, 0x00, 0xff,
|
||||
0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
got := Convolve3x3(tc.src, tc.kernel, tc.options)
|
||||
want := tc.want
|
||||
if !compareNRGBA(got, want, 0) {
|
||||
t.Errorf("test [%s] failed: want %#v got %#v", tc.desc, want, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestConvolve5x5(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
src image.Image
|
||||
kernel [25]float64
|
||||
options *ConvolveOptions
|
||||
want *image.NRGBA
|
||||
}{
|
||||
{
|
||||
"Convolve5x5 4x4 translate",
|
||||
&image.NRGBA{
|
||||
Rect: image.Rect(-1, -1, 3, 3),
|
||||
Stride: 4 * 4,
|
||||
Pix: []uint8{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
},
|
||||
},
|
||||
[25]float64{
|
||||
0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 1,
|
||||
},
|
||||
nil,
|
||||
&image.NRGBA{
|
||||
Rect: image.Rect(0, 0, 4, 4),
|
||||
Stride: 4 * 4,
|
||||
Pix: []uint8{
|
||||
0x28, 0x29, 0x2a, 0x03, 0x2c, 0x2d, 0x2e, 0x07, 0x2c, 0x2d, 0x2e, 0x0b, 0x2c, 0x2d, 0x2e, 0x0f,
|
||||
0x38, 0x39, 0x3a, 0x13, 0x3c, 0x3d, 0x3e, 0x17, 0x3c, 0x3d, 0x3e, 0x1b, 0x3c, 0x3d, 0x3e, 0x1f,
|
||||
0x38, 0x39, 0x3a, 0x23, 0x3c, 0x3d, 0x3e, 0x27, 0x3c, 0x3d, 0x3e, 0x2b, 0x3c, 0x3d, 0x3e, 0x2f,
|
||||
0x38, 0x39, 0x3a, 0x33, 0x3c, 0x3d, 0x3e, 0x37, 0x3c, 0x3d, 0x3e, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
got := Convolve5x5(tc.src, tc.kernel, tc.options)
|
||||
want := tc.want
|
||||
if !compareNRGBA(got, want, 0) {
|
||||
t.Errorf("test [%s] failed: want %#v got %#v", tc.desc, want, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkConvolve3x3(b *testing.B) {
|
||||
b.StopTimer()
|
||||
img, err := Open("testdata/lena_512.png")
|
||||
if err != nil {
|
||||
b.Fatalf("Open: %v", err)
|
||||
}
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
Convolve3x3(
|
||||
img,
|
||||
[9]float64{
|
||||
-1, -1, 0,
|
||||
-1, 0, 1,
|
||||
0, 1, 1,
|
||||
},
|
||||
nil,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkConvolve5x5(b *testing.B) {
|
||||
b.StopTimer()
|
||||
img, err := Open("testdata/lena_512.png")
|
||||
if err != nil {
|
||||
b.Fatalf("Open: %v", err)
|
||||
}
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
Convolve5x5(
|
||||
img,
|
||||
[25]float64{
|
||||
-1, -1, -1, -1, 0,
|
||||
-1, -1, -1, 0, 1,
|
||||
-1, -1, 0, 1, 1,
|
||||
-1, 0, 1, 1, 1,
|
||||
0, 1, 1, 1, 1,
|
||||
},
|
||||
nil,
|
||||
)
|
||||
}
|
||||
}
|
||||
36
vendor/github.com/disintegration/imaging/effects.go
сгенерированный
поставляемый
@@ -62,8 +62,7 @@ func blurHorizontal(src *image.NRGBA, kernel []float64) *image.NRGBA {
|
||||
}
|
||||
|
||||
for y := 0; y < height; y++ {
|
||||
|
||||
r, g, b, a := 0.0, 0.0, 0.0, 0.0
|
||||
var r, g, b, a float64
|
||||
for ix := start; ix <= end; ix++ {
|
||||
weight := kernel[absint(x-ix)]
|
||||
i := y*src.Stride + ix*4
|
||||
@@ -74,17 +73,11 @@ func blurHorizontal(src *image.NRGBA, kernel []float64) *image.NRGBA {
|
||||
a += wa
|
||||
}
|
||||
|
||||
r = math.Min(math.Max(r/a, 0.0), 255.0)
|
||||
g = math.Min(math.Max(g/a, 0.0), 255.0)
|
||||
b = math.Min(math.Max(b/a, 0.0), 255.0)
|
||||
a = math.Min(math.Max(a/weightSum, 0.0), 255.0)
|
||||
|
||||
j := y*dst.Stride + x*4
|
||||
dst.Pix[j+0] = uint8(r + 0.5)
|
||||
dst.Pix[j+1] = uint8(g + 0.5)
|
||||
dst.Pix[j+2] = uint8(b + 0.5)
|
||||
dst.Pix[j+3] = uint8(a + 0.5)
|
||||
|
||||
dst.Pix[j+0] = clamp(r / a)
|
||||
dst.Pix[j+1] = clamp(g / a)
|
||||
dst.Pix[j+2] = clamp(b / a)
|
||||
dst.Pix[j+3] = clamp(a / weightSum)
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -117,8 +110,7 @@ func blurVertical(src *image.NRGBA, kernel []float64) *image.NRGBA {
|
||||
}
|
||||
|
||||
for x := 0; x < width; x++ {
|
||||
|
||||
r, g, b, a := 0.0, 0.0, 0.0, 0.0
|
||||
var r, g, b, a float64
|
||||
for iy := start; iy <= end; iy++ {
|
||||
weight := kernel[absint(y-iy)]
|
||||
i := iy*src.Stride + x*4
|
||||
@@ -129,17 +121,11 @@ func blurVertical(src *image.NRGBA, kernel []float64) *image.NRGBA {
|
||||
a += wa
|
||||
}
|
||||
|
||||
r = math.Min(math.Max(r/a, 0.0), 255.0)
|
||||
g = math.Min(math.Max(g/a, 0.0), 255.0)
|
||||
b = math.Min(math.Max(b/a, 0.0), 255.0)
|
||||
a = math.Min(math.Max(a/weightSum, 0.0), 255.0)
|
||||
|
||||
j := y*dst.Stride + x*4
|
||||
dst.Pix[j+0] = uint8(r + 0.5)
|
||||
dst.Pix[j+1] = uint8(g + 0.5)
|
||||
dst.Pix[j+2] = uint8(b + 0.5)
|
||||
dst.Pix[j+3] = uint8(a + 0.5)
|
||||
|
||||
dst.Pix[j+0] = clamp(r / a)
|
||||
dst.Pix[j+1] = clamp(g / a)
|
||||
dst.Pix[j+2] = clamp(b / a)
|
||||
dst.Pix[j+3] = clamp(a / weightSum)
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -173,7 +159,7 @@ func Sharpen(img image.Image, sigma float64) *image.NRGBA {
|
||||
i := y*src.Stride + x*4
|
||||
for j := 0; j < 4; j++ {
|
||||
k := i + j
|
||||
val := int(src.Pix[k]) + (int(src.Pix[k]) - int(blurred.Pix[k]))
|
||||
val := int(src.Pix[k])<<1 - int(blurred.Pix[k])
|
||||
if val < 0 {
|
||||
val = 0
|
||||
} else if val > 255 {
|
||||
|
||||
64
vendor/github.com/disintegration/imaging/effects_test.go
сгенерированный
поставляемый
@@ -88,6 +88,38 @@ func TestBlur(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestBlurGolden(t *testing.T) {
|
||||
src, err := Open("testdata/lena_128.png")
|
||||
if err != nil {
|
||||
t.Errorf("Open: %v", err)
|
||||
}
|
||||
for name, sigma := range map[string]float64{
|
||||
"out_blur_0.5.png": 0.5,
|
||||
"out_blur_1.5.png": 1.5,
|
||||
} {
|
||||
got := Blur(src, sigma)
|
||||
want, err := Open("testdata/" + name)
|
||||
if err != nil {
|
||||
t.Errorf("Open: %v", err)
|
||||
}
|
||||
if !compareNRGBA(got, toNRGBA(want), 0) {
|
||||
t.Errorf("resulting image differs from golden: %s", name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkBlur(b *testing.B) {
|
||||
b.StopTimer()
|
||||
img, err := Open("testdata/lena_512.png")
|
||||
if err != nil {
|
||||
b.Fatalf("Open: %v", err)
|
||||
}
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
Blur(img, 3)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSharpen(t *testing.T) {
|
||||
td := []struct {
|
||||
desc string
|
||||
@@ -188,3 +220,35 @@ func TestSharpen(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSharpenGolden(t *testing.T) {
|
||||
src, err := Open("testdata/lena_128.png")
|
||||
if err != nil {
|
||||
t.Errorf("Open: %v", err)
|
||||
}
|
||||
for name, sigma := range map[string]float64{
|
||||
"out_sharpen_0.5.png": 0.5,
|
||||
"out_sharpen_1.5.png": 1.5,
|
||||
} {
|
||||
got := Sharpen(src, sigma)
|
||||
want, err := Open("testdata/" + name)
|
||||
if err != nil {
|
||||
t.Errorf("Open: %v", err)
|
||||
}
|
||||
if !compareNRGBA(got, toNRGBA(want), 0) {
|
||||
t.Errorf("resulting image differs from golden: %s", name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSharpen(b *testing.B) {
|
||||
b.StopTimer()
|
||||
img, err := Open("testdata/lena_512.png")
|
||||
if err != nil {
|
||||
b.Fatalf("Open: %v", err)
|
||||
}
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
Sharpen(img, 3)
|
||||
}
|
||||
}
|
||||
|
||||
58
vendor/github.com/disintegration/imaging/example_test.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,58 @@
|
||||
package imaging_test
|
||||
|
||||
import (
|
||||
"image"
|
||||
"image/color"
|
||||
"log"
|
||||
|
||||
"github.com/disintegration/imaging"
|
||||
)
|
||||
|
||||
func Example() {
|
||||
// Open the test image.
|
||||
src, err := imaging.Open("testdata/lena_512.png")
|
||||
if err != nil {
|
||||
log.Fatalf("Open failed: %v", err)
|
||||
}
|
||||
|
||||
// Crop the original image to 350x350px size using the center anchor.
|
||||
src = imaging.CropAnchor(src, 350, 350, imaging.Center)
|
||||
|
||||
// Resize the cropped image to width = 256px preserving the aspect ratio.
|
||||
src = imaging.Resize(src, 256, 0, imaging.Lanczos)
|
||||
|
||||
// Create a blurred version of the image.
|
||||
img1 := imaging.Blur(src, 2)
|
||||
|
||||
// Create a grayscale version of the image with higher contrast and sharpness.
|
||||
img2 := imaging.Grayscale(src)
|
||||
img2 = imaging.AdjustContrast(img2, 20)
|
||||
img2 = imaging.Sharpen(img2, 2)
|
||||
|
||||
// Create an inverted version of the image.
|
||||
img3 := imaging.Invert(src)
|
||||
|
||||
// Create an embossed version of the image using a convolution filter.
|
||||
img4 := imaging.Convolve3x3(
|
||||
src,
|
||||
[9]float64{
|
||||
-1, -1, 0,
|
||||
-1, 1, 1,
|
||||
0, 1, 1,
|
||||
},
|
||||
nil,
|
||||
)
|
||||
|
||||
// Create a new image and paste the four produced images into it.
|
||||
dst := imaging.New(512, 512, color.NRGBA{0, 0, 0, 0})
|
||||
dst = imaging.Paste(dst, img1, image.Pt(0, 0))
|
||||
dst = imaging.Paste(dst, img2, image.Pt(0, 256))
|
||||
dst = imaging.Paste(dst, img3, image.Pt(256, 0))
|
||||
dst = imaging.Paste(dst, img4, image.Pt(256, 256))
|
||||
|
||||
// Save the resulting image using JPEG format.
|
||||
err = imaging.Save(dst, "testdata/out_example.jpg")
|
||||
if err != nil {
|
||||
log.Fatalf("Save failed: %v", err)
|
||||
}
|
||||
}
|
||||
44
vendor/github.com/disintegration/imaging/helpers.go
сгенерированный
поставляемый
@@ -1,11 +1,9 @@
|
||||
/*
|
||||
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 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 (
|
||||
@@ -24,8 +22,10 @@ import (
|
||||
"golang.org/x/image/tiff"
|
||||
)
|
||||
|
||||
// Format is an image file format.
|
||||
type Format int
|
||||
|
||||
// Image file formats.
|
||||
const (
|
||||
JPEG Format = iota
|
||||
PNG
|
||||
@@ -52,6 +52,7 @@ func (f Format) String() string {
|
||||
}
|
||||
|
||||
var (
|
||||
// ErrUnsupportedFormat means the given image format (or file extension) is unsupported.
|
||||
ErrUnsupportedFormat = errors.New("imaging: unsupported image format")
|
||||
)
|
||||
|
||||
@@ -194,15 +195,12 @@ func Clone(img image.Image) *image.NRGBA {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
si := src.PixOffset(srcMinX, srcMinY+dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
|
||||
dst.Pix[di+0] = src.Pix[si+0]
|
||||
dst.Pix[di+1] = src.Pix[si+2]
|
||||
dst.Pix[di+2] = src.Pix[si+4]
|
||||
dst.Pix[di+3] = src.Pix[si+6]
|
||||
|
||||
di += 4
|
||||
si += 8
|
||||
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -213,9 +211,9 @@ func Clone(img image.Image) *image.NRGBA {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
si := src.PixOffset(srcMinX, srcMinY+dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
|
||||
a := src.Pix[si+3]
|
||||
dst.Pix[di+3] = a
|
||||
|
||||
switch a {
|
||||
case 0:
|
||||
dst.Pix[di+0] = 0
|
||||
@@ -237,7 +235,6 @@ func Clone(img image.Image) *image.NRGBA {
|
||||
|
||||
di += 4
|
||||
si += 4
|
||||
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -248,9 +245,9 @@ func Clone(img image.Image) *image.NRGBA {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
si := src.PixOffset(srcMinX, srcMinY+dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
|
||||
a := src.Pix[si+6]
|
||||
dst.Pix[di+3] = a
|
||||
|
||||
switch a {
|
||||
case 0:
|
||||
dst.Pix[di+0] = 0
|
||||
@@ -272,7 +269,6 @@ func Clone(img image.Image) *image.NRGBA {
|
||||
|
||||
di += 4
|
||||
si += 8
|
||||
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -283,16 +279,13 @@ func Clone(img image.Image) *image.NRGBA {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
si := src.PixOffset(srcMinX, srcMinY+dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
|
||||
c := src.Pix[si]
|
||||
dst.Pix[di+0] = c
|
||||
dst.Pix[di+1] = c
|
||||
dst.Pix[di+2] = c
|
||||
dst.Pix[di+3] = 0xff
|
||||
|
||||
di += 4
|
||||
si += 1
|
||||
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -303,16 +296,13 @@ func Clone(img image.Image) *image.NRGBA {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
si := src.PixOffset(srcMinX, srcMinY+dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
|
||||
c := src.Pix[si]
|
||||
dst.Pix[di+0] = c
|
||||
dst.Pix[di+1] = c
|
||||
dst.Pix[di+2] = c
|
||||
dst.Pix[di+3] = 0xff
|
||||
|
||||
di += 4
|
||||
si += 2
|
||||
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -322,7 +312,6 @@ func Clone(img image.Image) *image.NRGBA {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
|
||||
srcX := srcMinX + dstX
|
||||
srcY := srcMinY + dstY
|
||||
siy := src.YOffset(srcX, srcY)
|
||||
@@ -332,9 +321,7 @@ func Clone(img image.Image) *image.NRGBA {
|
||||
dst.Pix[di+1] = g
|
||||
dst.Pix[di+2] = b
|
||||
dst.Pix[di+3] = 0xff
|
||||
|
||||
di += 4
|
||||
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -345,22 +332,18 @@ func Clone(img image.Image) *image.NRGBA {
|
||||
for i := 0; i < plen; i++ {
|
||||
pnew[i] = color.NRGBAModel.Convert(src.Palette[i]).(color.NRGBA)
|
||||
}
|
||||
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
si := src.PixOffset(srcMinX, srcMinY+dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
|
||||
c := pnew[src.Pix[si]]
|
||||
dst.Pix[di+0] = c.R
|
||||
dst.Pix[di+1] = c.G
|
||||
dst.Pix[di+2] = c.B
|
||||
dst.Pix[di+3] = c.A
|
||||
|
||||
di += 4
|
||||
si += 1
|
||||
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -370,15 +353,12 @@ func Clone(img image.Image) *image.NRGBA {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
di := dst.PixOffset(0, dstY)
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
|
||||
c := color.NRGBAModel.Convert(img.At(srcMinX+dstX, srcMinY+dstY)).(color.NRGBA)
|
||||
dst.Pix[di+0] = c.R
|
||||
dst.Pix[di+1] = c.G
|
||||
dst.Pix[di+2] = c.B
|
||||
dst.Pix[di+3] = c.A
|
||||
|
||||
di += 4
|
||||
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -388,7 +368,7 @@ func Clone(img image.Image) *image.NRGBA {
|
||||
return dst
|
||||
}
|
||||
|
||||
// This function used internally to convert any image type to NRGBA if needed.
|
||||
// toNRGBA converts any image type to *image.NRGBA with min-point at (0, 0).
|
||||
func toNRGBA(img image.Image) *image.NRGBA {
|
||||
srcBounds := img.Bounds()
|
||||
if srcBounds.Min.X == 0 && srcBounds.Min.Y == 0 {
|
||||
|
||||
2
vendor/github.com/disintegration/imaging/histogram.go
сгенерированный
поставляемый
@@ -17,7 +17,7 @@ func Histogram(img image.Image) [256]float64 {
|
||||
var total float64
|
||||
|
||||
if width == 0 || height == 0 {
|
||||
return histogram
|
||||
return histogram
|
||||
}
|
||||
|
||||
for y := 0; y < height; y++ {
|
||||
|
||||
2
vendor/github.com/disintegration/imaging/histogram_test.go
сгенерированный
поставляемый
@@ -36,7 +36,7 @@ func TestHistogram(t *testing.T) {
|
||||
for _, val := range h {
|
||||
if val != 0 {
|
||||
t.Errorf("Histogram for an empty image should be a zero histogram.")
|
||||
return
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
132
vendor/github.com/disintegration/imaging/resize.go
сгенерированный
поставляемый
@@ -5,17 +5,12 @@ import (
|
||||
"math"
|
||||
)
|
||||
|
||||
type iwpair struct {
|
||||
i int
|
||||
w int32
|
||||
type indexWeight struct {
|
||||
index int
|
||||
weight float64
|
||||
}
|
||||
|
||||
type pweights struct {
|
||||
iwpairs []iwpair
|
||||
wsum int32
|
||||
}
|
||||
|
||||
func precomputeWeights(dstSize, srcSize int, filter ResampleFilter) []pweights {
|
||||
func precomputeWeights(dstSize, srcSize int, filter ResampleFilter) [][]indexWeight {
|
||||
du := float64(srcSize) / float64(dstSize)
|
||||
scale := du
|
||||
if scale < 1.0 {
|
||||
@@ -23,7 +18,7 @@ func precomputeWeights(dstSize, srcSize int, filter ResampleFilter) []pweights {
|
||||
}
|
||||
ru := math.Ceil(scale * filter.Support)
|
||||
|
||||
out := make([]pweights, dstSize)
|
||||
out := make([][]indexWeight, dstSize)
|
||||
|
||||
for v := 0; v < dstSize; v++ {
|
||||
fu := (float64(v)+0.5)*du - 0.5
|
||||
@@ -37,15 +32,19 @@ func precomputeWeights(dstSize, srcSize int, filter ResampleFilter) []pweights {
|
||||
endu = srcSize - 1
|
||||
}
|
||||
|
||||
wsum := int32(0)
|
||||
var sum float64
|
||||
for u := startu; u <= endu; u++ {
|
||||
w := int32(0xff * filter.Kernel((float64(u)-fu)/scale))
|
||||
w := filter.Kernel((float64(u) - fu) / scale)
|
||||
if w != 0 {
|
||||
wsum += w
|
||||
out[v].iwpairs = append(out[v].iwpairs, iwpair{u, w})
|
||||
sum += w
|
||||
out[v] = append(out[v], indexWeight{index: u, weight: w})
|
||||
}
|
||||
}
|
||||
if sum != 0 {
|
||||
for i := range out[v] {
|
||||
out[v][i].weight /= sum
|
||||
}
|
||||
}
|
||||
out[v].wsum = wsum
|
||||
}
|
||||
|
||||
return out
|
||||
@@ -127,22 +126,26 @@ func resizeHorizontal(src *image.NRGBA, width int, filter ResampleFilter) *image
|
||||
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
i0 := dstY * src.Stride
|
||||
j0 := dstY * dst.Stride
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
var c [4]int64
|
||||
for _, iw := range weights[dstX].iwpairs {
|
||||
i := dstY*src.Stride + iw.i*4
|
||||
a := int64(src.Pix[i+3]) * int64(iw.w)
|
||||
c[0] += int64(src.Pix[i+0]) * a
|
||||
c[1] += int64(src.Pix[i+1]) * a
|
||||
c[2] += int64(src.Pix[i+2]) * a
|
||||
c[3] += a
|
||||
var r, g, b, a float64
|
||||
for _, w := range weights[dstX] {
|
||||
i := i0 + w.index*4
|
||||
aw := float64(src.Pix[i+3]) * w.weight
|
||||
r += float64(src.Pix[i+0]) * aw
|
||||
g += float64(src.Pix[i+1]) * aw
|
||||
b += float64(src.Pix[i+2]) * aw
|
||||
a += aw
|
||||
}
|
||||
if a != 0 {
|
||||
aInv := 1 / a
|
||||
j := j0 + dstX*4
|
||||
dst.Pix[j+0] = clamp(r * aInv)
|
||||
dst.Pix[j+1] = clamp(g * aInv)
|
||||
dst.Pix[j+2] = clamp(b * aInv)
|
||||
dst.Pix[j+3] = clamp(a)
|
||||
}
|
||||
j := dstY*dst.Stride + dstX*4
|
||||
sum := weights[dstX].wsum
|
||||
dst.Pix[j+0] = clampint32(int32(float64(c[0])/float64(c[3]) + 0.5))
|
||||
dst.Pix[j+1] = clampint32(int32(float64(c[1])/float64(c[3]) + 0.5))
|
||||
dst.Pix[j+2] = clampint32(int32(float64(c[2])/float64(c[3]) + 0.5))
|
||||
dst.Pix[j+3] = clampint32(int32(float64(c[3])/float64(sum) + 0.5))
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -163,33 +166,33 @@ func resizeVertical(src *image.NRGBA, height int, filter ResampleFilter) *image.
|
||||
weights := precomputeWeights(dstH, srcH, filter)
|
||||
|
||||
parallel(dstW, func(partStart, partEnd int) {
|
||||
|
||||
for dstX := partStart; dstX < partEnd; dstX++ {
|
||||
for dstY := 0; dstY < dstH; dstY++ {
|
||||
var c [4]int64
|
||||
for _, iw := range weights[dstY].iwpairs {
|
||||
i := iw.i*src.Stride + dstX*4
|
||||
a := int64(src.Pix[i+3]) * int64(iw.w)
|
||||
c[0] += int64(src.Pix[i+0]) * a
|
||||
c[1] += int64(src.Pix[i+1]) * a
|
||||
c[2] += int64(src.Pix[i+2]) * a
|
||||
c[3] += a
|
||||
var r, g, b, a float64
|
||||
for _, w := range weights[dstY] {
|
||||
i := w.index*src.Stride + dstX*4
|
||||
aw := float64(src.Pix[i+3]) * w.weight
|
||||
r += float64(src.Pix[i+0]) * aw
|
||||
g += float64(src.Pix[i+1]) * aw
|
||||
b += float64(src.Pix[i+2]) * aw
|
||||
a += aw
|
||||
}
|
||||
if a != 0 {
|
||||
aInv := 1 / a
|
||||
j := dstY*dst.Stride + dstX*4
|
||||
dst.Pix[j+0] = clamp(r * aInv)
|
||||
dst.Pix[j+1] = clamp(g * aInv)
|
||||
dst.Pix[j+2] = clamp(b * aInv)
|
||||
dst.Pix[j+3] = clamp(a)
|
||||
}
|
||||
j := dstY*dst.Stride + dstX*4
|
||||
sum := weights[dstY].wsum
|
||||
dst.Pix[j+0] = clampint32(int32(float64(c[0])/float64(c[3]) + 0.5))
|
||||
dst.Pix[j+1] = clampint32(int32(float64(c[1])/float64(c[3]) + 0.5))
|
||||
dst.Pix[j+2] = clampint32(int32(float64(c[2])/float64(c[3]) + 0.5))
|
||||
dst.Pix[j+3] = clampint32(int32(float64(c[3])/float64(sum) + 0.5))
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
return dst
|
||||
}
|
||||
|
||||
// fast nearest-neighbor resize, no filtering
|
||||
// resizeNearest is a fast nearest-neighbor resize, no filtering.
|
||||
func resizeNearest(src *image.NRGBA, width, height int) *image.NRGBA {
|
||||
dstW, dstH := width, height
|
||||
|
||||
@@ -205,13 +208,16 @@ func resizeNearest(src *image.NRGBA, width, height int) *image.NRGBA {
|
||||
parallel(dstH, func(partStart, partEnd int) {
|
||||
|
||||
for dstY := partStart; dstY < partEnd; dstY++ {
|
||||
fy := (float64(dstY)+0.5)*dy - 0.5
|
||||
srcY := int((float64(dstY) + 0.5) * dy)
|
||||
if srcY > srcH-1 {
|
||||
srcY = srcH - 1
|
||||
}
|
||||
|
||||
for dstX := 0; dstX < dstW; dstX++ {
|
||||
fx := (float64(dstX)+0.5)*dx - 0.5
|
||||
|
||||
srcX := int(math.Min(math.Max(math.Floor(fx+0.5), 0.0), float64(srcW)))
|
||||
srcY := int(math.Min(math.Max(math.Floor(fy+0.5), 0.0), float64(srcH)))
|
||||
srcX := int((float64(dstX) + 0.5) * dx)
|
||||
if srcX > srcW-1 {
|
||||
srcX = srcW - 1
|
||||
}
|
||||
|
||||
srcOff := srcY*src.Stride + srcX*4
|
||||
dstOff := dstY*dst.Stride + dstX*4
|
||||
@@ -326,7 +332,7 @@ func Thumbnail(img image.Image, width, height int, filter ResampleFilter) *image
|
||||
return Fill(img, width, height, Center, filter)
|
||||
}
|
||||
|
||||
// Resample filter struct. It can be used to make custom filters.
|
||||
// ResampleFilter is a resampling filter struct. It can be used to define custom filters.
|
||||
//
|
||||
// Supported resample filters: NearestNeighbor, Box, Linear, Hermite, MitchellNetravali,
|
||||
// CatmullRom, BSpline, Gaussian, Lanczos, Hann, Hamming, Blackman, Bartlett, Welch, Cosine.
|
||||
@@ -361,7 +367,7 @@ type ResampleFilter struct {
|
||||
Kernel func(float64) float64
|
||||
}
|
||||
|
||||
// Nearest-neighbor filter, no anti-aliasing.
|
||||
// NearestNeighbor is a nearest-neighbor filter (no anti-aliasing).
|
||||
var NearestNeighbor ResampleFilter
|
||||
|
||||
// Box filter (averaging pixels).
|
||||
@@ -373,37 +379,37 @@ var Linear ResampleFilter
|
||||
// Hermite cubic spline filter (BC-spline; B=0; C=0).
|
||||
var Hermite ResampleFilter
|
||||
|
||||
// Mitchell-Netravali cubic filter (BC-spline; B=1/3; C=1/3).
|
||||
// MitchellNetravali is Mitchell-Netravali cubic filter (BC-spline; B=1/3; C=1/3).
|
||||
var MitchellNetravali ResampleFilter
|
||||
|
||||
// Catmull-Rom - sharp cubic filter (BC-spline; B=0; C=0.5).
|
||||
// CatmullRom is a Catmull-Rom - sharp cubic filter (BC-spline; B=0; C=0.5).
|
||||
var CatmullRom ResampleFilter
|
||||
|
||||
// Cubic B-spline - smooth cubic filter (BC-spline; B=1; C=0).
|
||||
// BSpline is a smooth cubic filter (BC-spline; B=1; C=0).
|
||||
var BSpline ResampleFilter
|
||||
|
||||
// Gaussian Blurring Filter.
|
||||
// Gaussian is a Gaussian blurring Filter.
|
||||
var Gaussian ResampleFilter
|
||||
|
||||
// Bartlett-windowed sinc filter (3 lobes).
|
||||
// Bartlett is a Bartlett-windowed sinc filter (3 lobes).
|
||||
var Bartlett ResampleFilter
|
||||
|
||||
// Lanczos filter (3 lobes).
|
||||
var Lanczos ResampleFilter
|
||||
|
||||
// Hann-windowed sinc filter (3 lobes).
|
||||
// Hann is a Hann-windowed sinc filter (3 lobes).
|
||||
var Hann ResampleFilter
|
||||
|
||||
// Hamming-windowed sinc filter (3 lobes).
|
||||
// Hamming is a Hamming-windowed sinc filter (3 lobes).
|
||||
var Hamming ResampleFilter
|
||||
|
||||
// Blackman-windowed sinc filter (3 lobes).
|
||||
// Blackman is a Blackman-windowed sinc filter (3 lobes).
|
||||
var Blackman ResampleFilter
|
||||
|
||||
// Welch-windowed sinc filter (parabolic window, 3 lobes).
|
||||
// Welch is a Welch-windowed sinc filter (parabolic window, 3 lobes).
|
||||
var Welch ResampleFilter
|
||||
|
||||
// Cosine-windowed sinc filter (3 lobes).
|
||||
// Cosine is a Cosine-windowed sinc filter (3 lobes).
|
||||
var Cosine ResampleFilter
|
||||
|
||||
func bcspline(x, b, c float64) float64 {
|
||||
|
||||
68
vendor/github.com/disintegration/imaging/resize_test.go
сгенерированный
поставляемый
@@ -108,10 +108,10 @@ func TestResize(t *testing.T) {
|
||||
Rect: image.Rect(0, 0, 4, 4),
|
||||
Stride: 4 * 4,
|
||||
Pix: []uint8{
|
||||
0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x3f, 0xff, 0x00, 0x00, 0xc0, 0xff, 0x00, 0x00, 0xff,
|
||||
0x00, 0xff, 0x00, 0x3f, 0x6d, 0x6e, 0x24, 0x6f, 0xb1, 0x13, 0x3a, 0xd0, 0xc0, 0x00, 0x3f, 0xff,
|
||||
0x00, 0xff, 0x00, 0xc0, 0x13, 0xb2, 0x3a, 0xcf, 0x33, 0x32, 0x9a, 0xef, 0x3f, 0x00, 0xc0, 0xff,
|
||||
0x00, 0xff, 0x00, 0xff, 0x00, 0xc0, 0x3f, 0xff, 0x00, 0x3f, 0xc0, 0xff, 0x00, 0x00, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x40, 0xff, 0x00, 0x00, 0xbf, 0xff, 0x00, 0x00, 0xff,
|
||||
0x00, 0xff, 0x00, 0x40, 0x6e, 0x6d, 0x25, 0x70, 0xb0, 0x14, 0x3b, 0xcf, 0xbf, 0x00, 0x40, 0xff,
|
||||
0x00, 0xff, 0x00, 0xbf, 0x14, 0xb0, 0x3b, 0xcf, 0x33, 0x33, 0x99, 0xef, 0x40, 0x00, 0xbf, 0xff,
|
||||
0x00, 0xff, 0x00, 0xff, 0x00, 0xbf, 0x40, 0xff, 0x00, 0x40, 0xbf, 0xff, 0x00, 0x00, 0xff, 0xff,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -158,7 +158,7 @@ func TestResize(t *testing.T) {
|
||||
for _, d := range td {
|
||||
got := Resize(d.src, d.w, d.h, d.f)
|
||||
want := d.want
|
||||
if !compareNRGBA(got, want, 1) {
|
||||
if !compareNRGBA(got, want, 0) {
|
||||
t.Errorf("test [%s] failed: %#v", d.desc, got)
|
||||
}
|
||||
}
|
||||
@@ -201,6 +201,28 @@ func TestResize(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestResizeGolden(t *testing.T) {
|
||||
src, err := Open("testdata/lena_512.png")
|
||||
if err != nil {
|
||||
t.Errorf("Open: %v", err)
|
||||
}
|
||||
for name, filter := range map[string]ResampleFilter{
|
||||
"out_resize_nearest.png": NearestNeighbor,
|
||||
"out_resize_linear.png": Linear,
|
||||
"out_resize_catrom.png": CatmullRom,
|
||||
"out_resize_lanczos.png": Lanczos,
|
||||
} {
|
||||
got := Resize(src, 128, 0, filter)
|
||||
want, err := Open("testdata/" + name)
|
||||
if err != nil {
|
||||
t.Errorf("Open: %v", err)
|
||||
}
|
||||
if !compareNRGBA(got, toNRGBA(want), 0) {
|
||||
t.Errorf("resulting image differs from golden: %s", name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFit(t *testing.T) {
|
||||
td := []struct {
|
||||
desc string
|
||||
@@ -568,3 +590,39 @@ func TestThumbnail(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkResizeLanczosUp(b *testing.B) {
|
||||
benchmarkResize(b, "testdata/lena_128.png", 512, Lanczos)
|
||||
}
|
||||
|
||||
func BenchmarkResizeLinearUp(b *testing.B) {
|
||||
benchmarkResize(b, "testdata/lena_128.png", 512, Linear)
|
||||
}
|
||||
|
||||
func BenchmarkResizeNearestNeighborUp(b *testing.B) {
|
||||
benchmarkResize(b, "testdata/lena_128.png", 512, NearestNeighbor)
|
||||
}
|
||||
|
||||
func BenchmarkResizeLanczosDown(b *testing.B) {
|
||||
benchmarkResize(b, "testdata/lena_512.png", 128, Lanczos)
|
||||
}
|
||||
|
||||
func BenchmarkResizeLinearDown(b *testing.B) {
|
||||
benchmarkResize(b, "testdata/lena_512.png", 128, Linear)
|
||||
}
|
||||
|
||||
func BenchmarkResizeNearestNeighborDown(b *testing.B) {
|
||||
benchmarkResize(b, "testdata/lena_512.png", 128, NearestNeighbor)
|
||||
}
|
||||
|
||||
func benchmarkResize(b *testing.B, filename string, size int, f ResampleFilter) {
|
||||
b.StopTimer()
|
||||
img, err := Open(filename)
|
||||
if err != nil {
|
||||
b.Fatalf("Open: %v", err)
|
||||
}
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
Resize(img, size, size, f)
|
||||
}
|
||||
}
|
||||
|
||||
Двоичные данные
vendor/github.com/disintegration/imaging/testdata/lena_128.png
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 49 KiB |
Двоичные данные
vendor/github.com/disintegration/imaging/testdata/lena_512.png
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 465 KiB |
Двоичные данные
vendor/github.com/disintegration/imaging/testdata/out_blur_0.5.png
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 28 KiB |
Двоичные данные
vendor/github.com/disintegration/imaging/testdata/out_blur_1.5.png
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 21 KiB |
Двоичные данные
vendor/github.com/disintegration/imaging/testdata/out_brightness_m10.png
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 31 KiB |
Двоичные данные
vendor/github.com/disintegration/imaging/testdata/out_brightness_p10.png
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 31 KiB |
Двоичные данные
vendor/github.com/disintegration/imaging/testdata/out_contrast_m10.png
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 30 KiB |
Двоичные данные
vendor/github.com/disintegration/imaging/testdata/out_contrast_p10.png
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 32 KiB |
Двоичные данные
vendor/github.com/disintegration/imaging/testdata/out_example.jpg
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 134 KiB |
Двоичные данные
vendor/github.com/disintegration/imaging/testdata/out_gamma_0.75.png
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 31 KiB |
Двоичные данные
vendor/github.com/disintegration/imaging/testdata/out_gamma_1.25.png
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 31 KiB |
Двоичные данные
vendor/github.com/disintegration/imaging/testdata/out_resize_catrom.png
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 30 KiB |
Двоичные данные
vendor/github.com/disintegration/imaging/testdata/out_resize_lanczos.png
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 31 KiB |
Двоичные данные
vendor/github.com/disintegration/imaging/testdata/out_resize_linear.png
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 29 KiB |
Двоичные данные
vendor/github.com/disintegration/imaging/testdata/out_resize_nearest.png
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 35 KiB |
Двоичные данные
vendor/github.com/disintegration/imaging/testdata/out_sharpen_0.5.png
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 33 KiB |
Двоичные данные
vendor/github.com/disintegration/imaging/testdata/out_sharpen_1.5.png
сгенерированный
поставляемый
Обычный файл
|
После Ширина: | Высота: | Размер: 36 KiB |
1
vendor/github.com/disintegration/imaging/tools.go
сгенерированный
поставляемый
@@ -8,6 +8,7 @@ import (
|
||||
// Anchor is the anchor point for image alignment.
|
||||
type Anchor int
|
||||
|
||||
// Anchor point positions.
|
||||
const (
|
||||
Center Anchor = iota
|
||||
TopLeft
|
||||
|
||||
2
vendor/github.com/disintegration/imaging/tools_test.go
сгенерированный
поставляемый
@@ -598,7 +598,7 @@ func TestOverlay(t *testing.T) {
|
||||
for _, d := range td {
|
||||
got := Overlay(d.src1, d.src2, d.p, d.a)
|
||||
want := d.want
|
||||
if !compareNRGBA(got, want, 1) {
|
||||
if !compareNRGBA(got, want, 0) {
|
||||
t.Errorf("test [%s] failed: %#v", d.desc, got)
|
||||
}
|
||||
}
|
||||
|
||||
42
vendor/github.com/disintegration/imaging/utils.go
сгенерированный
поставляемый
@@ -1,28 +1,24 @@
|
||||
package imaging
|
||||
|
||||
import (
|
||||
"math"
|
||||
"runtime"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
var parallelizationEnabled = true
|
||||
|
||||
// if GOMAXPROCS = 1: no goroutines used
|
||||
// if GOMAXPROCS > 1: spawn N=GOMAXPROCS workers in separate goroutines
|
||||
// parallel starts parallel image processing based on the current GOMAXPROCS value.
|
||||
// If GOMAXPROCS = 1 it uses no parallelization.
|
||||
// If GOMAXPROCS > 1 it spawns N=GOMAXPROCS workers in separate goroutines.
|
||||
func parallel(dataSize int, fn func(partStart, partEnd int)) {
|
||||
numGoroutines := 1
|
||||
partSize := dataSize
|
||||
|
||||
if parallelizationEnabled {
|
||||
numProcs := runtime.GOMAXPROCS(0)
|
||||
if numProcs > 1 {
|
||||
numGoroutines = numProcs
|
||||
partSize = dataSize / (numGoroutines * 10)
|
||||
if partSize < 1 {
|
||||
partSize = 1
|
||||
}
|
||||
numProcs := runtime.GOMAXPROCS(0)
|
||||
if numProcs > 1 {
|
||||
numGoroutines = numProcs
|
||||
partSize = dataSize / (numGoroutines * 10)
|
||||
if partSize < 1 {
|
||||
partSize = 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +50,7 @@ func parallel(dataSize int, fn func(partStart, partEnd int)) {
|
||||
}
|
||||
}
|
||||
|
||||
// absint returns the absolute value of i.
|
||||
func absint(i int) int {
|
||||
if i < 0 {
|
||||
return -i
|
||||
@@ -61,17 +58,14 @@ func absint(i int) int {
|
||||
return i
|
||||
}
|
||||
|
||||
// clamp & round float64 to uint8 (0..255)
|
||||
func clamp(v float64) uint8 {
|
||||
return uint8(math.Min(math.Max(v, 0.0), 255.0) + 0.5)
|
||||
}
|
||||
|
||||
// clamp int32 to uint8 (0..255)
|
||||
func clampint32(v int32) uint8 {
|
||||
if v < 0 {
|
||||
return 0
|
||||
} else if v > 255 {
|
||||
// clamp rounds and clamps float64 value to fit into uint8.
|
||||
func clamp(x float64) uint8 {
|
||||
v := int64(x + 0.5)
|
||||
if v > 255 {
|
||||
return 255
|
||||
}
|
||||
return uint8(v)
|
||||
if v > 0 {
|
||||
return uint8(v)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
24
vendor/github.com/disintegration/imaging/utils_test.go
сгенерированный
поставляемый
@@ -15,7 +15,7 @@ func testParallelN(enabled bool, n, procs int) bool {
|
||||
}
|
||||
})
|
||||
for i := 0; i < n; i++ {
|
||||
if data[i] != true {
|
||||
if !data[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,7 @@ func TestParallel(t *testing.T) {
|
||||
for _, e := range []bool{true, false} {
|
||||
for _, n := range []int{1, 10, 100, 1000} {
|
||||
for _, p := range []int{1, 2, 4, 8, 16, 100} {
|
||||
if testParallelN(e, n, p) != true {
|
||||
if !testParallelN(e, n, p) {
|
||||
t.Errorf("test [parallel %v %d %d] failed", e, n, p)
|
||||
}
|
||||
}
|
||||
@@ -59,23 +59,3 @@ func TestClamp(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestClampint32(t *testing.T) {
|
||||
td := []struct {
|
||||
i int32
|
||||
u uint8
|
||||
}{
|
||||
{0, 0},
|
||||
{255, 255},
|
||||
{128, 128},
|
||||
{256, 255},
|
||||
{2500, 255},
|
||||
{-10, 0},
|
||||
}
|
||||
|
||||
for _, d := range td {
|
||||
if clampint32(d.i) != d.u {
|
||||
t.Errorf("test [clampint32 %v %v] failed: %v", d.i, d.u, clampint32(d.i))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||