diff --git a/resize.go b/resize.go index 7b2cffc..77bfbfc 100644 --- a/resize.go +++ b/resize.go @@ -403,11 +403,11 @@ func imageCalculations(o *Options, inWidth, inHeight int) float64 { // Fixed width, auto height case o.Width > 0: factor = xfactor - o.Height = int(math.Floor(float64(inHeight) / factor)) + o.Height = roundFloat(float64(inHeight) / factor) // Fixed height, auto width case o.Height > 0: factor = yfactor - o.Width = int(math.Floor(float64(inWidth) / factor)) + o.Width = roundFloat(float64(inWidth) / factor) // Identity transform default: o.Width = inWidth @@ -418,6 +418,14 @@ func imageCalculations(o *Options, inWidth, inHeight int) float64 { return factor } +func roundFloat(f float64) int { + if f < 0 { + return int(math.Ceil(f - 0.5)) + } else { + return int(math.Floor(f + 0.5)) + } +} + func calculateCrop(inWidth, inHeight, outWidth, outHeight int, gravity Gravity) (int, int) { left, top := 0, 0 diff --git a/resize_test.go b/resize_test.go index f8b6c10..4b8b4c1 100644 --- a/resize_test.go +++ b/resize_test.go @@ -1,6 +1,9 @@ package bimg import ( + "bytes" + "image" + "image/jpeg" "io/ioutil" "os" "path" @@ -112,6 +115,24 @@ func TestResizeCustomSizes(t *testing.T) { } } +func TestResizePrecision(t *testing.T) { + // see https://github.com/h2non/bimg/issues/99 + img := image.NewGray16(image.Rect(0, 0, 1920, 1080)) + input := &bytes.Buffer{} + jpeg.Encode(input, img, nil) + + opts := Options{Width: 300} + newImg, err := Resize(input.Bytes(), opts) + if err != nil { + t.Fatalf("Resize(imgData, %#v) error: %#v", opts, err) + } + + size, _ := Size(newImg) + if size.Width != opts.Width { + t.Fatalf("Invalid width: %d", size.Width) + } +} + func TestRotate(t *testing.T) { options := Options{Width: 800, Height: 600, Rotate: 270, Crop: true} buf, _ := Read("fixtures/test.jpg")