h2non / bimg

Go package for fast high-level image processing powered by libvips C library
https://pkg.go.dev/github.com/h2non/bimg?tab=doc
MIT License
2.73k stars 341 forks source link

Incorrect manipulating with image sizes in resizer with latest libvips versions #263

Open Arimeka opened 6 years ago

Arimeka commented 6 years ago

Suppose we have a jpeg with a size of 1440x959 and we want to get an image from it with a size of 265x200 with cropping using nearest neighbor interpolator.

We going to resizer.go#L73 with factor = 4.795000 (959/200 = 4.795) and shrink = 4

In libvips before 8.6.0

vips_jpegload("1440x959.jpg", out, "shrink", 4, NULL); // or vips_jpegload_buffer

produce image with size 360x240. In libvips after 8.6.0 it produce image with size 360x239. I don’t know if it’s a bug or a feature, but according libvips wiki

It's best to use jpeg shrink-on-load to make an image about 2x larger than your final output size and then do a further shrink with something more sophisticated

Now we go here resizer.go#L92 and have shrink = 1 and residual = 0.834202.

In transformImage() we go to resizer.go#L206 with 1/residualx = 1.198750 and 1/residualy = 1.198750. And here the problems begin: 239/1.198750 = 199.37 and we get a smaller image than requested.

The same problem can produce black lines on the image when resizing while keeping same aspect ratio.

Arimeka commented 6 years ago

It looks like always rounding to smaller number is the right behavior (kinda)- https://github.com/libvips/libvips/commit/d1dd41a21fe8251dd57d9069ae388e1b7ae30764