05-05-2025, 05:44 PM
(This post was last modified: 05-05-2025, 05:45 PM by madscijr.
Edit Reason: fixed typo
)
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:
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...
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.
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
}
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)