Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resizing animated images leads to a toilet roll in some scale values #350

Open
apiks opened this issue Apr 20, 2023 · 0 comments
Open

Resizing animated images leads to a toilet roll in some scale values #350

apiks opened this issue Apr 20, 2023 · 0 comments

Comments

@apiks
Copy link

apiks commented Apr 20, 2023

I'm trying to resize a 500x280 GIF via the Resize function. If the scale parameter is a multiple of 5 (e.g. 0.1, 0.15 or 0.2) it works fine in unrolling the GIF.

The problem is when the scale has isn't a multiple of 5 (e.g. 0.14, 0.22 or 0.66) it can't unroll. It will always return a roll.

This behavior is only for two decimals. With more decimals it becomes even more confusing as 0.265 doesn't work either. Maybe due to the 6 in it?

After fiddling with it for a bit, rounding the scale or forcing a multiple fixes the issue, but also does not allow for the intended scale on the final image.

Additionally I've noticed that in the ResizeWithVScale function it calculates the new page height with int(float64(pageHeight) * scale) which forces it to drop the decimal if it exists. Perhaps this is causing the issue? LibVips takes an int so I understand why it's done.

This only happens with animated images (tested only on GIF). Non-animated images work fine, likely due to their height always being an integer.

To replicate this issue, take a GIF with a width of 500 and try resizing it to the above mentioned scales.

Here's the logic I'm using to resize the GIF:

func resizeImage(img *vips.ImageRef, width, height int, upscale bool) (*vips.ImageRef, error) {
	if width == 0 && height == 0 {
		return img, nil
	}

	if width == 0 {
		scale := float64(height) / float64(img.PageHeight())
		if upscale || scale <= 1 {
			err := img.Resize(scale, vips.KernelAuto)
			if err != nil {
				return nil, err
			}
		}
		return img, nil
	}

	if height == 0 {
		scale := float64(width) / float64(img.Width())
		if upscale || scale <= 1 {
			err := img.Resize(scale, vips.KernelAuto)
			if err != nil {
				return nil, err
			}
		}
		return img, nil
	}

	hScale := float64(width) / float64(img.Width())
	vScale := float64(height) / float64(img.PageHeight())
	if upscale || (hScale <= 1 && vScale <= 1) {
		err := img.ResizeWithVScale(hScale, vScale, vips.KernelAuto)
		if err != nil {
			return nil, err
		}
	}

	return img, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant