summaryrefslogtreecommitdiffstats
path: root/Godeps/_workspace/src/github.com/nfnt/resize/resize.go
diff options
context:
space:
mode:
Diffstat (limited to 'Godeps/_workspace/src/github.com/nfnt/resize/resize.go')
-rw-r--r--Godeps/_workspace/src/github.com/nfnt/resize/resize.go614
1 files changed, 0 insertions, 614 deletions
diff --git a/Godeps/_workspace/src/github.com/nfnt/resize/resize.go b/Godeps/_workspace/src/github.com/nfnt/resize/resize.go
deleted file mode 100644
index c1672432e..000000000
--- a/Godeps/_workspace/src/github.com/nfnt/resize/resize.go
+++ /dev/null
@@ -1,614 +0,0 @@
-/*
-Copyright (c) 2012, Jan Schlicht <jan.schlicht@gmail.com>
-
-Permission to use, copy, modify, and/or distribute this software for any purpose
-with or without fee is hereby granted, provided that the above copyright notice
-and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
-FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
-TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
-THIS SOFTWARE.
-*/
-
-// Package resize implements various image resizing methods.
-//
-// The package works with the Image interface described in the image package.
-// Various interpolation methods are provided and multiple processors may be
-// utilized in the computations.
-//
-// Example:
-// imgResized := resize.Resize(1000, 0, imgOld, resize.MitchellNetravali)
-package resize
-
-import (
- "image"
- "runtime"
- "sync"
-)
-
-// An InterpolationFunction provides the parameters that describe an
-// interpolation kernel. It returns the number of samples to take
-// and the kernel function to use for sampling.
-type InterpolationFunction int
-
-// InterpolationFunction constants
-const (
- // Nearest-neighbor interpolation
- NearestNeighbor InterpolationFunction = iota
- // Bilinear interpolation
- Bilinear
- // Bicubic interpolation (with cubic hermite spline)
- Bicubic
- // Mitchell-Netravali interpolation
- MitchellNetravali
- // Lanczos interpolation (a=2)
- Lanczos2
- // Lanczos interpolation (a=3)
- Lanczos3
-)
-
-// kernal, returns an InterpolationFunctions taps and kernel.
-func (i InterpolationFunction) kernel() (int, func(float64) float64) {
- switch i {
- case Bilinear:
- return 2, linear
- case Bicubic:
- return 4, cubic
- case MitchellNetravali:
- return 4, mitchellnetravali
- case Lanczos2:
- return 4, lanczos2
- case Lanczos3:
- return 6, lanczos3
- default:
- // Default to NearestNeighbor.
- return 2, nearest
- }
-}
-
-// values <1 will sharpen the image
-var blur = 1.0
-
-// Resize scales an image to new width and height using the interpolation function interp.
-// A new image with the given dimensions will be returned.
-// If one of the parameters width or height is set to 0, its size will be calculated so that
-// the aspect ratio is that of the originating image.
-// The resizing algorithm uses channels for parallel computation.
-func Resize(width, height uint, img image.Image, interp InterpolationFunction) image.Image {
- scaleX, scaleY := calcFactors(width, height, float64(img.Bounds().Dx()), float64(img.Bounds().Dy()))
- if width == 0 {
- width = uint(0.7 + float64(img.Bounds().Dx())/scaleX)
- }
- if height == 0 {
- height = uint(0.7 + float64(img.Bounds().Dy())/scaleY)
- }
-
- // Trivial case: return input image
- if int(width) == img.Bounds().Dx() && int(height) == img.Bounds().Dy() {
- return img
- }
-
- if interp == NearestNeighbor {
- return resizeNearest(width, height, scaleX, scaleY, img, interp)
- }
-
- taps, kernel := interp.kernel()
- cpus := runtime.GOMAXPROCS(0)
- wg := sync.WaitGroup{}
-
- // Generic access to image.Image is slow in tight loops.
- // The optimal access has to be determined from the concrete image type.
- switch input := img.(type) {
- case *image.RGBA:
- // 8-bit precision
- temp := image.NewNRGBA(image.Rect(0, 0, input.Bounds().Dy(), int(width)))
- result := image.NewNRGBA(image.Rect(0, 0, int(width), int(height)))
-
- // horizontal filter, results in transposed temporary image
- coeffs, offset, filterLength := createWeights8(temp.Bounds().Dy(), taps, blur, scaleX, kernel)
- wg.Add(cpus)
- for i := 0; i < cpus; i++ {
- slice := makeSlice(temp, i, cpus).(*image.NRGBA)
- go func() {
- defer wg.Done()
- resizeRGBA(input, slice, scaleX, coeffs, offset, filterLength)
- }()
- }
- wg.Wait()
-
- // horizontal filter on transposed image, result is not transposed
- coeffs, offset, filterLength = createWeights8(result.Bounds().Dy(), taps, blur, scaleY, kernel)
- wg.Add(cpus)
- for i := 0; i < cpus; i++ {
- slice := makeSlice(result, i, cpus).(*image.NRGBA)
- go func() {
- defer wg.Done()
- resizeNRGBA(temp, slice, scaleY, coeffs, offset, filterLength)
- }()
- }
- wg.Wait()
- return result
- case *image.NRGBA:
- // 8-bit precision
- temp := image.NewNRGBA(image.Rect(0, 0, input.Bounds().Dy(), int(width)))
- result := image.NewNRGBA(image.Rect(0, 0, int(width), int(height)))
-
- // horizontal filter, results in transposed temporary image
- coeffs, offset, filterLength := createWeights8(temp.Bounds().Dy(), taps, blur, scaleX, kernel)
- wg.Add(cpus)
- for i := 0; i < cpus; i++ {
- slice := makeSlice(temp, i, cpus).(*image.NRGBA)
- go func() {
- defer wg.Done()
- resizeNRGBA(input, slice, scaleX, coeffs, offset, filterLength)
- }()
- }
- wg.Wait()
-
- // horizontal filter on transposed image, result is not transposed
- coeffs, offset, filterLength = createWeights8(result.Bounds().Dy(), taps, blur, scaleY, kernel)
- wg.Add(cpus)
- for i := 0; i < cpus; i++ {
- slice := makeSlice(result, i, cpus).(*image.NRGBA)
- go func() {
- defer wg.Done()
- resizeNRGBA(temp, slice, scaleY, coeffs, offset, filterLength)
- }()
- }
- wg.Wait()
- return result
-
- case *image.YCbCr:
- // 8-bit precision
- // accessing the YCbCr arrays in a tight loop is slow.
- // converting the image to ycc increases performance by 2x.
- temp := newYCC(image.Rect(0, 0, input.Bounds().Dy(), int(width)), input.SubsampleRatio)
- result := newYCC(image.Rect(0, 0, int(width), int(height)), image.YCbCrSubsampleRatio444)
-
- coeffs, offset, filterLength := createWeights8(temp.Bounds().Dy(), taps, blur, scaleX, kernel)
- in := imageYCbCrToYCC(input)
- wg.Add(cpus)
- for i := 0; i < cpus; i++ {
- slice := makeSlice(temp, i, cpus).(*ycc)
- go func() {
- defer wg.Done()
- resizeYCbCr(in, slice, scaleX, coeffs, offset, filterLength)
- }()
- }
- wg.Wait()
-
- coeffs, offset, filterLength = createWeights8(result.Bounds().Dy(), taps, blur, scaleY, kernel)
- wg.Add(cpus)
- for i := 0; i < cpus; i++ {
- slice := makeSlice(result, i, cpus).(*ycc)
- go func() {
- defer wg.Done()
- resizeYCbCr(temp, slice, scaleY, coeffs, offset, filterLength)
- }()
- }
- wg.Wait()
- return result.YCbCr()
- case *image.RGBA64:
- // 16-bit precision
- temp := image.NewNRGBA64(image.Rect(0, 0, input.Bounds().Dy(), int(width)))
- result := image.NewNRGBA64(image.Rect(0, 0, int(width), int(height)))
-
- // horizontal filter, results in transposed temporary image
- coeffs, offset, filterLength := createWeights16(temp.Bounds().Dy(), taps, blur, scaleX, kernel)
- wg.Add(cpus)
- for i := 0; i < cpus; i++ {
- slice := makeSlice(temp, i, cpus).(*image.NRGBA64)
- go func() {
- defer wg.Done()
- resizeRGBA64(input, slice, scaleX, coeffs, offset, filterLength)
- }()
- }
- wg.Wait()
-
- // horizontal filter on transposed image, result is not transposed
- coeffs, offset, filterLength = createWeights16(result.Bounds().Dy(), taps, blur, scaleY, kernel)
- wg.Add(cpus)
- for i := 0; i < cpus; i++ {
- slice := makeSlice(result, i, cpus).(*image.NRGBA64)
- go func() {
- defer wg.Done()
- resizeNRGBA64(temp, slice, scaleY, coeffs, offset, filterLength)
- }()
- }
- wg.Wait()
- return result
- case *image.NRGBA64:
- // 16-bit precision
- temp := image.NewNRGBA64(image.Rect(0, 0, input.Bounds().Dy(), int(width)))
- result := image.NewNRGBA64(image.Rect(0, 0, int(width), int(height)))
-
- // horizontal filter, results in transposed temporary image
- coeffs, offset, filterLength := createWeights16(temp.Bounds().Dy(), taps, blur, scaleX, kernel)
- wg.Add(cpus)
- for i := 0; i < cpus; i++ {
- slice := makeSlice(temp, i, cpus).(*image.NRGBA64)
- go func() {
- defer wg.Done()
- resizeNRGBA64(input, slice, scaleX, coeffs, offset, filterLength)
- }()
- }
- wg.Wait()
-
- // horizontal filter on transposed image, result is not transposed
- coeffs, offset, filterLength = createWeights16(result.Bounds().Dy(), taps, blur, scaleY, kernel)
- wg.Add(cpus)
- for i := 0; i < cpus; i++ {
- slice := makeSlice(result, i, cpus).(*image.NRGBA64)
- go func() {
- defer wg.Done()
- resizeNRGBA64(temp, slice, scaleY, coeffs, offset, filterLength)
- }()
- }
- wg.Wait()
- return result
- case *image.Gray:
- // 8-bit precision
- temp := image.NewGray(image.Rect(0, 0, input.Bounds().Dy(), int(width)))
- result := image.NewGray(image.Rect(0, 0, int(width), int(height)))
-
- // horizontal filter, results in transposed temporary image
- coeffs, offset, filterLength := createWeights8(temp.Bounds().Dy(), taps, blur, scaleX, kernel)
- wg.Add(cpus)
- for i := 0; i < cpus; i++ {
- slice := makeSlice(temp, i, cpus).(*image.Gray)
- go func() {
- defer wg.Done()
- resizeGray(input, slice, scaleX, coeffs, offset, filterLength)
- }()
- }
- wg.Wait()
-
- // horizontal filter on transposed image, result is not transposed
- coeffs, offset, filterLength = createWeights8(result.Bounds().Dy(), taps, blur, scaleY, kernel)
- wg.Add(cpus)
- for i := 0; i < cpus; i++ {
- slice := makeSlice(result, i, cpus).(*image.Gray)
- go func() {
- defer wg.Done()
- resizeGray(temp, slice, scaleY, coeffs, offset, filterLength)
- }()
- }
- wg.Wait()
- return result
- case *image.Gray16:
- // 16-bit precision
- temp := image.NewGray16(image.Rect(0, 0, input.Bounds().Dy(), int(width)))
- result := image.NewGray16(image.Rect(0, 0, int(width), int(height)))
-
- // horizontal filter, results in transposed temporary image
- coeffs, offset, filterLength := createWeights16(temp.Bounds().Dy(), taps, blur, scaleX, kernel)
- wg.Add(cpus)
- for i := 0; i < cpus; i++ {
- slice := makeSlice(temp, i, cpus).(*image.Gray16)
- go func() {
- defer wg.Done()
- resizeGray16(input, slice, scaleX, coeffs, offset, filterLength)
- }()
- }
- wg.Wait()
-
- // horizontal filter on transposed image, result is not transposed
- coeffs, offset, filterLength = createWeights16(result.Bounds().Dy(), taps, blur, scaleY, kernel)
- wg.Add(cpus)
- for i := 0; i < cpus; i++ {
- slice := makeSlice(result, i, cpus).(*image.Gray16)
- go func() {
- defer wg.Done()
- resizeGray16(temp, slice, scaleY, coeffs, offset, filterLength)
- }()
- }
- wg.Wait()
- return result
- default:
- // 16-bit precision
- temp := image.NewNRGBA64(image.Rect(0, 0, img.Bounds().Dy(), int(width)))
- result := image.NewNRGBA64(image.Rect(0, 0, int(width), int(height)))
-
- // horizontal filter, results in transposed temporary image
- coeffs, offset, filterLength := createWeights16(temp.Bounds().Dy(), taps, blur, scaleX, kernel)
- wg.Add(cpus)
- for i := 0; i < cpus; i++ {
- slice := makeSlice(temp, i, cpus).(*image.NRGBA64)
- go func() {
- defer wg.Done()
- resizeGeneric(img, slice, scaleX, coeffs, offset, filterLength)
- }()
- }
- wg.Wait()
-
- // horizontal filter on transposed image, result is not transposed
- coeffs, offset, filterLength = createWeights16(result.Bounds().Dy(), taps, blur, scaleY, kernel)
- wg.Add(cpus)
- for i := 0; i < cpus; i++ {
- slice := makeSlice(result, i, cpus).(*image.NRGBA64)
- go func() {
- defer wg.Done()
- resizeNRGBA64(temp, slice, scaleY, coeffs, offset, filterLength)
- }()
- }
- wg.Wait()
- return result
- }
-}
-
-func resizeNearest(width, height uint, scaleX, scaleY float64, img image.Image, interp InterpolationFunction) image.Image {
- taps, _ := interp.kernel()
- cpus := runtime.GOMAXPROCS(0)
- wg := sync.WaitGroup{}
-
- switch input := img.(type) {
- case *image.RGBA:
- // 8-bit precision
- temp := image.NewRGBA(image.Rect(0, 0, input.Bounds().Dy(), int(width)))
- result := image.NewRGBA(image.Rect(0, 0, int(width), int(height)))
-
- // horizontal filter, results in transposed temporary image
- coeffs, offset, filterLength := createWeightsNearest(temp.Bounds().Dy(), taps, blur, scaleX)
- wg.Add(cpus)
- for i := 0; i < cpus; i++ {
- slice := makeSlice(temp, i, cpus).(*image.RGBA)
- go func() {
- defer wg.Done()
- nearestRGBA(input, slice, scaleX, coeffs, offset, filterLength)
- }()
- }
- wg.Wait()
-
- // horizontal filter on transposed image, result is not transposed
- coeffs, offset, filterLength = createWeightsNearest(result.Bounds().Dy(), taps, blur, scaleY)
- wg.Add(cpus)
- for i := 0; i < cpus; i++ {
- slice := makeSlice(result, i, cpus).(*image.RGBA)
- go func() {
- defer wg.Done()
- nearestRGBA(temp, slice, scaleY, coeffs, offset, filterLength)
- }()
- }
- wg.Wait()
- return result
- case *image.NRGBA:
- // 8-bit precision
- temp := image.NewNRGBA(image.Rect(0, 0, input.Bounds().Dy(), int(width)))
- result := image.NewNRGBA(image.Rect(0, 0, int(width), int(height)))
-
- // horizontal filter, results in transposed temporary image
- coeffs, offset, filterLength := createWeightsNearest(temp.Bounds().Dy(), taps, blur, scaleX)
- wg.Add(cpus)
- for i := 0; i < cpus; i++ {
- slice := makeSlice(temp, i, cpus).(*image.NRGBA)
- go func() {
- defer wg.Done()
- nearestNRGBA(input, slice, scaleX, coeffs, offset, filterLength)
- }()
- }
- wg.Wait()
-
- // horizontal filter on transposed image, result is not transposed
- coeffs, offset, filterLength = createWeightsNearest(result.Bounds().Dy(), taps, blur, scaleY)
- wg.Add(cpus)
- for i := 0; i < cpus; i++ {
- slice := makeSlice(result, i, cpus).(*image.NRGBA)
- go func() {
- defer wg.Done()
- nearestNRGBA(temp, slice, scaleY, coeffs, offset, filterLength)
- }()
- }
- wg.Wait()
- return result
- case *image.YCbCr:
- // 8-bit precision
- // accessing the YCbCr arrays in a tight loop is slow.
- // converting the image to ycc increases performance by 2x.
- temp := newYCC(image.Rect(0, 0, input.Bounds().Dy(), int(width)), input.SubsampleRatio)
- result := newYCC(image.Rect(0, 0, int(width), int(height)), image.YCbCrSubsampleRatio444)
-
- coeffs, offset, filterLength := createWeightsNearest(temp.Bounds().Dy(), taps, blur, scaleX)
- in := imageYCbCrToYCC(input)
- wg.Add(cpus)
- for i := 0; i < cpus; i++ {
- slice := makeSlice(temp, i, cpus).(*ycc)
- go func() {
- defer wg.Done()
- nearestYCbCr(in, slice, scaleX, coeffs, offset, filterLength)
- }()
- }
- wg.Wait()
-
- coeffs, offset, filterLength = createWeightsNearest(result.Bounds().Dy(), taps, blur, scaleY)
- wg.Add(cpus)
- for i := 0; i < cpus; i++ {
- slice := makeSlice(result, i, cpus).(*ycc)
- go func() {
- defer wg.Done()
- nearestYCbCr(temp, slice, scaleY, coeffs, offset, filterLength)
- }()
- }
- wg.Wait()
- return result.YCbCr()
- case *image.RGBA64:
- // 16-bit precision
- temp := image.NewRGBA64(image.Rect(0, 0, input.Bounds().Dy(), int(width)))
- result := image.NewRGBA64(image.Rect(0, 0, int(width), int(height)))
-
- // horizontal filter, results in transposed temporary image
- coeffs, offset, filterLength := createWeightsNearest(temp.Bounds().Dy(), taps, blur, scaleX)
- wg.Add(cpus)
- for i := 0; i < cpus; i++ {
- slice := makeSlice(temp, i, cpus).(*image.RGBA64)
- go func() {
- defer wg.Done()
- nearestRGBA64(input, slice, scaleX, coeffs, offset, filterLength)
- }()
- }
- wg.Wait()
-
- // horizontal filter on transposed image, result is not transposed
- coeffs, offset, filterLength = createWeightsNearest(result.Bounds().Dy(), taps, blur, scaleY)
- wg.Add(cpus)
- for i := 0; i < cpus; i++ {
- slice := makeSlice(result, i, cpus).(*image.RGBA64)
- go func() {
- defer wg.Done()
- nearestRGBA64(temp, slice, scaleY, coeffs, offset, filterLength)
- }()
- }
- wg.Wait()
- return result
- case *image.NRGBA64:
- // 16-bit precision
- temp := image.NewNRGBA64(image.Rect(0, 0, input.Bounds().Dy(), int(width)))
- result := image.NewNRGBA64(image.Rect(0, 0, int(width), int(height)))
-
- // horizontal filter, results in transposed temporary image
- coeffs, offset, filterLength := createWeightsNearest(temp.Bounds().Dy(), taps, blur, scaleX)
- wg.Add(cpus)
- for i := 0; i < cpus; i++ {
- slice := makeSlice(temp, i, cpus).(*image.NRGBA64)
- go func() {
- defer wg.Done()
- nearestNRGBA64(input, slice, scaleX, coeffs, offset, filterLength)
- }()
- }
- wg.Wait()
-
- // horizontal filter on transposed image, result is not transposed
- coeffs, offset, filterLength = createWeightsNearest(result.Bounds().Dy(), taps, blur, scaleY)
- wg.Add(cpus)
- for i := 0; i < cpus; i++ {
- slice := makeSlice(result, i, cpus).(*image.NRGBA64)
- go func() {
- defer wg.Done()
- nearestNRGBA64(temp, slice, scaleY, coeffs, offset, filterLength)
- }()
- }
- wg.Wait()
- return result
- case *image.Gray:
- // 8-bit precision
- temp := image.NewGray(image.Rect(0, 0, input.Bounds().Dy(), int(width)))
- result := image.NewGray(image.Rect(0, 0, int(width), int(height)))
-
- // horizontal filter, results in transposed temporary image
- coeffs, offset, filterLength := createWeightsNearest(temp.Bounds().Dy(), taps, blur, scaleX)
- wg.Add(cpus)
- for i := 0; i < cpus; i++ {
- slice := makeSlice(temp, i, cpus).(*image.Gray)
- go func() {
- defer wg.Done()
- nearestGray(input, slice, scaleX, coeffs, offset, filterLength)
- }()
- }
- wg.Wait()
-
- // horizontal filter on transposed image, result is not transposed
- coeffs, offset, filterLength = createWeightsNearest(result.Bounds().Dy(), taps, blur, scaleY)
- wg.Add(cpus)
- for i := 0; i < cpus; i++ {
- slice := makeSlice(result, i, cpus).(*image.Gray)
- go func() {
- defer wg.Done()
- nearestGray(temp, slice, scaleY, coeffs, offset, filterLength)
- }()
- }
- wg.Wait()
- return result
- case *image.Gray16:
- // 16-bit precision
- temp := image.NewGray16(image.Rect(0, 0, input.Bounds().Dy(), int(width)))
- result := image.NewGray16(image.Rect(0, 0, int(width), int(height)))
-
- // horizontal filter, results in transposed temporary image
- coeffs, offset, filterLength := createWeightsNearest(temp.Bounds().Dy(), taps, blur, scaleX)
- wg.Add(cpus)
- for i := 0; i < cpus; i++ {
- slice := makeSlice(temp, i, cpus).(*image.Gray16)
- go func() {
- defer wg.Done()
- nearestGray16(input, slice, scaleX, coeffs, offset, filterLength)
- }()
- }
- wg.Wait()
-
- // horizontal filter on transposed image, result is not transposed
- coeffs, offset, filterLength = createWeightsNearest(result.Bounds().Dy(), taps, blur, scaleY)
- wg.Add(cpus)
- for i := 0; i < cpus; i++ {
- slice := makeSlice(result, i, cpus).(*image.Gray16)
- go func() {
- defer wg.Done()
- nearestGray16(temp, slice, scaleY, coeffs, offset, filterLength)
- }()
- }
- wg.Wait()
- return result
- default:
- // 16-bit precision
- temp := image.NewRGBA64(image.Rect(0, 0, img.Bounds().Dy(), int(width)))
- result := image.NewRGBA64(image.Rect(0, 0, int(width), int(height)))
-
- // horizontal filter, results in transposed temporary image
- coeffs, offset, filterLength := createWeightsNearest(temp.Bounds().Dy(), taps, blur, scaleX)
- wg.Add(cpus)
- for i := 0; i < cpus; i++ {
- slice := makeSlice(temp, i, cpus).(*image.RGBA64)
- go func() {
- defer wg.Done()
- nearestGeneric(img, slice, scaleX, coeffs, offset, filterLength)
- }()
- }
- wg.Wait()
-
- // horizontal filter on transposed image, result is not transposed
- coeffs, offset, filterLength = createWeightsNearest(result.Bounds().Dy(), taps, blur, scaleY)
- wg.Add(cpus)
- for i := 0; i < cpus; i++ {
- slice := makeSlice(result, i, cpus).(*image.RGBA64)
- go func() {
- defer wg.Done()
- nearestRGBA64(temp, slice, scaleY, coeffs, offset, filterLength)
- }()
- }
- wg.Wait()
- return result
- }
-
-}
-
-// Calculates scaling factors using old and new image dimensions.
-func calcFactors(width, height uint, oldWidth, oldHeight float64) (scaleX, scaleY float64) {
- if width == 0 {
- if height == 0 {
- scaleX = 1.0
- scaleY = 1.0
- } else {
- scaleY = oldHeight / float64(height)
- scaleX = scaleY
- }
- } else {
- scaleX = oldWidth / float64(width)
- if height == 0 {
- scaleY = scaleX
- } else {
- scaleY = oldHeight / float64(height)
- }
- }
- return
-}
-
-type imageWithSubImage interface {
- image.Image
- SubImage(image.Rectangle) image.Image
-}
-
-func makeSlice(img imageWithSubImage, i, n int) image.Image {
- return img.SubImage(image.Rect(img.Bounds().Min.X, img.Bounds().Min.Y+i*img.Bounds().Dy()/n, img.Bounds().Max.X, img.Bounds().Min.Y+(i+1)*img.Bounds().Dy()/n))
-}