Я пытаюсь применить эффекты оттенка и насыщенности ко всем кадрам 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 г.