Skip to content

Commit

Permalink
Changed from draw to native function
Browse files Browse the repository at this point in the history
  • Loading branch information
leon-wolf authored and leon3103 committed Jan 29, 2020
1 parent af66474 commit 40d7f54
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 55 deletions.
62 changes: 30 additions & 32 deletions resize.go
Original file line number Diff line number Diff line change
@@ -1,45 +1,43 @@
package canvas

import (
"golang.org/x/image/draw"
"image"
"math"
)

type InterpolationFunction int
func Resize(img image.Image, newWidth int, newHeight int, intFunc string) image.Image {

// InterpolationFunction constants
const (
Bilinear InterpolationFunction = iota
CatmullRom
)

// kernal, returns an InterpolationFunctions taps and kernel.
func (i InterpolationFunction) kernel() *draw.Kernel {
switch i {
case Bilinear:
return draw.BiLinear
case CatmullRom:
return draw.CatmullRom
if newWidth == 0 && newHeight == 0 {
newWidth = img.Bounds().Dx()
newHeight = img.Bounds().Dy()
} else if newWidth == 0 && newHeight != 0 {
newWidth = img.Bounds().Dx() / img.Bounds().Dy() * newHeight
} else if newWidth != 0 && newHeight == 0 {
newHeight = img.Bounds().Dy() / img.Bounds().Dx() * newWidth
}
// perform resizing
switch intFunc {
case "NearestNeighbor":
return ScaleNearestNeighbor(img, newWidth, newHeight)
default:
return draw.CatmullRom
return ScaleNearestNeighbor(img, newWidth, newHeight)
}
}

func Resize(img image.Image, width int, height int, intFunc InterpolationFunction) (image.Image, error) {

if width == 0 && height == 0 {
width = img.Bounds().Dx()
height = img.Bounds().Dy()
} else if width == 0 && height != 0 {
width = img.Bounds().Dx() / img.Bounds().Dy() * height
} else if width != 0 && height == 0 {
height = img.Bounds().Dy() / img.Bounds().Dx() * width
func ScaleNearestNeighbor(img image.Image, newWidth int, newHeight int) image.Image {
targetRect := image.Rect(0, 0, newWidth, newHeight)
targetImg := image.NewNRGBA(targetRect)
width := img.Bounds().Dx()
height := img.Bounds().Dy()
for x := 0; x <= width; x++ {
for y := 0; y <= height; y++ {
srcX := int(math.Round(float64(x) / float64(newWidth) * float64(width)))
srcY := int(math.Round(float64(y) / float64(newHeight) * float64(height)))
srcX = int(math.Min(float64(srcX), float64(width-1)))
srcX = int(math.Min(float64(srcY), float64(height-1)))
tarPixel := img.At(srcX, srcY)
targetImg.Set(x, y, tarPixel)
}
}
// new size of image
dstRect := image.Rect(0, 0, width, height)
// perform resizing
dstImg := image.NewRGBA(dstRect)
intFunc.kernel().Scale(dstImg, dstRect, img, img.Bounds(), draw.Over, nil)

return dstImg, nil
return targetImg
}
47 changes: 24 additions & 23 deletions resize_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,45 +9,46 @@ import (
)

var img = image.NewNRGBA(image.Rect(0, 0, 5, 5))
var kernels = []InterpolationFunction{CatmullRom, Bilinear}

func init() {
runtime.GOMAXPROCS(runtime.NumCPU())
img.Set(5, 5, color.Black)
}

func Test_NNScale(t *testing.T) {
newImg := Resize(img, 100, 100, "NearestNeighbor")
if newImg.Bounds().Dx() != 100 || newImg.Bounds().Dy() != 100 {
t.Fail()
}
}

func Test_SameSize(t *testing.T) {
for _, kernel := range kernels {
newImg, _ := Resize(img, 0, 0, kernel)
if newImg.Bounds() != img.Bounds() {
log.Print(img.Bounds().Dx(), "x", img.Bounds().Dy())
log.Print(newImg.Bounds().Dx(), "x", newImg.Bounds().Dy())
t.Fail()
}

newImg := Resize(img, 0, 0, "NearestNeighbor")
if newImg.Bounds() != img.Bounds() {
log.Print(img.Bounds().Dx(), "x", img.Bounds().Dy())
log.Print(newImg.Bounds().Dx(), "x", newImg.Bounds().Dy())
t.Fail()
}

}

func Test_Height(t *testing.T) {
for _, kernel := range kernels {
newImg, err := Resize(img, 0, 100, kernel)
if err != nil || newImg.Bounds().Dy() != 100 || newImg.Bounds().Dx() != 100 {
t.Fail()
}

newImg := Resize(img, 0, 100, "NearestNeighbor")
if newImg.Bounds().Dy() != 100 || newImg.Bounds().Dx() != 100 {
t.Fail()
}
}
func Test_Width(t *testing.T) {
for _, kernel := range kernels {
newImg, err := Resize(img, 200, 0, kernel)
if err != nil || newImg.Bounds().Dy() != 200 || newImg.Bounds().Dx() != 200 {
t.Fail()
}
newImg := Resize(img, 200, 0, "NearestNeighbor")
if newImg.Bounds().Dy() != 200 || newImg.Bounds().Dx() != 200 {
t.Fail()
}
}
func Test_WidthAndHeight(t *testing.T) {
for _, kernel := range kernels {
newImg, err := Resize(img, 300, 300, kernel)
if err != nil || newImg.Bounds() != image.Rect(0, 0, 300, 300) {
t.Fail()
}
newImg := Resize(img, 300, 300, "NearestNeighbor")
if newImg.Bounds() != image.Rect(0, 0, 300, 300) {
t.Fail()
}
}

0 comments on commit 40d7f54

Please sign in to comment.