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

The bar is not moving, and suggestions? #1

Open
sliday opened this issue Jul 30, 2019 · 7 comments
Open

The bar is not moving, and suggestions? #1

sliday opened this issue Jul 30, 2019 · 7 comments

Comments

@sliday
Copy link

sliday commented Jul 30, 2019

in
out

I simply launched main.go with this:
image

@nwtgck
Copy link
Owner

nwtgck commented Jul 30, 2019

@sliday Quite interesting... Thanks!

In my assumption, the moving of the GIF is the guy on the right corner, so GIF optimization stores only diff parts, in this case, the right guy. However, the position of the progress bar is on the bottom. Thus, the progress bar is not under diff part and gone.

I'll create a proof of concept.

@nwtgck
Copy link
Owner

nwtgck commented Jul 30, 2019

@sliday

Proof of concept

I changed the following code

package gif_progress
import (
"image/color"
"image/gif"
)
func AddProgressBar(inOutGif *gif.GIF, barTop bool, barHeight int, barColor color.RGBA) {
// NOTE: inOutGif is changed destructively
width := inOutGif.Config.Width
height := inOutGif.Config.Height
image_len := len(inOutGif.Image)
for i, paletted := range inOutGif.Image {
w := int(float32(width) * ((float32(i)+1)/float32(image_len)))
for x := 0; x < w; x++ {
for h := 0; h < barHeight; h++ {
var y = h
if !barTop {
y = height - h
}
paletted.Set(x, y, barColor)
}
}
}
}

into the following.

package gif_progress

import (
	"image"
	"image/color"
	"image/gif"
)

func AddProgressBar(inOutGif *gif.GIF, barTop bool, barHeight int, barColor color.RGBA) {
	// NOTE: inOutGif is changed destructively
	width := inOutGif.Config.Width
	height := inOutGif.Config.Height
	image_len := len(inOutGif.Image)
	//outGif := gif.GIF{Delay: inOutGif.Delay, LoopCount: inOutGif.LoopCount, Disposal}
	for i, paletted := range inOutGif.Image {
		w := int(float32(width) * ((float32(i)+1)/float32(image_len)))

		bounds := image.Rect(0, 0, width, height)
		// Get whole image not only diff
		wholeImage := paletted.SubImage(bounds)
		// Create new empty paletted
		newPaletted := image.NewPaletted(bounds, paletted.Palette)
		// Copy whole image to the new paletted
		for x := 0; x < width; x++ {
			for y := 0; y < height; y++ {
				newPaletted.Set(x, y, wholeImage.At(x, y))
			}
		}
		// Attach progress bar
		for x := 0; x < w; x++ {
			for h := 0; h < barHeight; h++ {
				var y = h
				if !barTop {
					y = height - h
				}
				newPaletted.Set(x, y, barColor)
			}
		}

		inOutGif.Image[i] = newPaletted
	}
}

Then, I got the following GIF. Sorry for ver blinking, but I got the progress bar.
out

As you know, this output GIF is not perfect I have to remove the green parts. I'm investigating how to remove.

@nwtgck
Copy link
Owner

nwtgck commented Jul 30, 2019

No blinking

Finally, I got animated GIF without blinking!

Code

Some part may be unnecessary.

package gif_progress

import (
	"image"
	"image/color"
	"image/gif"
)

func AddProgressBar(inOutGif *gif.GIF, barTop bool, barHeight int, barColor color.RGBA) {
	// NOTE: inOutGif is changed destructively
	width := inOutGif.Config.Width
	height := inOutGif.Config.Height
	imageLen := len(inOutGif.Image)
	// Image size
	imageSize := image.Rect(0, 0, width, height)
	// Previous frame
	previousImage := inOutGif.Image[0].SubImage(imageSize)
	firstPalette := inOutGif.Image[0].Palette
	for i, paletted := range inOutGif.Image {
		// Create new empty paletted
		newPaletted := image.NewPaletted(imageSize, firstPalette)
		// Copy previous frame to the new paletted
		for x := 0; x < width; x++ {
			for y := 0; y < height; y++ {
				newPaletted.Set(x, y, previousImage.At(x, y))
			}
		}
		// Copy whole image to the new paletted
		rect := paletted.Rect
		for x := rect.Min.X; x < rect.Max.X; x++ {
			for y := rect.Min.Y; y < rect.Max.Y; y++ {
				newPaletted.Set(x, y, paletted.At(x, y))
			}
		}
		// Save as previous
		previousImage = newPaletted.SubImage(imageSize)

		// Attach progress bar
		w := int(float32(width) * ((float32(i)+1)/float32(imageLen)))
		for x := 0; x < w; x++ {
			for h := 0; h < barHeight; h++ {
				var y = h
				if !barTop {
					y = height - h
				}
				newPaletted.Set(x, y, barColor)
			}
		}

		inOutGif.Image[i] = newPaletted
	}
}

Generated GIF

out

Problem

Because the frame has whole size pixels without using diff, the file size of the output is larger than the input and it takes more time. I want to solve this issue before creating PR.

branch: https://github.com/nwtgck/gif-progress/tree/feature/fix-not-moving-progress-bar

@sliday
Copy link
Author

sliday commented Jul 30, 2019 via email

@jasonraimondi
Copy link

I've gone and compiled the fix-not-moving-progress-bar branch in an attempt to resolve the same issue on one of my photos. I wanted to share how the photo came out, perhaps it may help you.

Original:
original

Converted with master branch:
converted-master-branch

Converted with fix-not-moving-progress-bar branch:
converted-fix-not-moving-progress-bar-branch

@nwtgck
Copy link
Owner

nwtgck commented Aug 30, 2019

@jasonraimondi Thank you very much! Your images are very helpful to investigate the issue.

@nwtgck
Copy link
Owner

nwtgck commented Sep 16, 2019

I attached a tag to the working branch to fix this issue.
Executable binaries are available in

You can check the latest behavior easily. Note that the tag will be dynamically changed if the branch is updated.

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

3 participants