Add watermark to images with Shiny and Magick library
This Shiny app allows to add a watermark to images and to do some basic photo retouch.
I created this shiny application with:
- magick library;
- I deployed it on shinyapps.io;
- I embedded it in the blog with an iframe;
- and the image is kindly provided by my cat (when he was a kitty).
The layout for this post is best seen via a computer.
The code
In the code below are missing the standard shiny commands such as:
- ui <- ()
- server <- function(input, output, session) {}
- shinyApp(ui, server)
because I used shiny in a Rmarkdown file.
fluidPage(
fluidRow(column(4,fileInput("upload", "Upload new image", accept = c('image/png', 'image/jpeg'))),
column(2,textInput("size", "Change size", value = "500x500!") ),
column(2, sliderInput("rotation", "Rotate", 0, 180, 0)),
column(2, sliderInput("brightness", "Brightness", 0, 200, 100)),
column(1, checkboxGroupInput("effects", "", choices = list( "Flop")))
),
hr(),
fluidRow(
column(4, checkboxGroupInput("effects2", "Watermark adjustments:", choices = list("Add watermark")),
textInput("W_text", "Watermark text", value = "Copyright"),
sliderInput("W_size", "Watermark size", 25, 150, 40),
sliderInput("W_degrees", "Watermark degrees", 0, 180, 0),
selectInput("W_gravity", "Watermark position:",
c("Center" = "center",
"North" = "north",
"West" = "west",
"East" = "east",
"South"="south",
"North West" = "northwest",
"North East" = "northeast",
"South West" = "southwest",
"South East" = "northeast")),
downloadButton('downloadImage', 'Download modified image')),
column(8, imageOutput("img") )
)
)
library(magick)
imageLoc <- reactiveVal("https://www.enricodata.com/images_added/mimo.png")
## convert the img location to an img value
imageVal <- reactive({
image_convert(image_read(imageLoc()), "jpeg")
})
# When uploading new image
observeEvent(input$upload, {
if (length(input$upload$datapath)) {
## set the image location
imageLoc(input$upload$datapath)
}
updateCheckboxGroupInput(session, "effects", selected = "")
})
## if the image information ever updates, set the info values
observe({
info <- image_info(imageVal())
updateTextInput(session, "size", value = paste0(info$width, "x", info$height, "!"))
})
updatedImageLoc <- reactive({
## retrieve the imageVal
image <- imageVal()
# output$img <- renderImage({
if("Add watermark" %in% input$effects2)
image <- image_annotate(image, input$W_text, gravity = input$W_gravity, location = "+0+0",
degrees = input$W_degrees, size = input$W_size, color = "#FFFFFF66",
strokecolor = NULL, boxcolor = NULL)
if("Flop" %in% input$effects)
image <- image_flop(image)
tmpfile <- image %>%
image_resize(input$size) %>%
image_modulate(brightness = input$brightness , saturation = 100, hue = 100) %>%
image_rotate(input$rotation) %>%
image_write(tempfile(fileext='jpg'), format = 'jpg')
## return only the tmp file location
tmpfile
})
# A plot of fixed size
output$img <- renderImage(
{
# Return a list
list(src = updatedImageLoc(), contentType = "image/jpeg")
},
## DO NOT DELETE THE FILE!
deleteFile = FALSE
)
output$downloadImage <- downloadHandler(
filename = "Modified_image_from_EnricoData.jpeg",
contentType = "image/jpeg",
content = function(file) {
## copy the file from the updated image location to the final download location
file.copy(updatedImageLoc(), file)
}
)