Ich habe einen Code, der die folgenden logischen Operationen ausführt:
- Ein GIF-Bild einlesen und mit gif.DecodeAll in ein *GIF decodieren
- Ändern Sie einige Pixel in jedem Frame des *GIF mit image.Set
- Schreiben Sie das resultierende modifizierte Bild mit gif.EncodeAll aus
Hier sind einige Codeschnipsel, die zeigen, was der Code tut (Fehlerbehandlung, Schließen von Dateien usw. wurden der Kürze halber entfernt):
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)
Hier ist die modify_image-Funktion:
func modify_image(img *gif.GIF) error {
for i:= 0; i < len(img.Image); i++ {
err:= modify_frame(img.Image[i])
}
return nil
}
Und 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
}
Das out.gif, das dieser Code erzeugt, hat die richtigen Pixel transparent gemacht, aber während die Animation fortschreitet, werden die Pixel, die ich transparent gemacht habe, nicht "gelöscht"; dh wenn diese transparenten Pixel über nicht transparente Pixel geschrieben werden, werden die darunter liegenden nicht transparenten Pixel immer noch angezeigt.
Mein (kurzes) Verständnis ist, dass es zwei verschiedene Methoden gibt, um Transparenz in Gifs darzustellen. Ich weiß nicht, ob ich Index-Transparenz im Vergleich zu Alpha-Transparenz verwenden muss oder ob ich nur Dinge völlig falsch mache. Jeder Rat wäre willkommen.
Lösung des Problems
Dies wird in verschiedenen Golang-Tutorials zum Generieren von GIFs oft weggelassen oder nicht behandelt, aber neben dem Einstellen des Verzögerungs Delay
-Slices für jeden Frame im Image
Slice ist es auch erforderlich, Disposal
für jeden Frame des GIFs eine Einstellung vorzunehmen. DisposalNone
wird verwendet, wenn das Slice kein Mitglied hat, das dem aktuellen Frame-Index entspricht.
Entsorgungsmöglichkeiten sind:
const (
DisposalNone = 0x01
DisposalBackground = 0x02
DisposalPrevious = 0x03
)
Das Folgende ist das resultierende GIF für jede Entsorgungsart.
EntsorgungKeine:
EntsorgungHintergrund:
EntsorgungBisher:
Keine Kommentare:
Kommentar veröffentlichen