Error using R magick package - r

I am trying to save a jpeg picture in png format using the magick package in R and I'm facing an error.
Below is the error that I get using this code:
library(magick)
testPic <- "https://upload.wikimedia.org/wikipedia/commons/thumb/4/42/President_Roosevelt_-_Pach_Bros.tif/lossy-page1-165px-President_Roosevelt_-_Pach_Bros.tif.jpg"
image <- image_read(testPic)
image_info(image)
image_convert(image, format = "png", depth = NULL)
Error in magick_image_write(image, format, quality) :
Magick: profile 'icc': 'RGB ': RGB color space not permitted on grayscale PNG `' # warning/png.c/MagickPNGWarningHandler/1656

This is a bug in imagemagick. The workaround is to add strip = TRUE to image_read():
library(magick)
testPic <- "https://upload.wikimedia.org/wikipedia/commons/thumb/4/42/President_Roosevelt_-_Pach_Bros.tif/lossy-page1-165px-President_Roosevelt_-_Pach_Bros.tif.jpg"
image <- image_read(testPic, strip = TRUE)
image_info(image)
image_convert(image, format = "png", depth = NULL)
I'll try to ping upstream again to fix this.

Related

saving png/jpeg when X11 is not available

I am using a R package that renders the png images.
As I am running the command below in a script, I would like to avoid the error below and still be able to save the images.
How shall I do it ?
> ChIPQCreport(SAMPLE,
+ reportName = paste(ENTRY, "ChIPQC", sep="."),
+ reportFolder = paste(ENTRY, "ChIPQCreport", sep="."))
Saving 7 x 7 in image
Error in png_dev(..., res = dpi, units = "in") : X11 is not available

Get external image file dimensions with base r

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?
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
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)

Installing fonts so that R postscript() device can recognise them

Based on the advice in this post I am trying to get the serif font (or 'family' of fonts) installed into R so that I can save ggplots as .eps files. Though the suggestion provided worked I would like to try to resolve the issue for future use.
Here's code to generate the issue.
library(bayesplot)
df <- data.frame(xVar = rnorm(1e4,0,1), yVar = rnorm(1e4,2,1), zVar = rnorm(1e4,4,1))
t <- bayesplot::mcmc_trace(df)
t
Now when I go to save the figure I get this error
ggplot2::ggsave(filename = "tPlot.eps",
plot = t,
device = "eps",
dpi = 1200,
width = 15,
height = 10,
units = "cm")
Which throws the error
Error in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)) :
family 'serif' not included in postscript() device
In the previous post the answerer suggested I download the extrafont package.
I ran
View(fonttable())
But the serif font did not appear to be installed.
Then I tried
font_addpackage(pkg = "serif")
But I got the error
Error in font_addpackage(pkg = "serif") :
Unknown font package type: not type1 or ttf.
Does anyone know how to install the serif font so R can recognise/use it?
With package extrafont the fonts must be installed before being made available to users. This is done with function font_import.
library(extrafont)
font_import() # This takes several minutes
Now we can see what are the fonts installed and available. From the documentation, help("fonts").
Description
Show the fonts that are registered in the font table (and available for embedding)
fonts_installed <- fonts()
serif1 <- grepl("serif", fonts_installed, ignore.case = TRUE)
sans1 <- grepl("sans", fonts_installed, ignore.case = TRUE)
fonts_installed[serif1 & !sans1]
sum(serif1 & !sans1)
#[1] 458
There are 458 fonts available.
Another way to see the font table is with function fonttable but the fonts returned are not necessarily available for embedding. From help("fonttable").
Description
Returns the full font table
Note that the function returns a dataframe, hence the call to str below (output omitted).
df_font <- fonttable()
str(df_font)
serif2 <- grepl("serif", df_font$FontName, ignore.case = TRUE)
sans2 <- grepl("sans", df_font$FontName, ignore.case = TRUE)
df_font$FontName[serif2 & !sans2]
Finally see if the graphing functions work on a postscript device.
library(bayesplot)
df <- data.frame(xVar = rnorm(1e4,0,1), yVar = rnorm(1e4,2,1), zVar = rnorm(1e4,4,1))
p <- bayesplot::mcmc_trace(df)
p
ggplot2::ggsave(filename = "tPlot.eps",
plot = p,
device = "eps",
dpi = 1200,
width = 15,
height = 10,
units = "cm")

R gif with function

I am trying to make a gif out of an R-Script using a function to generate the images.
I have a function that given some information creates a Map with dots on it.
I use this function on a Vector obtaining a series of different images, and I would like to put them together in a gif. It looks more or less like that:
createMap <- function(my_variable){
my_map <- a_map() + geom_point() # some variable missing
png(filename = paste(aDate, ".png", sep = ""), width = 3149, height = 2183, units = "px")
plot(mw_map)
dev.off()
}
ImageMagick is installed on my pc and the conversion file "converter.exe" also. Later I try to generate the gif using
saveGIF({
lapply(my_vector, createMap)
}, movie.name = "MY_GIF.gif")
but I get an error message:
> convert: improper image header `Rplot1.png' #
> error/png.c/ReadPNGImage/4362. convert: no images defined `MY_GIF.gif'
> # error/convert.c/ConvertImageCommand/3254.
an error occurred in the conversion...
does anybody know what I did wrong?
After creating the map png files. Use the below code. You don't need ImageMagick is installed on PC.
library(magick)
png.files <- sprintf("Rplot%02d.png", 1:10) #Mention the number of files to be read
GIF.convert <- function(x, output = "animation.gif")#Create a function to read, animate and convert the files to gif
{
image_read(x) %>%
image_animate(fps = 1) %>%
image_write(output)
}
GIF.convert(png.files)
For more details check this link: Link

Using R to read out excel-colorinfo

Is there any way to read out the color-index of cells from excel files with R?
While I can set the cell color with packages like XLConnect or XLSX, I have found no way to extract the color-information from existing workbooks.
R-Bloggers provided a function that will do the job for you. I am including the answer here for future reference.
Read the excel file using xlsx package:
library(xlsx)
wb <- loadWorkbook("test.xlsx")
sheet1 <- getSheets(wb)[[1]]
# get all rows
rows <- getRows(sheet1)
cells <- getCells(rows)
This part extracts the information that later will be used for getting background color (or other style information) of the cells:
styles <- sapply(cells, getCellStyle) #This will get the styles
This is the function that identifies/extracts the cell background color:
cellColor <- function(style)
{
fg <- style$getFillForegroundXSSFColor()
rgb <- tryCatch(fg$getRgb(), error = function(e) NULL)
rgb <- paste(rgb, collapse = "")
return(rgb)
}
error will handle the cells with no background color.
Using sapply you can get the background color for all of the cells:
sapply(styles, cellColor)
You can also categorize/identify them by knowing the RGb codes:
mycolor <- list(green = "00ff00", red = "ff0000")
m <- match(sapply(styles, cellColor), mycolor)
labs <-names(mycolor)[m]
You can read more and learn how to apply it at R-bloggers
You can get the RGB codes from RapidTables.com
Old question but maybe it can help someone in the future.
There is a strange behavior in the POI (java) library (at least on my computer). It is not getting the colors correctly. The code provided in the #M--'s answer works well when the color is a basic color (indexed color), but does not work when the color is, for example, in grayscale. To get around you can use the following code using the getTint () function. Tint is a number between -1 (dark) and 1 (light), and combining it with the RGB (getRgb ()) function, you can completely recover the color.
cell_color <- function(style){
fg <- style$getFillForegroundXSSFColor()
hex <- tryCatch(fg$getRgb(), error = function(e) NULL)
hex <- paste0("#", paste(hex, collapse = ""))
tint <- tryCatch(fg$getTint(), error = function(e) NULL)
if(!is.null(tint) & !is.null(hex)){ # Tint varies between -1 (dark) and 1 (light)
rgb_col <- col2rgb(col = hex)
if(tint < 0) rgb_col <- (1-abs(tint))*rgb_col
if(tint > 0) rgb_col <- rgb_col + (255-rgb_col)*tint
hex <- rgb(red = rgb_col[1, 1],
green = rgb_col[2, 1],
blue = rgb_col[3, 1],
maxColorValue = 255)
}
return(hex)
}
Some references to help:
https://poi.apache.org/apidocs/dev/org/apache/poi/hssf/usermodel/HSSFExtendedColor.html#getTint--
https://bz.apache.org/bugzilla/show_bug.cgi?id=50787
Getting Excel fill colors using Apache POI

Resources