/
catalog2pdf.R
executable file
·163 lines (137 loc) · 6.43 KB
/
catalog2pdf.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#' Combine \code{\link{catalog}} images into pdfs
#'
#' \code{catalog2pdf} combines \code{\link{catalog}} jpeg images into pdfs
#' @usage catalog2pdf(keep.img = TRUE, overwrite = FALSE, parallel = 1, path = NULL,
#' pb = TRUE, by.img.suffix = FALSE, ...)
#' @param keep.img Logical argument. Indicates whether jpeg files should be kept (default) or remove.
#' @param overwrite Logical argument. If \code{TRUE} all jpeg pdf will be produced again
#' when code is rerun. If \code{FALSE} only the ones missing will be produced. Default is \code{FALSE}.
#' @param parallel Numeric. Controls whether parallel computing is applied.
#' It specifies the number of cores to be used. Default is 1 (i.e. no parallel computing).
#' @param path Character string containing the directory path where the catalog image files are located.
#' If \code{NULL} (default) then the current working directory is used.
#' @param pb Logical argument to control progress bar. Default is \code{TRUE}.
#' @param by.img.suffix Logical. If \code{TRUE} catalogs with the same image suffix will be
#' put together in a single pdf (so one pdf per image suffix in the catalog
#' images). Default is \code{FALSE} (i.e. no suffix).
#' @param ... Additional arguments to be passed to the internal pdf creating function \code{\link[grDevices]{pdf}} for customizing output.
#' @export
#' @name catalog2pdf
#' @details The function combines catalog images in .jpeg format from the \code{\link{catalog}} function into pdfs. Images must be saved in .jpeg format. Note that using lower resolution and smaller dimension (width and height) when creating catalogs will substantially decrease the size of pdf files (which could be pretty big).
#' @seealso \code{\link{full_spectrogram2pdf}}, \code{\link{catalog}}
#' @return Image files in pdf format with spectrogram catalogs in the working directory.
#' @examples
#' \dontrun{
#' # save sound file examples
#' data(list = c("Phae.long1", "Phae.long2"))
#' writeWave(Phae.long1, file.path(tempdir(), "Phae.long1.wav"))
#' writeWave(Phae.long2, file.path(tempdir(), "Phae.long2.wav"))
#'
#' catalog(X = lbh_selec_table, nrow = 2, ncol = 4)
#'
#' # now create single pdf removing jpeg
#' catalog2pdf(keep.img = FALSE, path = tempdir())
#'
#' # check this floder
#' tempdir()
#' }
#' @references {Araya-Salas, M., & Smith-Vidaurre, G. (2017). warbleR: An R package to streamline analysis of animal acoustic signals. Methods in Ecology and Evolution, 8(2), 184-191.}
#' @author Marcelo Araya-Salas (\email{marcelo.araya@@ucr.ac.cr})
# last modification on mar-13-2018 (MAS)
catalog2pdf <- function(keep.img = TRUE, overwrite = FALSE, parallel = 1, path = NULL,
pb = TRUE, by.img.suffix = FALSE, ...) {
# error message if jpeg package is not installed
if (!requireNamespace("jpeg", quietly = TRUE)) {
stop2("must install 'jpeg' to use this function")
}
#### set arguments from options
# get function arguments
argms <- methods::formalArgs(catalog2pdf)
# get warbleR options
opt.argms <- if (!is.null(getOption("warbleR"))) getOption("warbleR") else SILLYNAME <- 0
# remove options not as default in call and not in function arguments
opt.argms <- opt.argms[!sapply(opt.argms, is.null) & names(opt.argms) %in% argms]
# get arguments set in the call
call.argms <- as.list(base::match.call())[-1]
# remove arguments in options that are in call
opt.argms <- opt.argms[!names(opt.argms) %in% names(call.argms)]
# set options left
if (length(opt.argms) > 0) {
for (q in seq_len(length(opt.argms))) {
assign(names(opt.argms)[q], opt.argms[[q]])
}
}
# check path to working directory
if (is.null(path)) {
path <- getwd()
} else if (!dir.exists(path)) {
stop2("'path' provided does not exist")
} else {
path <- normalizePath(path)
}
# list jpeg files
imgs <- list.files(pattern = "\\.jpeg$|\\.jpeg$", path = path, ignore.case = TRUE)
if (length(imgs) == 0) stop2("No .jpeg files were found in the working directory")
# remove images that don't have the catalog_pX.jpeg ending
imgs <- grep("Catalog_p\\d+", imgs, value = TRUE)
# remove page info at the end of file names to get sound file names
if (by.img.suffix) {
or.sf <- gsub("Catalog_p\\d+\\-|\\.jpeg", "", imgs)
} else {
or.sf <- by.img.suffix
}
pdf.options(useDingbats = TRUE)
# loop over each sound file name
cat2pdfFUN <- function(i, overwrite, keep.img) {
if (!is.logical(i)) filnam <- paste0(i, ".pdf") else filnam <- "Catalog.pdf"
if (any(!overwrite & !file.exists(filnam), overwrite)) {
# order imgs so they look order in the pdf
if (!is.logical(i)) subimgs <- imgs[or.sf == i] else subimgs <- imgs
if (length(subimgs) > 1) {
pgs <- as.numeric(sapply(strsplit(substr(subimgs, start = regexpr("Catalog_p", subimgs) + 9, nchar(subimgs)), "-|.jpeg"), "[", 1))
if (!is.logical(i)) {
pgs <- as.numeric(gsub(paste0("-", i, "|\\.jpeg|\\.jpg"), "", pgs, ignore.case = TRUE))
} else {
pgs <- as.numeric(gsub(paste0("|\\.jpeg|\\.jpg"), "", pgs, ignore.case = TRUE))
}
subimgs <- subimgs[order(pgs)]
}
# get dimensions
imgdm <- dim(jpeg::readJPEG(file.path(path, subimgs[1]), native = T))
dimprop <- imgdm[1] / imgdm[2]
# start graphic device
if (!is.logical(i)) {
grDevices::pdf(file = file.path(path, paste0(i, ".pdf")), width = 10, height = dimprop * 10, ...)
} else {
grDevices::pdf(file = file.path(path, "Catalog.pdf"), width = 10, height = dimprop * 10, ...)
}
# plot
img <- jpeg::readJPEG(file.path(path, subimgs[1]))
par(mar = rep(0, 4), oma = rep(0, 4), pty = "m")
plot.new()
mr <- par("usr")
graphics::rasterImage(img, mr[1], mr[3], mr[2], mr[4])
# loop over the following pages if more than 1 page
if (length(subimgs) > 1) {
no.out <- lapply(subimgs[-1], function(y) {
plot.new()
mr <- par("usr")
img2 <- jpeg::readJPEG(file.path(path, y))
graphics::rasterImage(img2, mr[1], mr[3], mr[2], mr[4])
})
}
dev.off()
if (!keep.img) unlink(subimgs)
}
}
# set clusters for windows OS
if (Sys.info()[1] == "Windows" & parallel > 1) {
cl <- parallel::makePSOCKcluster(getOption("cl.cores", parallel))
} else {
cl <- parallel
}
# run loop apply function
a1 <- pblapply_wrblr_int(pbar = pb, X = unique(or.sf), cl = cl, FUN = function(i) {
cat2pdfFUN(i, overwrite, keep.img)
})
}