library(ambient)
simplex <- noise_simplex(c(500, 1000),
pertubation = 'normal',
pertubation_amplitude = 40)
plot(as.raster(normalise(simplex)))
Matt Crump
November 10, 2022
August 4, 2023
I stumbled across Dan Mackinlay’s wonderful notebooks and blog the other day and was inspired by his post rating system. Dan emoji stamps his posts to indicate his assessment of amount of uncertainty, usefulness, roughness, and novelty for his posts. I might give that a whirl. But, as of right now I can’t figure out how to get custom emojis working for this blog, so words will have to do.
Expertise: Not much | Usefulness: Decent | Audience: notes to self
search around and check out a few R packages for making generative art
Try them out here
Mess around on my own
Add more testing to this space over time (when I have time
Make options to generate blog header visuals, so that I can more quickly get into writing without having to bounce out and spend too much time making headers in Adobe Express (also fun).
I follow a lot of #rstats people, so I have some hunchs on where to start.
That should be enough to get started, and I’ll more later.
ambient makes visual noise (Pedersen and Peck 2022)! I am excited. I’m also trying to remember how to cite R packages in quarto.
First example from the ambient documentation.
library(ambient)
simplex <- noise_simplex(c(500, 1000),
pertubation = 'normal',
pertubation_amplitude = 40)
plot(as.raster(normalise(simplex)))
That’s fun. The output adds a border to the image, I’d like to turn that on/off.
Going for a full width picture.
Tangent time. How to add a layer of words on top of an image. Need to be able to do this part in order to use generative art for header backgrounds.
Ugh, tried imager::draw_text() but clunky, and didn’t work.
let’s check out https://swarm-lab.github.io/Rvision/…That looks super cool, but it needs some extra libraries to run. Best come back and try it out some time for video or other fast visual processing.
time for magick
library(magick)
library(magrittr)
simplex <- noise_simplex(c(500, 1000),
pertubation = 'normal',
pertubation_amplitude = 40) %>%
normalise() %>%
as.raster() %>%
magick::image_read() %>%
magick::image_annotate(
"IT TOOK ME WAY \n TOO LONG \n TO ACCOMPLISH \n THIS GOAL",
font = 'Times',
size = 100,
color = "white"
)
magick::image_write(simplex,
path = "images/test_magick.jpg",
format = "jpeg")
knitr::include_graphics("images/test_magick.jpg")
Is easy…go for IMPACT
simplex <- noise_simplex(c(500, 1000),
pertubation = 'normal',
pertubation_amplitude = 40) %>%
normalise() %>%
as.raster() %>%
magick::image_read() %>%
magick::image_annotate(
"IT TOOK ME WAY \n TOO LONG \n TO ACCOMPLISH \n THIS GOAL",
font = 'Impact',
size = 100,
color = "white"
)
magick::image_write(simplex,
path = "images/Impact.jpg",
format = "jpeg")
knitr::include_graphics("images/Impact.jpg")
Is easy…go for IMPACT
simplex <- noise_simplex(c(500, 1000),
pertubation = 'normal',
pertubation_amplitude = 40) %>%
normalise() %>%
as.raster() %>%
magick::image_read() %>%
magick::image_annotate(
" IT TOOK ME WAY \n TOO LONG \n TO ACCOMPLISH \n THIS GOAL",
font = 'Impact',
size = 100,
color = "white",
strokecolor = "pink"
)
magick::image_write(simplex,
path = "images/Impact2.jpg",
format = "jpeg")
knitr::include_graphics("images/Impact2.jpg")
Squish the noise back a little bit
simplex <- noise_simplex(c(500, 1000),
pertubation = 'normal',
pertubation_amplitude = 40) %>%
normalise(to = c(.7,1)) %>%
as.raster() %>%
magick::image_read() %>%
magick::image_annotate(
" IT TOOK ME WAY \n TOO LONG \n TO ACCOMPLISH \n THIS GOAL",
font = 'Impact',
size = 100,
color = "white",
strokecolor = "pink"
)
magick::image_write(simplex,
path = "images/Impact3.jpg",
format = "jpeg")
knitr::include_graphics("images/Impact3.jpg")
I might be into mono-color and text for blog headers. That should be simple enough now:
header <- matrix(1,nrow=500,ncol=1000) %>%
as.raster() %>%
image_read() %>%
magick::image_transparent(color="white") %>%
magick::image_background(color="#ffffcc") %>%
magick::image_annotate(
" IT TOOK ME WAY \n TOO LONG \n TO ACCOMPLISH \n THIS GOAL",
font = 'Impact',
size = 100,
color = "white",
strokecolor = "pink"
)
magick::image_write(header,
path = "images/header.jpg",
format = "jpeg")
knitr::include_graphics("images/header.jpg")
I made some custom fonts a while back, and have them loaded to my system fonts. Checking if they work here. Working [x].
header <- matrix(1,nrow=500,ncol=1000) %>%
as.raster() %>%
image_read() %>%
magick::image_transparent(color="white") %>%
magick::image_background(color="#e2eeee") %>%
magick::image_annotate(
" SQUIGGLIGRAPHY \n by Matt Crump",
font = 'CrumpSquiggligraphy',
location = "-40+100",
size = 110,
color = "black"
)
magick::image_write(header,
path = "images/header2.jpg",
format = "jpeg")
knitr::include_graphics("images/header2.jpg")
Trying out the Moebius font with a highlight layer.
header <- matrix(1,nrow=500,ncol=1000) %>%
as.raster() %>%
magick::image_read() %>%
magick::image_transparent(color="white") %>%
magick::image_background(color="#dcfcf9") %>%
magick::image_annotate(
" Moebius \n by Matt Crump",
font = 'CrumpMoebius',
location = "-15+155",
size = 100,
color = "white"
) %>%
magick::image_blur(radius = 20, sigma = 5) %>%
magick::image_annotate(
" Moebius \n by Matt Crump",
font = 'CrumpMoebius',
location = "-20+150",
size = 100,
color = "black"
) %>%
magick::image_border(color="lightgray",
geometry = "10x10")
magick::image_write(header,
path = "images/header3.jpg",
format = "jpeg")
knitr::include_graphics("images/header3.jpg")
This is fun. I accomplished my goal of making simple headers for blogs. I can see how spelling command over layers of pixel space is intriguing for a generative artist.
For my next trick, I would like to merge this basic header above with some noise from ambient. Not too much noise, just a little bit.
noise <- noise_simplex(c(500, 1000),
pertubation = 'normal',
pertubation_amplitude = 40) %>%
normalise() %>%
as.raster() %>%
magick::image_read()
header <- matrix(1,nrow=500,ncol=1000) %>%
as.raster() %>%
magick::image_read() %>%
magick::image_transparent(color="white") %>%
magick::image_background(color="#dcfcf9") %>%
magick::image_composite(noise,
operator = "blend",
compose_args="10") %>%
magick::image_blur(radius = 20, sigma = 20) %>%
magick::image_annotate(
" Moebius \n by Matt Crump",
font = 'CrumpMoebius',
location = "-15+155",
size = 100,
color = "white"
) %>%
magick::image_blur(radius = 20, sigma = 5) %>%
magick::image_annotate(
" Moebius \n by Matt Crump",
font = 'CrumpMoebius',
location = "-20+150",
size = 100,
color = "black"
) %>%
magick::image_border(color="pink",
geometry = "20x20")
magick::image_write(header,
path = "images/header4.jpg",
format = "jpeg")
knitr::include_graphics("images/header4.jpg")
What does 16:9 feel like? NOTE: this is the correct size for mastodon preview windows
noise <- noise_simplex(c(900, 1600),
pertubation = 'normal',
pertubation_amplitude = 40) %>%
normalise() %>%
as.raster() %>%
magick::image_read()
header <- matrix(1,nrow=900,ncol=1600) %>%
as.raster() %>%
magick::image_read() %>%
magick::image_transparent(color="white") %>%
magick::image_background(color="#dcfcf9") %>%
magick::image_composite(noise,
operator = "blend",
compose_args="5") %>%
magick::image_blur(radius = 20, sigma = 20) %>%
magick::image_annotate(
" Moebius \n by Matt Crump",
font = 'CrumpMoebius',
location = "+0+310",
size = 150,
color = "white"
) %>%
magick::image_blur(radius = 20, sigma = 5) %>%
magick::image_annotate(
" Moebius \n by Matt Crump",
font = 'CrumpMoebius',
location = "-10+300",
size = 150,
color = "black"
) %>%
magick::image_border(color="pink",
geometry = "20x20")
magick::image_write(header,
path = "images/header4_16x9.jpg",
format = "jpeg")
knitr::include_graphics("images/header4_16x9.jpg")
THIS PART IS WRONG, but part of my discovery process.
It seems that mastodon image preview is closer to 1.71 than 1.77 (16:9). So, I will use 1600x 935 pixels for blog headers. Mastodon does not seem to support “large” image cards, and the image preview is shown in a square. This is a test of an example header I might use with a title containing 10 words or so. The words will be roughly inside an inner square, but the header image will be a 1.71 rectangle.
This part is true.
Frown face: magick has a very nice add border function that does not respect image size, it adds a little bit to the image size, making it annoying to resize. Annoyed face.
This code adds a border, but does not expand the image. 16:9 shows equal border in the mastodon preview window. Also, hilariously long. First timer code.
noise <- noise_simplex(c(900, 1600),
pertubation = 'normal',
pertubation_amplitude = 40) %>%
normalise() %>%
as.raster() %>%
magick::image_read()
logo <- magick::image_read("images/crumplab-logos_black.png")
logo <- magick::image_scale(logo,"350")
header <- matrix(1,nrow=900,ncol=1600) %>%
as.raster() %>%
magick::image_read() %>%
magick::image_transparent(color="white") %>%
magick::image_background(color="#dcfcf9") %>%
magick::image_composite(noise,
operator = "blend",
compose_args="5") %>%
magick::image_blur(radius = 20, sigma = 20) %>%
magick::image_annotate(
"This is a possible \n blog post title \n I might write",
font = 'CrumpMoebius',
location = "+10+10",
size = 100,
color = "white",
gravity = "center",
) %>%
magick::image_blur(radius = 20, sigma = 5) %>%
magick::image_annotate(
"This is a possible \n blog post title \n I might write",
font = 'CrumpMoebius',
location = "+0+0",
size = 100,
color = "black",
gravity = "center",
) %>%
magick::image_composite(logo,
operator = "atop",
gravity = "center",
offset = "+0+300")
border <- magick::image_blank(width = 1600-80,
height = 900-80)
border <- border %>%
magick::image_border(color="pink",
geometry = "40x40")
header <- magick::image_composite(header,border,"atop")
magick::image_write(header,
path = "images/header5.jpg",
format = "jpeg")
knitr::include_graphics("images/header5.jpg")