R Magick处理多个文件

R Magick process multiple files

所以大家好。

我遇到了魔法问题,但我不明白...

我写了一个函数来加载、重新缩放和保存图像

    convert <- function(infile,outpath, topspace=200){
  require(magick)
  if(!file.exists(infile)) return("file does not exist")

  print(paste0("Load ", infile, " ..."))
  read <- image_read(infile, strip= TRUE)
  basename <- basename(infile)
  basename2 <- gsub(".png", "", basename)

  print(paste0("Resize ", basename, " ..."))
  read4300 <- image_resize(read, "4300x4300")
  read4000 <- image_resize(read4300, "4000x4000")

  print(paste0("Extent ", basename, " ..."))
  read5400 <- image_extent(read4300, paste0("4500x", 5400-2*topspace), gravity = "North")
  read5400 <- image_extent(read5400, "4500x5400", gravity = "Center")
  read4050 <- image_extent(read4000, "4500x4050")
  print(paste0("Speicher ", basename, " ..."))

  image_write(read4000 , paste0(outpath,"\",basename2,"4000.png"))
  image_write(read5400 , paste0(outpath,"\",basename2,"5400.png"))
  image_write(read4050 , paste0(outpath,"\",basename2,"4050.png"))
}

这个功能很好用。我想在循环中将此功能应用于多个文件,但每次第三张图像(以任何顺序)变得非常慢。在调整 image3.png 大小时,它总是变得非常慢。如果我只尝试 image3.png 它工作正常。如果我更改顺序 (3-2-1),问题会出现在 image1.png。所以文件大约 1MB,前两张图像的处理时间大约 15 秒,第三张大约需要 5-10 分钟...

我尝试添加

read <- NULL
  read4300 <- NULL
  read4000 <- NULL
  read5400 <- NULL
  read4050 <- NULL
  remove(list = ls())

在转换函数中,但这没有帮助。我 运行 满分 space 或有什么问题,我该如何解决?

这听起来像是内存问题。

这可能是由于 ImageMagick 安全策略对可用资源的限制所致。参见 https://github.com/ImageMagick/ImageMagick/issues/396 (由于这个问题,你的代码对我不起作用,但你似乎在 Windows,所以那里的情况可能有所不同。)

要查看这是否是您的问题,请从命令行尝试 运行 identify -list resource

如果这是 R 中内存管理的一个问题,您可以在转换函数的末尾添加一个 gc(full=TRUE) 命令,以查看是否可以通过显式调用垃圾收集来回收任何资源。

您可以在您的文件上尝试这个稍微修改过的功能,看看它是否适合您。

convert_img <- function(infile, outpath, topspace=200){
    require(magick)
    if(!file.exists(infile)) return("file does not exist")
    
    print(paste0("Load ", infile, " ..."))
    read0 <- image_read(infile, strip = TRUE)
    basename <- basename(infile)
    basename2 <- tools::file_path_sans_ext(basename)
    
    print(paste0("Resize ", basename, " ..."))
    read4300 <- image_resize(read0, "4300x4300")
    read4000 <- image_resize(read0, "4000x4000")
    
    print(paste0("Extent ", basename, " ..."))
    read5400 <- image_extent(read4300, paste0("4500x", 5400-2*topspace), gravity = "North")
    read5400 <- image_extent(read5400, "4500x5400", gravity = "Center")
    read4050 <- image_extent(read4000, "4500x4050")
    print(paste0("Speicher ", basename, " ..."))
    
    image_write(read4000 , file.path(outpath, paste0(basename2, "4000.png")))
    image_write(read5400 , file.path(outpath, paste0(basename2,"5400.png")))
    image_write(read4050 , file.path(outpath, paste0(basename2,"4050.png")))
    gc(full=TRUE)
}

# my test examples ran fine and R memory usage stayed below 2 GB:
files <- list.files(path="~/Downloads", pattern = ".png", full.names = TRUE)
sapply(files, convert_img, outpath="~/outfiles/")