在Go语言中修改gif图像时,透明度设置不正确。

huangapple go评论91阅读模式
英文:

Modifying a gif image in go...not setting transparency correctly

问题

我有一些代码执行以下逻辑操作:

  • 使用gif.DecodeAll读取和解码gif图像为*GIF
  • 使用image.Set修改*GIF中每帧的一些像素
  • 使用gif.EncodeAll将修改后的图像写出

以下是一些代码片段,以帮助演示代码的功能(为简洁起见,省略了错误处理、文件关闭等):

f, err := os.Open(filename)
reader := bufio.NewReader(f)
g, err := gif.DecodeAll(reader)
err = modify_image(g)

of, err := os.Create("out.gif")
writer := bufio.NewWriter(of)
err = gif.EncodeAll(writer, g)

这是modify_image函数:

func modify_image(img *gif.GIF) error {
	for i := 0; i < len(img.Image); i++ {
		err := modify_frame(img.Image[i])
	}
	return nil
}

以及modify_frame函数:

func modify_frame(frame *image.Paletted) error {
	xmin := frame.Rect.Min.X
	ymin := frame.Rect.Min.Y
	xmax := frame.Rect.Max.X
	ymax := frame.Rect.Max.Y

	for y := ymin; y < ymax; y++ {
		for x := xmin; x < xmax; x++ {
			if should_turn_pixel_transparent(frame, x, y) {
				frame.Set(x, y, color.RGBA64{0, 0, 0, 0})
			}
		}
	}
	return nil
}

这段代码生成的out.gif将正确地将像素转为透明,但随着动画的进行,我将转为透明的像素并没有"清除";也就是说,当这些透明像素覆盖在非透明像素上时,底下的非透明像素仍然显示出来。

我(简要)了解到gif图像有两种不同的透明表示方法。我不知道是否需要使用索引透明度还是alpha透明度,或者我完全做错了什么。任何建议都将不胜感激。

英文:

I have some code which performs the following logical operations:

  • Read in and decode a gif image to a *GIF using gif.DecodeAll
  • Modify some pixels in each frame of the *GIF using image.Set
  • Write out the resulting modified image using gif.EncodeAll

Here's some code snippets to help demonstrate what the code is doing (error handling, file closing, etc removed for brevity):

f, err := os.Open(filename)
reader := bufio.NewReader(f)
g, err := gif.DecodeAll(reader)
err = modify_image(g)

of, err := os.Create(&quot;out.gif&quot;)
writer := bufio.NewWriter(of)
err = gif.EncodeAll(writer, g)

Here's the modify_image function:

func modify_image(img *gif.GIF) error {
	for i := 0; i &lt; len(img.Image); i++ {
		err := modify_frame(img.Image[i])
	}
	return nil
}

And modify_frame:

func modify_frame(frame *image.Paletted) error {
	xmin := frame.Rect.Min.X
	ymin := frame.Rect.Min.Y
	xmax := frame.Rect.Max.X
	ymax := frame.Rect.Max.Y

	for y := ymin; y &lt; ymax; y++ {
		for x := xmin; x &lt; xmax; x++ {
			if should_turn_pixel_transparent(frame, x, y) {
				frame.Set(x, y, color.RGBA64{0, 0, 0, 0})
			}
		}
	}
	return nil
}

The out.gif that this code produces has the correct pixels turned transparent, but as the animation proceeds, the pixels which I turned transparent are not "clearing"; i.e. as these transparent pixels are written over non-transparent pixels, the non-transparent pixels underneath are still displayed.

My (brief) understanding is that there are two different methods for representing transparency in gifs. I don't know if I need to use index transparency versus alpha transparency, or if I'm just doing things entirely wrong. Any advice would be appreciated.

答案1

得分: 4

这在各种生成gif的golang教程中经常被省略或不涉及,但是除了为gif的每一帧在Image切片中设置延迟Delay之外,为每一帧设置Disposal也是可选的。如果切片中没有与当前帧索引对应的成员,则使用DisposalNone。

Disposal选项如下:

const (
	DisposalNone       = 0x01 // 不处理前一帧
	DisposalBackground = 0x02 // 处理前一帧中由GIF.BackgroundIndex定义的特定颜色
	DisposalPrevious   = 0x03 // 处理前一帧
)

以下是每种处理方式的结果gif。

DisposalNone:
在Go语言中修改gif图像时,透明度设置不正确。

DisposalBackground:
在Go语言中修改gif图像时,透明度设置不正确。

DisposalPrevious:
在Go语言中修改gif图像时,透明度设置不正确。

英文:

This is often omitted or not covered in various golang tutorials for generating gifs, but along with setting the delay Delay slice for each frame in the Image slice, it is also optional to set Disposal for each frame of the gif. DisposalNone is used of the slice does not have a member corresponding to the current frame index.

Disposal options are:

const (
	DisposalNone       = 0x01 // dont dispose of previous frames
	DisposalBackground = 0x02 // dispose of specific colour in previous frames defined by GIF.BackgroundIndex
	DisposalPrevious   = 0x03 // dispose of the previous frame
)

The following is the resulting gif for each type of disposal.

DisposalNone:
在Go语言中修改gif图像时,透明度设置不正确。

DisposalBackground:
在Go语言中修改gif图像时,透明度设置不正确。

DisposalPrevious:
在Go语言中修改gif图像时,透明度设置不正确。

huangapple
  • 本文由 发表于 2014年1月2日 06:28:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/20873955.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定