`dithr` package for error diffusion dithering in R

Introduction

I made a simple package to encapsulate the dithering code from yesterday’s post.

The package is called dithr and is available on github

The code expects a numeric matrix (all values in the range [0, 1]) as input and provides a matrix as output with only 0 and 1 values. It includes 10 pre-defined diffusion matrices in dithr::diffusion_matrix.

At the moment it’s not really very user friendly, mostly because dealing with image data in R can be a bit of a pain.
There’s probably a great set of image packages out there I haven’t discovered yet! (let me know!)

Intallation

devtools::install_github('coolbutuseless/dithr')

Packages

  • magick - for image preparation
  • EBImage - easiest(?) way to get image data out of magick

To Do

  • Serpentine error diffusion (i.e. alternating traversal direction every row)

Create a ggplot and save it as a PNG

p <-  ggplot(iris) + 
  geom_histogram(aes(Sepal.Length, fill=Species), bins=10) + 
  scale_fill_brewer() +
  theme_bw() + 
  theme(legend.position='none')

ggsave("hist.png", width=6, height=4, units = 'in', dpi = 100)

p

Load the image and convert to a matrix

im <- magick::image_read('hist.png') %>%
  magick::image_convert(type='grayscale') %>%
  magick::image_scale(geometry="75%")

m <- magick::as_EBImage(im)@.Data

dithr::plot_matrix(m)

Dither matrix using floyd steinberg.

dithered_matrix <- dithr::dither(m, edm = dithr::diffusion_matrix$floyd_steinberg)


dithr::plot_matrix(dithered_matrix)

Dithered pie chart (Atkinson dithering)

#-----------------------------------------------------------------------------
# Create and save pie chart
#-----------------------------------------------------------------------------
p <-  ggplot(iris) + 
  geom_bar(aes(1, fill=Species)) +
  coord_polar(theta='y') +
  scale_fill_viridis_d() + 
  theme_bw() +
  theme(legend.position='none')

ggsave("pie.png", width=6, height=4, units = 'in', dpi = 100)

#-----------------------------------------------------------------------------
# Load and prepare image
#-----------------------------------------------------------------------------
im <- magick::image_read('pie.png') %>%
  magick::image_convert(type='grayscale') 

#-----------------------------------------------------------------------------
# Extract matrix data
#-----------------------------------------------------------------------------
m <- magick::as_EBImage(im)@.Data


#-----------------------------------------------------------------------------
# Dither
#-----------------------------------------------------------------------------
dithered_matrix <- dithr::dither(m, edm = dithr::diffusion_matrix$atkinson)
dithr::plot_matrix(dithered_matrix)