So I was messing around with Racket’s new excellent flomap module, and I came up with a script that turns images into televised versions of themselves.
The results of this look like:
You’ll need Racket 5.3 to use this. Call it like this:
(televise (make-object bitmap% "some-filename.png"))
and you’ll get a bitmap% that you can then save to a file or display in DrRacket.
#lang racket
(require images/flomap
racket/draw
images/icons/style)
;; Turns 'bitmap' into an old CRT television-like version of itself.
(define (televise bitmap
#:color-offset [color-offset 2]
#:lens-bend [lens-bend (* 2/3 pi)])
(define imgfm (fmsqr (bitmap->flomap bitmap)))
;; fake gamma control
(define noise-offset-big
;; Approximating a square wave with power series (you can tell i
;; was in signals and systems class today)
;; This creates the "large" bands on the screen.
(flomap-normalize
(build-flomap 1 (flomap-width imgfm) (flomap-height imgfm)
(λ(k x y-not)
(define y (+ 12 (/ y-not 20)))
(+ (* 1/1 (sin (* 1 y)))
(* 1/3 (sin (* 3 y)))
(* 1/5 (sin (* 5 y)))
(* 1/7 (sin (* 7 y)))
(* 1/9 (sin (* 9 y))))))))
(define noise-offset
;; Smaller noise bands
(flomap-normalize
(build-flomap 1 (flomap-width imgfm) (flomap-height imgfm)
(λ(k x y)
(sin y)))))
(define (flomap-move fm dx dy)
;; Offset a flomap.
(flomap-inset fm dx dy (- dx) (- dy)))
;; Offset each channel of the RGB picture to make it look worse
(match-define (list imgfmr imgfmg imgfmb)
(map (curry flomap-ref-component imgfm) '(1 2 3)))
(define flomap-rgbshifted
(flomap-append-components (flomap-move imgfmr color-offset color-offset)
(flomap-move imgfmg (- color-offset) (- color-offset))
(flomap-move imgfmb (- color-offset) color-offset)))
(define screen
;; Build the actual CRT screen, without shading
(flomap-transform
;; Copy alpha channel from original:
(flomap-append-components (flomap-ref-component imgfm 0)
(fm+ (fm* noise-offset 0.1)
(fm+ (fm* noise-offset-big 0.1)
flomap-rgbshifted)))
;; Fisheye:
(flomap-projection-transform
(equal-area-projection lens-bend)
(stereographic-projection lens-bend)
#f)))
;; Finally, give glassy gloss to the TV screen.
(bitmap-render-icon (flomap->bitmap screen)
5/8 glass-icon-material))