Настройка оттенка и насыщенности на всех кадрах GIF-файла

1
7

Я пытаюсь применить эффекты оттенка и насыщенности ко всем кадрам gif-файла с помощью этой библиотеки.

Функции adjust.Hue() и adjust.Saturation() принимают *image.RGBA, поэтому я преобразую кадры gif-файла *image.Paletted в *image.RGBA, применяю фильтры, а затем преобразую их обратно в *image.Paletted.

Фильтры, похоже, работают, однако кадры искажены.

Входные данные:

Вывод:

Вот мой code:

В чем может быть проблема?

package main

import (
    "image"
    "image/color"
    "image/draw"
    "image/gif"
    "log"
    "os"

    "github.com/anthonynsimon/bild/adjust"
)

type ImageData struct {
    Hue        int
    Saturation float64
}

func ProcessGif(inputPath string, outputPath string, imageData ImageData) error {
    file, err := os.Open(inputPath)
    if err != nil {
        return err
    }
    defer file.Close()

    gifImage, err := gif.DecodeAll(file)
    if err != nil {
        return err
    }

    // Process each frame
    for i, img := range gifImage.Image {
        // Convert *image.Paletted to *image.RGBA
        rgba := PalettedToRGBA(img)

        // Apply adjustments
        rgba = adjust.Hue(rgba, imageData.Hue)
        rgba = adjust.Saturation(rgba, imageData.Saturation)

        // Convert *image.RGBA to *image.Paletted
        gifImage.Image[i] = RGBAToPaletted(rgba)

    }

    outputFile, err := os.Create(outputPath)
    if err != nil {
        return err
    }
    defer outputFile.Close()

    return gif.EncodeAll(outputFile, gifImage)
}

func PalettedToRGBA(paletted *image.Paletted) *image.RGBA {
    bounds := paletted.Bounds()
    rgba := image.NewRGBA(bounds)
    draw.Draw(rgba, bounds, paletted, image.Point{}, draw.Over)
    return rgba
}

func RGBAToPaletted(rgba *image.RGBA) *image.Paletted {
    bounds := rgba.Bounds()
    // Extract the unique colors from the RGBA image
    palette := color.Palette{}
    for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
        for x := bounds.Min.X; x < bounds.Max.X; x++ {
            c := rgba.At(x, y)
            if !sliceIncludes(palette, c) {
                palette = append(palette, c)
            }
        }
    }
    // Create the Paletted image with the constructed palette
    paletted := image.NewPaletted(bounds, palette)
    draw.Draw(paletted, bounds, rgba, image.Point{}, draw.Over)
    return paletted
}

func sliceIncludes[T comparable](slice []T, t T) bool {
    for _, c := range slice {
        if c == t {
            return true
        }
    }
    return false
}

func main() {
    imgData := ImageData{
        Hue:        80,
        Saturation: 0.4,
    }
    log.Fatal(ProcessGif("image.gif", "output.gif", imgData))
}
Мефодий
Вопрос задан12 июня 2024 г.

1 Ответ

Ваш ответ

Загрузить файл.