Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
FM effect!
#1
A reddit user known as velocityvector2 recently posted this animation 

FM effect : r/glitch_art

which is pretty neat, and included the GoLang source code:

Code: (Select All)
package main

import (
    "image"
    "image/color"
    "math"

    "github.com/anthonynsimon/bild/blend"
    "github.com/anthonynsimon/bild/fcolor"
    "github.com/anthonynsimon/bild/imgio"
    "github.com/anthonynsimon/bild/transform"
    "github.com/setanarut/apng"
)

func processImageFrames(img image.Image, freqMultiplier float64, frameCount int) []image.Image {
    bounds := img.Bounds()
    width, height := bounds.Max.X, bounds.Max.Y
    frames := make([]image.Image, frameCount)
    minOmega := 2 * math.Pi / (0.05 * float64(width))
    baseOmega := minOmega * freqMultiplier
    for frame := range frames {
        destImg := image.NewRGBA(bounds)
        frames[frame] = destImg
        // Time progression - normalized value for the loop (between 0-1)
        timeOffset := float64(frame) / float64(frameCount) * 2 * math.Pi * 1
        for y := range height {
            rf := 0.0
            gf := 0.0
            bf := 0.0
            for x := range width {
                r, g, b, _ := img.At(x, y).RGBA()

                rf += float64(r)/65535.0 - 1
                gf += float64(g)/65535.0 - 1
                bf += float64(b)/65535.0 - 1

                // Add time progression
                rm := math.Cos(baseOmega*float64(x) + rf + timeOffset)
                gm := math.Cos(baseOmega*float64(x) + gf + timeOffset)
                bm := math.Cos(baseOmega*float64(x) + bf + timeOffset)

                // Remap signal back to channel value
                rv := uint8(min(max((rm+1)*127.5, 0), 255))
                gv := uint8(min(max((gm+1)*127.5, 0), 255))
                bv := uint8(min(max((bm+1)*127.5, 0), 255))

                destImg.SetRGBA(x, y, color.RGBA{rv, gv, bv, 255})
            }
        }
    }
    for i := range frames {
        frames[i] = blend.Blend(frames[i], img, HardMix)
        frames[i] = transform.Resize(frames[i], width/2, height/2, transform.CatmullRom)

    }
    return frames
}

func main() {
    img, _ := imgio.Open("input.jpg")
    frames := processImageFrames(img, 5, 8)
    apng.Save("out.png", frames, 7)
}

func HardMix(c1, c2 fcolor.RGBAF64) (result fcolor.RGBAF64) {
    f := func(i, j float64) float64 {
        if j < 1-i {
            return 0
        }
        return 1
    }
    result.R = f(c1.R, c2.R)
    result.G = f(c1.G, c2.G)
    result.B = f(c1.B, c2.B)
    result.A = 1
    return result
}
Is anyone familiar with Go or want to try translating it to QB64PE? 
I tracked down the libraries, which apparently are freely available:

"github.com/anthonynsimon/bild/blend"
anthonynsimon/bild/tree/master/blend
or
anthonynsimon/bild/blend

"github.com/anthonynsimon/bild/fcolor"
anthonynsimon/bild/tree/master/fcolor

"github.com/anthonynsimon/bild/imgio"
anthonynsimon/bild/tree/master/imgio
or
anthonynsimon/bild/blob/master/imgio

"github.com/anthonynsimon/bild/transform"
anthonynsimon/bild/tree/master/transform

"github.com/setanarut/apng"
setanarut/apng

This is as far as I got... 

Code: (Select All)
' func processImageFrames(img image.Image, freqMultiplier float64, frameCount int) []image.Image {
Function processImageFrames&(img&, freqMultiplier##, frameCount%)
    'bounds := img.Bounds()
    'width, height := bounds.Max.X, bounds.Max.Y
    width = _WIDTH(img) : height = _HEIGHT(img)
   
    ' SEEMS TO RETURN AN ARRAY OF IMAGES, NOT JUST ONE IMAGE:
    frames := make([]image.Image, frameCount)
I'm a bit out of my depth with this stuff, but I thought maybe one of the geniuses here would have fun with it.
Reply


Messages In This Thread
FM effect! - by madscijr - 05-05-2025, 05:44 PM



Users browsing this thread: 1 Guest(s)