Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upSize of gif increases after processing with Vips::Image.thumbnail #244
Comments
|
Hello @chloe-meister, I think that's just the way it is. GIF optimisation is a very manual process. If your source GIF has been carefully tuned, you'll need to do the same amount of tuning to get a small thumbnail from it. |
|
I'll have a quick look inside the GIF, it's an interesting test image. |
|
I understand. Thanks for the quick answer and for looking at the gif. Hopefully you can find something interesting out of it |
|
Actually, it seems to be working OK for me. I tried:
So the size stays low. However, if I shrink I see:
What's happening is that the shrink operation also slightly sharpens. Your original GIF has perfect flat edges that compress well, but the raised edges on the shrunk version need more bytes to represent. I don't think there's much that can be done about this, unfortunately. |
|
I also tried just loading and saving the image:
and indeed the size stays low. As you pointed out, the issue is with shrinking. The increase in file size makes sense given that it's sharpening as well. Thank you very much for the clarifications |
|
Just wondering. Is it possible to make a thumbnail with another kernel? Such as "nearest" that won't mix colors. |
|
Yes, You can do the thumbnailing yourself since it's pretty easy with GIF. Something like: #!/usr/bin/ruby
require 'vips'
image = Vips::Image.new_from_file ARGV[0], access: :sequential, n: -1
target_size = ARGV[2].to_i
# image.height will be for all frames -- we want the height of one page. If
# page-height is missing, default to image height
page_height = if image.get_typeof("page-height") != 0
image.get("page-height")
else
image.height
end
# we now know the number of pages in the animation
n_loaded_pages = image.height / page_height
# resize to fit a inside target_size by target_size box
scale = [target_size.to_f / image.width, target_size.to_f / page_height].min
# adjust the scale so that we hit the image.height exactly, or we'll hae frames
# that vary in size
target_height = (page_height * scale).round
scale = (target_height.to_f * n_loaded_pages) / image.height
# normally you'd need to premultiply around resize, but :nearest does not mix
# pixels, so there's no need
image = image.resize scale, kernel: :nearest
# we need to set the new page_height
image = image.copy
image.set "page-height", target_height
image.write_to_file ARGV[1],
optimize_gif_frames: true, optimize_gif_transparency: trueRunning:
ie. a 20% shrink makes: 1.34mb, so it's smaller. Nearest will give nasty artifacts with large reductions, of course, eg.:
You can see there are odd "sparkle" effects: |
|
Thank you so much, works a treat! |
|
Hmmm, I don't understand the reason of sparkles. It's kind of divided on even and odd frames. Maybe it's related to this particular gif or encoder does something different on even/odd phases. In theory shrinking 4x should be the same as shrinking twice by 2x. |
|
A 8x nearest-neighbour shrink is just taking every 8th pixel, so you get horrible aliasing. You could use a triangle filter instead, but they look very soft, and the mushy edges would be hard to compress. |
|
If that can help, when I tried thumbnailing as above with large reductions I didn't get the sparkles but the last frames have got many white parts in them, as shown with the file attached. My implementation is really close to @jcupitt 's above:
Called by:
|
|
I was using 8.10 and it has some fixes to the GIF loader. You'll need to add a |
|
Thanks for clarifying, I wondered why the |



Hi there!
I'm using Vips::Image.thumbnail to resize gif images and I noticed that for some gifs, the size after resizing is much bigger than before.
My code:
As an example, the gif attached is 1.9MB, and after processing by the code above it's 4.88MB.

I've tried changing the quality in
magicksave:with x = 0, 1, 50 and 100 but it didn't make any difference.
I wonder what I could be missing?
Many thanks!
Chloe