Last active
July 24, 2019 23:05
-
-
Save dmi3kno/9c6cb927b799737698d27fcb66f75d0e to your computer and use it in GitHub Desktop.
Making pretty blobs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
library(magick) | |
library(tidyverse) | |
# generate noise and apply morphological transformations to make blobs | |
blobs <- image_blank(600,400, "black") %>% | |
image_noise("Impulse") %>% | |
image_channel("Green") %>% | |
image_morphology("Dilate", "Diamond:6") %>% | |
image_morphology("Open", "Disk:10", 3) %>% | |
image_blur(10,10) %>% | |
image_threshold("white") %>% | |
image_transparent("black") %>% | |
image_channel("Opacity") %>% | |
image_negate() %>% | |
image_crop(geometry_area(600-10, 400-10, 5,5)) %>% | |
image_border("black", geometry_area(5,5)) | |
blobs | |
# calculate centroids of the blobs for filling | |
point_fills <- blobs %>% | |
image_morphology("Thinning", "Skeleton:3", -1) %>% | |
image_morphology("Thinning", "LineEnds", -1) %>% | |
image_morphology("Thinning", "Corners", -1) %>% | |
image_morphology("Thinning", "Edges", -1) %>% | |
image_raster() %>% | |
dplyr::filter(col!="#000000ff") %>% | |
mutate(col=RColorBrewer::brewer.pal(n(),"Set3")) | |
# separate blobs | |
blob_lst <- point_fills %>% | |
split(1:nrow(.)) %>% | |
map(~image_fill(blobs, geometry_point(.x$x, .x$y), color = .x$col) %>% | |
image_transparent(.x$col) %>% | |
image_channel("Opacity") %>% | |
image_convert(matte=FALSE) %>% | |
image_transparent("black")) | |
# calculate required patch sizes | |
patch_sizes <- blob_lst %>% | |
map(image_trim) %>% | |
map_df(image_info) | |
# prepare gradiented patches | |
patches_lst <- patch_sizes %>% | |
bind_cols(point_fills) %>% | |
mutate(width=width*1.5, | |
height=height*1.5) %>% | |
select(width, height, col) %>% | |
pmap(~image_blank(..1, ..2, pseudo_image = paste0("gradient:", ..3, "-white"))) | |
# take empty canvas, apply patches where the holes will be be | |
# bring holes and apply them over patches | |
res <- map( | |
seq_along(blob_lst), | |
~image_composite(image_blank(600,400, color="white"), | |
patches_lst[[.x]], operator = "Atop", | |
offset = geometry_point(point_fills$x[.x]-patch_sizes$width[.x]/2, | |
point_fills$y[.x]-patch_sizes$height[.x]/2))) %>% | |
map2(blob_lst, ~image_composite(.x, image_negate(.y), operator="CopyOpacity")) | |
# animated image | |
res %>% {Reduce(c,.)} | |
# flat image | |
res %>% {Reduce(c,.)} %>% | |
image_flatten() %>% | |
image_transparent("white") %>% | |
image_background("pink") | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment