【问题标题】:ImageMagick PATH not being recognized with engine = "tikz" in knitrImageMagick PATH 无法被 knitr 中的 engine = "tikz" 识别
【发布时间】:2014-11-16 20:34:52
【问题描述】:

我正在尝试从knitr 编译 TikZ 图形。我正在使用可用的示例here。我特别想从 Rstudio 编织。

我从“R Markdown”选项卡得到的输出如下:

processing file: test.Rmd

Invalid Parameter - /test_files
Quitting from lines 16-31 (test.Rmd) 
Error in (knit_engines$get(options$engine))(options) : 
  problems with `convert`; probably not installed?
Calls: <Anonymous> ... process_group.block -> call_block -> block_exec -> in_dir -> <Anonymous>
Execution halted

正如 yihui here 所指出的,我需要安装 ImageMagick 才能通过 knitr 运行 TikZ 代码,并且需要在我的 PATH 变量中列出 ImageMagick(我运行的是 Windows 7)。我已经安装了 ImageMagick,并且我相信我已经在我的 PATH 变量中正确指定了目录。我从Sys.getenv("PATH")得到以下输出

[1] "C:\\Program Files\\R\\R-3.0.2\\bin\\x64;C:\\Program Files\\ImageMagick-6.8.9-Q16;C:\\Program Files\\Microsoft HPC Pack 2008 R2\\Bin\\;C:\\Program Files (x86)\\AMD APP\\bin\\x86_64;C:\\Program Files (x86)\\AMD APP\\bin\\x86;C:\\Windows\\system32;C:\\Windows;C:\\Windows\\System32\\Wbem;C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;c:\\Program Files (x86)\\Microsoft SQL Server\\100\\Tools\\Binn\\;c:\\Program Files\\Microsoft SQL Server\\100\\Tools\\Binn\\;c:\\Program Files\\Microsoft SQL Server\\100\\DTS\\Binn\\;c:\\Program Files (x86)\\Microsoft SQL Server\\100\\Tools\\Binn\\VSShell\\Common7\\IDE\\;c:\\Program Files (x86)\\Microsoft SQL Server\\100\\DTS\\Binn\\;C:\\Program Files\\MiKTeX 2.9\\miktex\\bin\\x64\\;C:\\Program Files (x86)\\Microsoft Visual Studio 9.0\\Common7\\IDE\\PrivateAssemblies\\;c:\\Program Files (x86)\\ATI Technologies\\ATI.ACE\\Core-Static;C:\\PDF\\xpdfbin-win-3.03\\bin64;C:\\Program Files\\Microsoft SQL Server\\110\\DTS\\Binn\\;C:\\Program Files (x86)\\Microsoft SQL Server\\110\\Tools\\Binn\\;C:\\Program Files\\Microsoft SQL Server\\110\\Tools\\Binn\\;C:\\Program Files (x86)\\Microsoft SQL Server\\110\\Tools\\Binn\\ManagementStudio\\;C:\\Program Files (x86)\\Microsoft Visual Studio 10.0\\Common7\\IDE\\PrivateAssemblies\\;C:\\Program Files (x86)\\Microsoft SQL Server\\110\\DTS\\Binn\\;C:\\Program Files (x86)\\Windows Kits\\8.1\\Windows Performance Toolkit\\;C:\\Program Files\\SlikSvn\\bin;C:\\Program Files (x86)\\QuickTime\\QTSystem\\;C:\\Program Files\\nodejs\\;C:\\Program Files (x86)\\Google\\Google Apps Sync\\;C:\\Program Files (x86)\\Google\\Google Apps Migration\\;C:\\Program Files (x86)\\Microsoft Visual Studio 11.0\\Common7\\IDE\\PrivateAssemblies\\;C:\\Program Files\\ImageMagick-6.8.9-Q16;C:\\Users\\mienkoja\\AppData\\Local\\Pandoc\\;C:\\Program Files (x86)\\Google\\google_appengine\\;C:\\Users\\mienkoja\\AppData\\Roaming\\MiKTeX\\2.9\\miktex\\bin\\x64\\;C:\\Users\\mienkoja\\AppData\\Roaming\\npm" 

如您所见,C:\\Program Files\\ImageMagick-6.8.9-Q16; 在我的目录列表中排名第二,顺序似乎并不重要 - 我尝试将其移动到列表中的不同位置并获得相同的结果。

我还尝试以管理员身份运行 RStudio(我在我的用户和系统 PATH 变量中都指定了 ImageMagick),但仍然收到相同的错误消息。

TikZ 本身似乎也可以正常工作,因为我可以从 Rnw 文件或命令行将相同的代码编译为 PDF。

鉴于我上面的设置,对于knitr 为何退出,是否有人有任何其他想法?

更新

这似乎是与 ImageMagick 相关的 Windows 问题。当我尝试从 r-blogger 条目 here 运行示例 4 时,我意识到了这一点。

当我从该示例的末尾运行 system("convert -delay 40 *.png example_4.gif") 时,我收到以下警告消息:

Invalid Parameter - 40
Warning message:
running command 'convert -delay 40 *.png example_4.gif' had status 4 

这似乎是一个问题,因为 Windows 在 System32 目录(也在 PATH 变量中)中有一个名为 convert.exe 的文件。如here 中更详细的描述,windows 文件是一个 Windows 系统实用程序,用于将 FAT 卷转换为 NTFS。我已经尝试了引用链接中的所有建议(即重新排序 PATH 变量中的列表,重命名文件(Windows 显然不允许),以及编辑注册表(用户和本地计算机))。 Windows 似乎(不知何故)优先考虑位于 System32 目录中的文件。

我还尝试使用 Sys.setenv() 函数从 R 中手动重定向 PATH 变量。运行 system("where convert", intern=TRUE) 会产生以下输出:

[1] "C:\\Program Files\\ImageMagick-6.8.9-Q16\\convert.exe" "C:\\Windows\\System32\\convert.exe"

第一个路径是正确的目录。第二个路径是上面引用的 Windows 系统函数。因此,我手动设置 PATH 变量如下:Sys.setenv(PATH=system("where convert", intern=TRUE)[1])

当我尝试编织时,我似乎越过了convert 错误。现在我在我的 R Markdown 控制台中收到以下错误:

error in texi2dvi(file = file, pdf = true, clean = clean, quiet = quiet, : 
pdflatex is not available 

这实际上是有道理的,因为我重置了 PATH 变量并且没有指定到 pdflatex.exe 的路径 - 只有 convert.exe。因此,我使用Sys.setenv() 函数添加了pdflatex.exe 的路径,如下所示:Sys.setenv(PATH=paste(Sys.getenv("PATH"),"C:\\Program Files\\MiKTeX 2.9\\miktex\\bin\\x64",sep=";"))。随后对Sys.getenv("PATH") 的调用会产生以下输出:

[1] "C:\\Program Files\\ImageMagick-6.8.9-Q16\\convert.exe;C:\\Program Files\\MiKTeX 2.9\\miktex\\bin\\x64"

因此,PATH 变量似乎包含所有必要信息:convert.exe 的路径和pdflatex.exe 的路径。但是,在 PATH 变量中指定了两个目录后,我现在再次收到原始错误消息:

processing file: test.Rmd

Invalid Parameter - /test_files
Quitting from lines 16-31 (test.Rmd) 
Error in (knit_engines$get(options$engine))(options) : 
  problems with `convert`; probably not installed?
Calls: <Anonymous> ... process_group.block -> call_block -> block_exec -> in_dir -> <Anonymous>
Execution halted

顺便说一句,继续上面的 r-blogger 示例,我可以在系统命令中完全指定路径,如下所示:system('"C:\\Program Files\\ImageMagick-6.8.9-Q16\\convert.exe" -delay 40 *.png example_4.gif')。这将转换示例中的文件而不会出现警告或错误。但是,我不能(据我所知)为knitr 手动指定convert.exe 的路径。

任何其他建议将不胜感激。

【问题讨论】:

  • 您是否重新启动了计算机?
  • 我很高兴在点击 2 或 3 次后进入一个页面,其中包含“因此,就超滤器的运动理论而言,超连通单模曲线的等平凡族是自对偶的。结果,整个数学和逻辑就变得微不足道了。证明留给读者。”
  • @Pascal,计算机已重新启动多次。

标签: r path imagemagick knitr imagemagick-convert


【解决方案1】:

所以,这不是最优雅的解决方案,但它确实有效......

按照上面 r-blogger 示例的想法,我分叉了 github knitr repo here

我把@yihui的版本engine.R代码功能中的eng_tikz()改了 到我自己的版本:

## convert tikz string to PDF
eng_tikz = function(options) {
  if (!options$eval) return(engine_output(options, options$code, ''))

  lines = readLines(tmpl <- options$engine.opts$template %n%
                      system.file('misc', 'tikz2pdf.tex', package = 'knitr'))
  i = grep('%% TIKZ_CODE %%', lines)
  if (length(i) != 1L)
    stop("Couldn't find replacement string; or the are multiple of them.")

  s = append(lines, options$code, i)  # insert tikz into tex-template
  writeLines(s, texf <- str_c(f <- tempfile('tikz', '.'), '.tex'))
  unlink(outf <- str_c(f, '.pdf'))
  tools::texi2pdf(texf, clean = TRUE)
  if (!file.exists(outf)) stop('failed to compile tikz; check the template: ', tmpl)
  unlink(texf)

  fig = fig_path('', options)
  dir.create(dirname(fig), recursive = TRUE, showWarnings = FALSE)
  file.rename(outf, str_c(fig, '.pdf'))
  # convert to the desired output-format, calling `convert`
  ext = tolower(options$fig.ext %n% dev2ext(options$dev))
  if (ext != 'pdf'){
    # Changed this line
    # conv = system(sprintf('convert %s.pdf %s.%s', fig, fig, ext))
    # to specify full path to ImageMagick
    conv = system(sprintf('"C:\\Program Files\\ImageMagick-6.8.9-Q16\\convert.exe" %s.pdf %s.%s', fig, fig, ext))
    if (conv != 0) stop('problems with `convert`; probably not installed?')
  }
  options$fig.num = 1L; options$fig.cur = 1L
  extra = knit_hooks$get('plot')(paste(fig, ext, sep = '.'), options)
  options$engine = 'tex'  # for output hooks to use the correct language class
  engine_output(options, options$code, '', extra)
}

可以看出,我只更改了一行 - 我只是在 sprintf() 函数中完全指定了 convert.exe 的路径。

当我运行 knitr 的分叉版本时,我最初从 knitr 收到以下消息:

convert.exe: iCCP: profile 'default_rgb.icc': 0h: PCS illuminant is not D50 
'C:/Users/mienkoja/AppData/Local/Temp/magick-11148QAz4QgZyDsZV1' @ warning/png.c/MagickPNGWarningHandler/1831.
Quitting from lines 16-31 (annual_review.Rmd) 
Error in (knit_engines$get(options$engine))(options) : 
  problems with `convert`; probably not installed?
Calls: <Anonymous> ... process_group.block -> call_block -> block_exec -> in_dir -> <Anonymous>
Execution halted

警告意味着该函数实际运行,我现在确实看到了 tikz-ex-1.pdftikz-ex-1.png 文件,正如预期的那样。

然而,knitr.png 被“编织”到 HTML 文档之前仍然产生相同的错误。

这是因为sprintf() 函数之后的if (conv != 0) stop('problems withconvert; probably not installed?') 行似乎在警告时停止knitr - 而不仅仅是错误。当我注释掉这条线时,我得到了一个完整的文档。

这显然是一个骇人听闻的解决方案(如果有人有更好的想法,我很乐意接受另一种选择)。

我也对任何关于向knitr repo 提交功能请求的 cmets 感兴趣,该请求允许路径规范作为与我类似的 Windows 用户的块选项。在使用tikz_engine() 时,如果能够将参数传递给 ImageMagick,那就太好了。

【讨论】:

  • 我已经向knitr repo here 添加了一个功能请求。如果有人对此请求有其他想法,请随时在此处添加!
猜你喜欢
  • 2012-09-27
  • 1970-01-01
  • 2013-02-18
  • 1970-01-01
  • 2015-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-25
相关资源
最近更新 更多