【问题标题】:R Magick process multiple filesR Magick处理多个文件
【发布时间】:2020-06-23 13:34:10
【问题描述】:

大家好。

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

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

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

在转换函数中,但这无济于事。我的空间不足或有什么问题,我该如何解决?

【问题讨论】:

  • 原始输入图像的尺寸(以像素宽乘以像素高)是多少?

标签: r image processing


【解决方案1】:

这听起来像是内存问题。

这可能是由于 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/")

【讨论】:

  • 太棒了。如果这解决了您的问题,请考虑投票和/或接受作为答案。
猜你喜欢
  • 2019-10-20
  • 2023-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-11
  • 1970-01-01
相关资源
最近更新 更多