I have a bunch of subfolders with images in them and some of the images have the tag "detection" in their metadata. I want to pick these files out and copy them to a new folder. This was as far as I got in trying to create a loop to do this:
metadata <- read_exif(file)
#Check if the tag is in the metadata tags field
if ("Tags" %in% names(metadata) && "detection" %in% metadata$Tags) {
files_to_copy <- c(files_to_copy, file)
}
where files_to_copy will be an empty vector to fill. Thanks in advance.
tibble
from exifr:read_exif()
includes full file paths in SourceFile column. Instead of looping though individual files, you can use a vector of all your file names (e.g. from list.files()
) with read_exif()
, filter / subset resulting frame and pass remaining SourceFile items to file.copy()
.
Using example files from exifr
package to copy files with FacesDetected tag:
library(dplyr, warn.conflicts = FALSE)
library(exifr)
#> Using ExifTool version 12.22
img_path <- system.file("images", package = "exifr")
fs::dir_tree(img_path)
#> D:/pkg_cache/renv/cache/v5/windows/R-4.4/x86_64-w64-mingw32/exifr/0.3.2/7e5e6d9140e2dbb379c1af6e24bc60da/exifr/images
#> ├── binary_tag.JPG
#> └── Canon.jpg
dest_path <- tempfile("dir")
dir.create(dest_path)
list.files(img_path, full.names = TRUE) |>
read_exif(tags = "FacesDetected") |>
# just for printing
mutate(SourceFile = tibble::char(SourceFile, min_chars = 10, shorten = "front")) |>
print() |>
filter(!is.na(FacesDetected)) |>
pull(SourceFile) |>
file.copy(dest_path)
#> # A tibble: 2 × 2
#> SourceFile FacesDetected
#> <char> <int>
#> 1 …c60da/exifr/images/binary_tag.JPG 0
#> 2 …6e24bc60da/exifr/images/Canon.jpg NA
#> [1] TRUE
# files in destination dir:
fs::dir_tree(dest_path)
#> Temp\RtmpKuHss4\dir7050a398c0
#> └── binary_tag.JPG