tpetzoldt
tpetzoldt

Reputation: 5813

How to suppress antialiasing of an image in shiny?

I have an image graphics in a shiny app with a relative large number of grid cells. However, smooth color transitions appear distorted in the browser. I suspect that this is an antialiasing artifact and wonder how it can be prevented, either in R or with a css option.

Here a minimal example in plain R, that looks smooth as expected:

library(RColorBrewer)
mycol <- colorRampPalette(brewer.pal(11, 'Spectral'))

png("image.png", width=600, height=600)
x <- seq(-0.5, 0.5, length.out = 200)
r <- sqrt(outer(x^2, x^2, `+`))
image(z = cos(r^2) * exp(-r/6), col = mycol(100))
dev.off()

picture with smooth colors

And the corresponding shiny demo, where the resulting image shows an annoying grid artifact:

library(shiny)
library(RColorBrewer)

mycol <- colorRampPalette(brewer.pal(11, 'Spectral'))

ui <- fluidPage(
    plotOutput("imagePlot")
)

server <- function(input, output) {
    output$imagePlot <- renderPlot({
        x <- seq(-0.5, 0.5, length.out = 200)
        r <- sqrt(outer(x^2, x^2, `+`))
        image(z = cos(r^2) * exp(-r/6), col = mycol(100))
    })
}

shinyApp(ui = ui, server = server)

image with distorted colors

Upvotes: 2

Views: 75

Answers (2)

St&#233;phane Laurent
St&#233;phane Laurent

Reputation: 84649

Here is a solution with renderImage/imageOutput which scales with the window size. Is it appropriate for your real application?

library(shiny)
library(RColorBrewer)

mycol <- colorRampPalette(brewer.pal(11, 'Spectral'))

ui <- fluidPage(
  imageOutput("image")
)

server <- function(input, output, session) {
  
  output$image <- renderImage({
    
    # Get width and height of image output
    width  <- session$clientData$output_image_width
    height <- session$clientData$output_image_height
    
    myimage <- tempfile(fileext = ".png")
    png(myimage, width = width, height = height)
    x <- seq(-0.5, 0.5, length.out = 200)
    r <- sqrt(outer(x^2, x^2, `+`))
    image(z = cos(r^2) * exp(-r/6), col = mycol(100))
    dev.off()
    
    # info list
    list(
      src = myimage,
      contentType = "image/png",
      width = width,
      height = height,
      alt = "This is alternate text"
    )
  }, deleteFile = FALSE)
  
}

shinyApp(ui = ui, server = server)

Upvotes: 1

St&#233;phane Laurent
St&#233;phane Laurent

Reputation: 84649

Very better with the parameter useRaster = TRUE:

server <- function(input, output) {
  output$imagePlot <- renderPlot({
    x <- seq(-0.5, 0.5, length.out = 200)
    r <- sqrt(outer(x^2, x^2, `+`))
    image(z = cos(r^2) * exp(-r/6), col = mycol(100), useRaster = TRUE)
  })
}

enter image description here

Upvotes: 1

Related Questions