У меня есть код, который выполняет следующие логические операции:
- Считайте и декодируйте изображение gif в * GIF, используя gif.DecodeAll
- Измените некоторые пиксели в каждом кадре *GIF, используя image.Set
- Запишите полученное измененное изображение, используя 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)
Вот функция mod_image:
func modify_image(img *gif.GIF) error {
for i:= 0; i < len(img.Image); i++ {
err:= modify_frame(img.Image[i])
}
return nil
}
И изменить_фрейм:
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. Я не знаю, нужно ли мне использовать индексную прозрачность по сравнению с альфа-прозрачностью, или я просто делаю что-то совершенно неправильно. Любой совет будет принят во внимание.
Решение проблемы
Это часто опускается или не освещается в различных руководствах по созданию гифок, но наряду с установкой Delayслайса задержки для каждого кадра в слайсе Imageтакже требуется установить Disposalдля каждого кадра гифки. DisposalNoneиспользуется, если срез не имеет члена, соответствующего текущему индексу кадра.
Варианты утилизации:
const (
DisposalNone = 0x01
DisposalBackground = 0x02
DisposalPrevious = 0x03
)
Ниже приведен результат GIF для каждого типа утилизации.
УтилизацияНет:
УтилизацияФон:
УтилизацияПредыдущий:
Комментариев нет:
Отправить комментарий