GOOGLE ADS

среда, 13 апреля 2022 г.

Изменение изображения gif в go... неправильная настройка прозрачности

У меня есть код, который выполняет следующие логические операции:


  • Считайте и декодируйте изображение 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 для каждого типа утилизации.

УтилизацияНет:
gif.DisposalNone

УтилизацияФон:
gif.DisposalBackground

УтилизацияПредыдущий:
gif.DisposalPrevious

Комментариев нет:

Отправить комментарий

Laravel Datatable addColumn returns ID of one record only

Я пытаюсь использовать Yajra Datatable для интеграции DataTable на свой веб-сайт. Я смог отобразить таблицу, но столкнулся с проблемой. В по...