1

Is it possible to get external image dimensions (for .png, .jpg, etc.) using base R? If not, what is the most lightweight R package that allows one to accomplish this?

Giovanni Colitti
  • 1,982
  • 11
  • 24
  • 1
    Most OSes have the `file` utility available (for the rest -- Windows -- `file.exe` is included in Rtools). `system('file "path/to/filename.png"', intern=TRUE)` displays something like: `filename.png: PNG image data, 1693 x 1200, 8-bit/color RGB, non-interlaced`. That is pretty easy to parse. If that doesn't work, install ImageMagick and you can use `system('magick identify "path/to/filename.png"', intern=TRUE)` for similar output. – r2evans Jun 11 '21 at 18:51

2 Answers2

2

Not base R, but the {magick} package does this easily. An example using a picture from the documentation:

library(magick)

frink <- image_read("https://jeroen.github.io/images/frink.png")
image_info(frink)

Output:

   format width height colorspace matte filesize density
 1    PNG   220    445       sRGB  TRUE    73494   72x72
Rory S
  • 1,278
  • 5
  • 17
1

Here is a function inspired by r2evans suggestion to use the file system command:

png_url <- "https://static1.squarespace.com/static/5d2dfbe36a873f0001547453/t/5d2e5ab5607b8f00015901b6/1619287812905/?format=1500w"
jpg_url <- "https://guardian.ng/wp-content/uploads/2016/12/Rice-farm.jpg"
download.file(png_url, "test.png")
download.file(jpg_url, "test.jpg")

get_image_dimensions <- function(path) {
  # Ensure file exists
  if(!file.exists(path)) 
    stop("No file found", call. = FALSE)
  
  # Ensure file ends with .png or .jpg or jpeg
  if (!grepl("\\.(png|jpg|jpeg)$", x = path, ignore.case = TRUE))
    stop("File must end with .png, .jpg, or .jpeg", call. = FALSE)
  
  # Get return of file system command
  s <- system(paste0("file ", path), intern = TRUE)
  
  # Extract width and height from string
  width <- regmatches(s, gregexpr("(?<=, )[0-9]+(?=(x| x )[0-9]+,)", s, perl = TRUE))[[1]]
  height <- regmatches(s, gregexpr(", [0-9]+(x| x )\\K[0-9]+(?=,)", s, perl = TRUE))[[1]] 
  setNames(as.numeric(c(width, height)), c("Width", "Height"))
}

get_image_dimensions('test.png')
#>  Width Height 
#>   1409   1046
get_image_dimensions('test.jpg')
#>  Width Height 
#>   1280    724

Created on 2021-06-11 by the reprex package (v1.0.0)

Giovanni Colitti
  • 1,982
  • 11
  • 24