英文:
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("out.gif")
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 < 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 < 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
}
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。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论