GOOGLE ADS

Samstag, 30. April 2022

Ändern eines GIF-Bildes in go ... Transparenz wird nicht richtig eingestellt

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 ImageSlice ist es auch erforderlich, Disposalfür jeden Frame des GIFs eine Einstellung vorzunehmen. DisposalNonewird 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:
gif.EntsorgungKeine

EntsorgungHintergrund:
gif.DisposalBackground

EntsorgungBisher:
gif.EntsorgungPrevious

Keine Kommentare:

Kommentar veröffentlichen

Warum werden SCHED_FIFO-Threads derselben physischen CPU zugewiesen, obwohl CPUs im Leerlauf verfügbar sind?

Lösung des Problems Wenn ich das richtig verstehe, versuchen Sie, SCHED_FIFO mit aktiviertem Hyperthreading ("HT") zu verwenden, ...