Search code examples
rrawmagick

Turn `magick` object into raw vector


I need the mime type and raw vector of an image to upload it to an API that I'm working with. I would like to do this with the magick package, but can't figure out how to get a proper raw vector out of a magick object. This is how I read in the image and get it's mime type:

library(magick)
example_image <- "https://i.sstatic.net/H5yfi.jpg?s=256&g=1"
img <- image_read(example_image)
image_mimetype <- paste0("image/", tolower(image_info(img)$format))
image_mimetype
#> [1] "image/jpeg"

My current workaround (that works) is to save the magick object to disk and read in the file as raw again:

tmp <- tempfile()
image_write(img, tmp)
img_raw <- readBin(tmp, "raw", file.info(tmp)$size)
head(img_raw)
#> [1] ff d8 ff e0 00 10
object.size(img_raw)
#> 24272 bytes

I looked through the magick github repo for mentions of raw and found that you can get a raw array like so:

img_raw <- img[[1]]
img_raw
#> 3 channel 256x256 bitmap array: 'bitmap' raw [1:3, 1:256, 1:256] 54 55 4d 4b ...

It's possible to turn this into a vector:

img_raw <- as.raw(img[[1]])
head(img_raw)
#> [1] 54 55 4d 4b 4c 44
object.size(img_raw)
#> 196656 bytes

But the vector is about 8 times as big and the API does not accept it as valid jpeg.

Created on 2024-01-16 with reprex v2.0.2


Solution

  • The function image_write silently returns the infomation you need, so you don't need to explicitly write it to a file (use path=NULL), so you can replace

    tmp <- tempfile()
    image_write(img, tmp)
    img_raw <- readBin(tmp, "raw", file.info(tmp)$size)
    

    by

    img_raw <- image_write(img, NULL)
    

    to avoid writing to file and produce the same output.

    I'm not sure this behaviour is clear from the documentation, but you can see what's going on from the source code of image_write().