Closed pieterprovoost closed 2 months ago
Does using something like image_click$coords_image$x
and image_click$coords_image$y
fix this?
Has this issue been addressed? Or is there a workaround for it? I have the same problem with my app and I can reproduce the issue with the example application provided by @pieterprovoost
Here's another repro of the problem, which is important because you can't capture clicks when you account for pixel ratios.
library(shiny)
library(magick)
# Define UI for application
ui <- fluidPage(
titlePanel("ImageMagick Wizard Rendering"),
sidebarLayout(
sidebarPanel(
helpText("Compare the wizard rendering with and without reference to pixel ratio."),
verbatimTextOutput("click_info_no_pixelratio"),
verbatimTextOutput("click_info_pixelratio")
),
mainPanel(
h3("Without Pixel Ratio Reference"),
imageOutput("image_no_pixelratio", click = "click_no_pixelratio"),
h3("With Pixel Ratio Reference - NO CLICK CAPTURED WHEN CLICKING LOWER RIGHT"),
imageOutput("image_pixelratio", click = "click_pixelratio")
)
)
)
# Define server logic
server <- function(input, output, session) {
output$image_no_pixelratio <- renderImage({
# Read image dimensions from client
width <- session$clientData$output_image_no_pixelratio_width
height <- session$clientData$output_image_no_pixelratio_height
# Load the wizard image
img <- image_read("wizard:")
original_width <- image_info(img)$width
original_height <- image_info(img)$height
# Maintain aspect ratio
aspect_ratio <- original_width / original_height
if (width / height > aspect_ratio) {
width <- height * aspect_ratio
} else {
height <- width / aspect_ratio
}
img <- image_resize(img, paste0(width, "x", height))
# Save the image without pixel ratio reference
img_path_no_pixelratio <- tempfile(fileext = ".jpeg")
image_write(img, path = img_path_no_pixelratio)
list(src = img_path_no_pixelratio,
width = width,
height = height,
contentType = 'image/jpeg',
alt = "Wizard without pixel ratio")
}, deleteFile = TRUE)
output$image_pixelratio <- renderImage({
# Read image dimensions and pixel ratio from client
width <- session$clientData$output_image_pixelratio_width
height <- session$clientData$output_image_pixelratio_height
pixelratio <- session$clientData$pixelratio
# Load the wizard image
img <- image_read("wizard:")
original_width <- image_info(img)$width
original_height <- image_info(img)$height
# Maintain aspect ratio
aspect_ratio <- original_width / original_height
if (width / height > aspect_ratio) {
width <- height * aspect_ratio
} else {
height <- width / aspect_ratio
}
img <- image_resize(img, paste0(width * pixelratio, "x", height * pixelratio))
# Save the image with pixel ratio reference
img_path_pixelratio <- tempfile(fileext = ".jpeg")
image_write(img, path = img_path_pixelratio)
list(src = img_path_pixelratio,
width = width,
height = height,
contentType = 'image/jpeg',
alt = "Wizard with pixel ratio")
}, deleteFile = TRUE)
# Display click coordinates without pixel ratio reference
output$click_info_no_pixelratio <- renderPrint({
if (!is.null(input$click_no_pixelratio)) {
coords <- input$click_no_pixelratio
cat("Click coordinates without pixel ratio reference:\n")
cat("x:", coords$x, "y:", coords$y, "\n")
}
})
# Display click coordinates with pixel ratio reference
output$click_info_pixelratio <- renderPrint({
if (!is.null(input$click_pixelratio)) {
coords <- input$click_pixelratio
pixelratio <- session$clientData$pixelratio
if (is.null(pixelratio)) {
pixelratio <- 1
}
cat("Click coordinates with pixel ratio reference:\n")
cat("x:", coords$x / pixelratio, "y:", coords$y / pixelratio, "\n")
}
})
}
# Run the application
shinyApp(ui = ui, server = server)
This was mentioned in internal support ticket 107146.
System details
Browser Version: Google Chrome Version 87.0.4280.88 (Official Build) (x86_64), high DPI screen
Output of
sessionInfo()
:Example application
Test image: test_1000.png
Describe the problem in detail
The example application loads an existing image into an imageOutput and adds a click handler. This works fine for smaller images, but when the image is larger than the DOM element, clicks are only registering in the top left part of the image. In the example below, a 1000 by 1000 pixel image is loaded into a 610 CSS pixels wide element. Clicking on the top left crosshairs will correctly return (200, 200) in image coordinates, so the fact that the image is scaled is taken into account. However, clicking on the bottom right crosshairs does not work as its location in image coordinates (800, 800) exceeds the size of the DOM element (610).
I fiddled around with the code a bit and managed to fix my problem by using
img.naturalWidth
andimg.naturalHeight
here, but that breaks the official example.