LaTex (tikz) 轉換為圖像

此項目是一個關於把LaTex文檔直接轉換為各種圖像的教程(在編譯TEX文件時,同時生成單獨的圖片)。此教程主要關注如何把tikz生成的,內嵌於LaTex生成的PDF文件中的圖像轉換為各種格式的單獨圖片。

此項目會討論到的圖片格式如下

  • SVG (矢量圖)
  • PNG(位圖)
  • EMF (Windows系統上的矢量圖)
  • EPS (印刷常用格式)

此項目的在於提供基於Windows系統的教程和例子。作者相信Linux用戶有能力獨自解決這個問題。

此教程會提供軟件安裝和配置指南,並會結合例子進行講解。

此教程認為用戶已經對LaTex有一定的理解,因而不會對LaTex中之各種進行詳解。

本教程將會詳盡講解流程。若只想快速使用而不在乎原理,可先閱讀 軟件的安裝和配置 然後按照 極簡教程 中之步驟執行即可。

系統和軟件

此項目會用到如下的系統和軟件,請先保證你已安裝了它們。

轉換軟件的使用理由

此項目選擇的轉換軟件主要基於以下理由。

  • 此項目堅持所有使用的轉換軟件必須為免費

  • 轉換結果必須是一頁PDF一張圖

  • 當把PDF轉換為矢量圖時,必須為真正的矢量圖,而不是包裹在矢量格式中的位圖

    • 因此,此項目不使用ImageMagick,因其在轉換矢量圖時經常柵格化
  • 當轉為為矢量圖時,字體應該嵌入而不是柵格化

  • 轉換命令應儘可能簡單

  • 使用的軟件儘可能少以降低依賴性

備註

儘管 inkscape 也可以進行PNG和SVG的轉換,但 pdftocairopdf2svg 自帶了多頁到單頁的功能,使用便利,而且安裝也簡易,故而用此二軟件分別進行PNG和SVG的轉換而不使用 inkscape 。若使用 inkscape ,則需要先調用 ghostscript 對PDF進行分頁,然後再轉換。

軟件的安裝和配置

軟件的下載鏈接可在 系統和軟件 獲得。若鏈接失效,請自行搜索。

  • texlive 的安裝過程比較長,請耐心等待(根據網速而定,可能需要數十分鐘到數小時不等)。

    • texlive 自帶 standalone 包和 pdftocairo
  • inkscapeghostscript 可採用默認安裝或者改變一下安裝路徑(非C盤)

  • 關於 pdf2svg ,請在github頁面下載zip壓縮包,然後解壓出對應系統位元的版本(32位或64位)。之後把解壓出來的文件夾路徑加到系統的環境變量 Path 中即可。

  • 請保證所有軟件的路徑都加到系統環境變量 Path 中,否則Windows的CMD會無法找到它們(除非用完整路徑)。此點會在 配置系統環境變量 Path 詳述。

配置系統環境變量 Path

當在CMD中鍵入非完整路徑時,譬如調用 pdftocairo 時,只鍵入“pdftocairo”而不是它完整的安裝路徑時(譬如“c:\一些文件夾\pdftocairo.exe”),系統會查找保存在 Path 變量中的路徑,看能不能找到。故此,為了便利和兼容,一般情況下軟件安裝時都會把自身重要的路徑加到 Path 中。

當然,也有列外的情況,比如不用安裝的軟件(譬如 pdf2svg ),或者用戶沒有修改環境變量的權限。這些情況下就需要手動把路徑加到 Path 中。權限不足的用戶需要管理員的幫助,或者進行提權。

在Windows上配置環境變量有好幾種方法,此處描述基於Windows 7的一種方法。Windows 10的方法基本一樣,只不過微軟把界面做了一些優化。

警告

注意,在改動環境變量時請先進行備份。

步驟如下。

  1. 打開系統的控制面板
  2. 點擊右上角的查看方式並設為大圖標
  3. 點擊“系統”
  4. 點擊“高級系統設置”
  5. 點擊“環境變量”
  6. 選中“系統環境變量”下的 Path
  7. 點擊“編輯”
  8. 在彈出的窗口中,複製所有路徑並保存到用以備份用的純文本文件
  9. 在彈出窗口的路徑結尾,鍵入分號“;”(英文的),之後粘貼入需要加入的文件夾路徑(不要把文件的完整路徑加進去)(Windows 10有友好的GUI,不需要鍵入分號)
  10. 點擊所有確認鍵

測試是否成功修改

假設加入的是 pdftocairo 的路徑,那麼,打開Windows的CMD,鍵入如下命令:

pdftocairo --help

如果配置 Path 成功,那一系列的幫助信息將會顯示在CMD裡面。如果不成功,那CMD會說找不到 pdftocairo

備註

可能需要重啟電腦

你可能需要重啟電腦才能令環境變量生效。若重啟後仍沒有生效,則證明配置錯誤。

一般來說, texlive 會自動添加路徑,但 inkscapeghostscriptpdf2svg 都需要手動添加路徑。

極簡教程

本章意在提供最簡短而必要的步驟,以使用戶快速上手。

在應用本章步驟前,請先保證所有需要的軟件和配置已完成。

轉換為SVG

  1. 把本教程附帶的 util 文件夾複製到需要轉換的TEX文件所在之目錄下。

  2. 對需要轉換的TEX的文件的 documentclass 進行如下配置:

    1
    2
    3
    4
    5
    6
    7
    8
    \documentclass[tikz, convert, convert={outext=.svg, command=\unexpanded{
    % 'out_svg'是用来存放SVG的文件夹
    % 'out_svg'是用來存放SVG的文件夾
    % 'out_svg' is the destination folder for SVG files
    call ./util/mk_folder out_svg
    && cd /d out_svg
    && call ../util/pdf_to_svg ../\infile\space \outfile\space
    }}]{standalone}
    
  3. 使用 -shell-escape 參數對TEX文件進行編譯。例如(需要把尖括號,及其所包裹的內容更換成你的TEX文件的文件名):

    xelatex -synctex=1 -interaction=nonstopmode -shell-escape <你TEX文件的文件名>.tex
    
  4. 轉換好的SVG文件將存放在 out_svg 文件夾下。

轉換為PNG

  1. 把本教程附帶的 util 文件夾複製到需要轉換的TEX文件所在之目錄下。

  2. 對需要轉換的TEX的文件的 documentclass 進行如下配置:

    1
    2
    3
    4
    5
    6
    7
    8
    \documentclass[tikz, convert, convert={command=\unexpanded{
    % 'out_png'是用来存放PNG的文件夹
    % 'out_png'是用來存放PNG的文件夾
    % 'out_png' is the destination folder for PNG files
    call ./util/mk_folder out_png
    && cd /d out_png
    && call ../util/pdf_to_png.bat 600 ../\infile\space
    }}]{standalone}
    
  3. 使用 -shell-escape 參數對TEX文件進行編譯。例如(需要把尖括號,及其所包裹的內容更換成你的TEX文件的文件名):

    xelatex -synctex=1 -interaction=nonstopmode -shell-escape <你TEX文件的文件名>.tex
    
  4. 轉換好的PNG文件將存放在 out_png 文件夾下。

轉換為EMF

  1. 把本教程附帶的 util 文件夾複製到需要轉換的TEX文件所在之目錄下。

  2. 對需要轉換的TEX的文件的 documentclass 進行如下配置:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    \documentclass[tikz, convert, convert={outext=.pdf, command=\unexpanded{
    % 'out_emf'是用来存放EMF的文件夹
    % 'out_emf'是用來存放EMF的文件夾
    % 'out_emf' is the destination folder for EMF files
    call ./util/mk_folder out_emf
    && call ./util/gs_split_pdf.bat out_emf \outfile\space \infile\space
    && cd /d out_emf
    && call ../util/pdf_to_emf.bat
    && del /F *.pdf \sapce
    }}]{standalone}
    % inkscape只能实现单张的PDF转换EMF,所以要先用ghostscript把LaTex生成的
    % PDF分页,然后调用inkscape做循环,把所有单页的PDF转换为EMF,最后删除所
    % 有单页的PDF,只保留EMF。
    % inkscape只能實現單張的PDF轉換EMF,所以要先用ghostscript把LaTex生成的
    % PDF分頁,然後調用inkscape做循環,把所有單頁的PDF轉換爲EMF,最後刪除所
    % 有單頁的PDF,只保留EMF。
    % inkscape can only convert single page PDF to EMF. Therefore, the whole
    % PDF generated by LaTex needs to be split into single pages first, by
    % ghostscript. Then use inkscape in a loop to convert all single page
    % PDFs into EMFs. Finally, delete all single page PDFs and keep only the
    % EMFs.
    
  3. 使用 -shell-escape 參數對TEX文件進行編譯。例如(需要把尖括號,及其所包裹的內容更換成你的TEX文件的文件名):

    xelatex -synctex=1 -interaction=nonstopmode -shell-escape <你TEX文件的文件名>.tex
    
  4. 轉換好的EMF文件將存放在 out_emf 文件夾下。

轉換為EPS

  1. 把本教程附帶的 util 文件夾複製到需要轉換的TEX文件所在之目錄下。

  2. 對需要轉換的TEX的文件的 documentclass 進行如下配置:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    \documentclass[tikz, convert, convert={outext=.pdf,
    command=\unexpanded{{
    % 'out_eps'是用来存放EPS的文件夹
    % 'out_eps'是用來存放EPS的文件夾
    % 'out_eps' is the destination folder for EPS files
    call ./util/mk_folder out_eps
    && call ./util/gs_split_pdf.bat out_eps \outfile\space \infile\space
    && cd /d out_eps
    && call ../util/pdf_to_eps.bat
    && del /F *.pdf \sapce
    }}}]{standalone}
    % inkscape只能实现单张的PDF转换EPS,所以要先用ghostscript把LaTex生成的
    % PDF分页,然后调用inkscape做循环,把所有单页的PDF转换为EPS,最后删除所
    % 有单页的PDF,只保留EPS。
    % inkscape只能實現單張的PDF轉換EPS,所以要先用ghostscript把LaTex生成的
    % PDF分頁,然後調用inkscape做循環,把所有單頁的PDF轉換爲EPS,最後刪除所
    % 有單頁的PDF,只保留EPS。
    % inkscape can only convert single page PDF to EPS. Therefore, the whole
    % PDF generated by LaTex needs to be split into single pages first, by
    % ghostscript. Then use inkscape in a loop to convert all single page
    % PDFs into EPSs. Finally, delete all single page PDFs and keep only the
    % EPSs.
    
  3. 使用 -shell-escape 參數對TEX文件進行編譯。例如(需要把尖括號,及其所包裹的內容更換成你的TEX文件的文件名):

    xelatex -synctex=1 -interaction=nonstopmode -shell-escape <你TEX文件的文件名>.tex
    
  4. 轉換好的EPS文件將存放在 out_eps 文件夾下。

本章中為了方便排錯,命令是分部進行的(通過 && 連成一行)。這些命令其實是可以放在同一個腳本中,而簡化 documentclass 的設置的。詳情請看 一步到位

LaTex standalone 包的配置

本教程是基於由 Martin Scharrer 開發的 standalone 包(自帶 standalone 類),故此於此對此包稍作講解。

備註

standalone (complex) [1]

standalone 是LaTex中非常有用的一個包。本教程主要講述怎樣利用此包來進行圖片的轉換,但此包其實還有其它相當多的應用。 Overleaf 上有一個非常有用的教程。

standalone 的轉換命令配置

standalone 本身的 說明文檔 已經對配置有詳盡的說明,此處重點說一下轉換成圖片需要用到的 convert 選項。

配置 convert 需要在 documentclass 中進行。以下是一個利用 pdf2svg 轉換為SVG的範例配置。

1
2
3
\documentclass[tikz, convert, convert={outext=.svg, command=\unexpanded{
pdf2svg \infile\space \outfile\space all
}}]{standalone}

其中,

  • tikz

    此選項告訴 standalone LaTex文檔中存在 tikz 圖片。

  • convert

    此選項開啟 standalone 的轉換功能。

  • convert={}

    此選項是 convert 的詳細配置項。

  • outext=.svg

    設置輸出文件的後綴名為“.svg”。更詳細的說明請參看 standalone 本身的 說明文檔 中的表1。

  • command=\unexpanded{}

    此項是將要調用系統運行的命令。

  • pdf2svg

    調用的轉換工具。

    備註

    pdf2svg 的語法

    pdf2svg 的語法可以參看 這裡

    其中,將一多頁PDF轉換為分頁的多個SVG的語法為:

    pdf2svg <輸入文件名>.pdf <輸出文件名>%d.svg all
    

    注意,尖括號,及其所包裹中的內容需要替換為所需的文件名。

  • \infile

    輸入文件名,包含後綴名。默認後綴名為“.pdf”或“.ps”。 更詳細的說明請參看 standalone 本身的 說明文檔 中的表1。

  • \space

    空格。若不使用此參數,\infile 後不會有空格,無論你實際上鍵入了多少個。 \outfile 也是這樣。

  • \outfile

    輸出文件名,包含後綴名。默認後綴名為“.png”。此處已經通過 outext 更改為“.svg”。更詳細的說明請參看 standalone 本身的 說明文檔 中的表1。

SVG配置範例中之命令將會被翻譯為如下(可以通過查看LOG文件確認)。其中, mew_to_svg 為所用的TEX文件的文件名。

1
pdf2svg mwe_to_svg.pdf mwe_to_svg-%01d.svg all

由此可以看出,轉換的重點,是要把 convert={} 中的配置正確設置,以令LaTex將其翻譯成正確的系統命令來進行圖片的轉換。用戶可以把多個系統命令整合為一行,以做出豐富多彩的組合來達成不同的目標(在Windows中可以通過“&”或“&&”把多行命令合併為一行)。在 轉換流程 中將會詳細敘述各種圖片轉換的流程。

備註

運行系統命令

其實在本小結就可以看出,既然 standalone 可以調用以上的命令,那當然也可以調用其它系統命令。理論上,用戶可以調用各種命令來做各種事,不僅僅是圖片的轉換。如果你有興趣,應該可以做到編譯完後自動上傳到某個網絡位置,或者刪除整個硬盤這一類有趣的事情。

編譯命令

standalone 需要在編譯時使用 -shell-escape 參數。一個使用 xelatexmew_to_svg.tex 進行編譯的命令如下(用 xelatex 是因為需要處理中文)。如果你使用LaTex編輯器進行書寫,比如 TEXsutdio ,則需要在其中編輯其命令。你也當然可以直接在TEX文件所在之目錄下打開CMD,用命令直接編譯。

1
xelatex -synctex=1 -interaction=nonstopmode -shell-escape mwe_to_svg.tex

簡例

以下提供一個轉換為單頁多個SVG的簡例。詳細的例子會在後文說明。

以下的文件可以在此項目的根目錄和 mew 文件夾中找到。

主文件:

mew 文件夾中的 mwe_to_svg.tex

 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
% 这是一个将tikz图片转换成多张SVG的示例文件,使用pdf2svg来实现转换
% 這是一個將tikz圖片轉換成多張SVG的示例文件,使用pdf2svg來實現轉換
% This is a demo file for tikz to multiple SVGs using pdf2svg
\documentclass[tikz, convert, convert={outext=.svg, command=\unexpanded{
    pdf2svg \infile\space \outfile\space all
}}]{standalone}

\usepackage{xeCJK}
\setCJKmainfont{Microsoft YaHei}

\usepackage{scalefnt}
\usepackage{tikz}

% tikz和colour的设定
% tikz和colour的設定
% tikz and colour configs
\input{../configs_tikz.tex}
\input{../configs_colour.tex}

\begin{document}

    % 全局字体缩放
    % 全局字體縮放
    % global font scale
    \scalefont{1.3}

    % tikz图像文档
    % tikz圖像文檔
    % tikz pics file
    \input{../tikz_pics.tex}

\end{document}

tikz配置文件:

本教程根目錄中的 configs_tikz.tex

 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
% 以下是关于tikz中画流程图的设置
% 以下是關於tikz中畫流程圖的設置
% configure flowchart shapes
\usetikzlibrary{shapes.geometric, arrows, positioning, calc}

% start, end shape
\tikzstyle{startstop} = [rectangle, rounded corners, minimum width=3cm,
minimum height=1cm,text centered,  text=white, draw=black,
fill=colorStarstop]

% process shape
\tikzstyle{process} = [rectangle, minimum width=3cm, minimum height=1cm,
text centered, text=white, draw=black, fill=colorPro]

% decision shape
\tikzstyle{decision}=[diamond, minimum width=3cm, minimum height=1cm,
text centered, draw=black, fill=colorDec]

% comment shape
\tikzstyle{comment}=[dashed, draw=black, fill=gray!10, minimum width=3cm, minimum height=1cm, text centered]

% docstring shape
\tikzstyle{docstring}=[draw=orange, fill=white, minimum width=50mm, text width=80mm, minimum height=1cm]

% arrows shape
\tikzstyle{arrow} = [ultra thick,->,>=stealth, line width=1.5mm]

% comment shape
\tikzstyle{comment}=[dashed, draw=black, fill=gray!10, minimum width=3cm, minimum height=1cm, text centered]

\tikzset{
    subprocess/.style = {rectangle, draw=black, semithick, fill=orange!30,
        minimum width=#1, minimum height=1cm, inner xsep=3mm, % <-- changed
        text width =\pgfkeysvalueof{/pgf/minimum width}-2*\pgfkeysvalueof{/pgf/inner xsep},
        align=flush center,
        path picture={\draw
            ([xshift =2mm] \ppbb.north west) -- ([xshift= 2mm] \ppbb.south west)
            ([xshift=-2mm] \ppbb.north east) -- ([xshift=-2mm] \ppbb.south east);
        },
    },
    subprocess/.default = 24mm % <-- added
}% end of tikzset

\usetikzlibrary{positioning}

color配置文件:

本教程根目錄中的 configs_colour.tex

1
2
3
4
5
6
7
8
9
% 以下是颜色的设置
% 以下是顏色的設置
% colour defs
\usepackage{color}
\definecolor{colorStarstop}{RGB}{174, 23, 21}
\definecolor{colorPro}{RGB}{0, 175, 121}
\definecolor{colorDec}{RGB}{255, 192, 0}
\definecolor{colorYes}{RGB}{51, 153, 51}
\definecolor{colorNo}{RGB}{255, 0, 0}
[1]Ghost In Shell : Standalone Complex

轉換流程

本章將對轉換流程進行講解。鑑於使用到之軟件,轉換成PNG的流程與轉換成SVG之流程相近,而轉換成EPS之流程則於轉換成EMF之流程同理。

本教程中轉換的流程將利用到數份Windows的批處理腳本(在本教程的 util 文件夾中),本教程將在 腳本詳解 中對它們進行詳細講解。

本章中之方法一律需要使用 -shell-escape 參數來進行編譯。一個使用 xelatexmew_to_svg.tex 進行編譯的命令如下(用 xelatex 是因為需要處理中文)。

1
xelatex -synctex=1 -interaction=nonstopmode -shell-escape mwe_to_svg.tex

請把 mwe_to_svg 替換為你的TEX文件文件名。

轉換為SVG之流程

轉換為SVG之流程可用如下之流程圖表示:

SVG flowchart

如上圖所示,轉換流程將在所在之目錄創建一個名為 out_svg 的文件夾單獨存放生成的SVG文件。之後將會調用 util 文件夾中的 pdf_to_svg 腳本來實現轉換。

此流程需要用戶對需要轉換之TEX文件的 documentclass 進行如下配置:

1
2
3
4
5
6
7
8
\documentclass[tikz, convert, convert={outext=.svg, command=\unexpanded{
% 'out_svg'是用来存放SVG的文件夹
% 'out_svg'是用來存放SVG的文件夾
% 'out_svg' is the destination folder for SVG files
call ./util/mk_folder out_svg
&& cd /d out_svg
&& call ../util/pdf_to_svg ../\infile\space \outfile\space
}}]{standalone}

備註

設置 outext

outext 有設置時, standalone 會自動地在輸出文件(即是 outfile)的文件名(不含後綴名)後加上計數關鍵字(一般是 %d)。

這小節的方法正是利用 standalone 之此特性,結合 pdf2svg 的語法來進行PDF轉換為分頁的SVG。

警告

關於“%”和“\”符號

在LaTex中,“%”是一個保留字,用來表示註釋。如果直接使用在 documentclass 之中,則會把其後面的同行代碼全部註釋掉。這樣的話,編譯時會出問題。

然而,若用 “\” 進行轉義(即“escape”)的話 standalone 是會把“\”符號作為明文加入到命令中的。這樣一來,命令通常都不對,因為“\”在LaTex中是表示的是後面跟的是參數或者命令。而在Windows命令中“%”通常用來指代參數,在Windows中使用for循環時絕對會用到它,無法避免。

綜上所述,如果在 documentclass 裡面直接把系統命令寫全的話,很難保證其正確性。

故此,作者選擇把命令封裝到多個批處理腳本中,這樣就可以避免以上提及的符號問題同時方便排錯。

本方法用到以下兩份腳本:

  1. mk_folder
    創建文件夾。
  2. pdf_to_svg
    將多頁的PDF轉換為分頁的SVG。

它們的詳細講解在 腳本詳解 中。

轉換為PNG之流程

轉換為PNG之流程可用如下之流程圖表示:

PNG flowchart

如上圖所示,轉換流程將在所在之目錄創建一個名為 out_png 的文件夾單獨存放生成的PNG文件。之後將會調用 util 文件夾中的 pdf_to_png 腳本來實現轉換。

此流程需要用戶對需要轉換之TEX文件的 documentclass 進行如下配置:

1
2
3
4
5
6
7
8
\documentclass[tikz, convert, convert={command=\unexpanded{
% 'out_png'是用来存放PNG的文件夹
% 'out_png'是用來存放PNG的文件夾
% 'out_png' is the destination folder for PNG files
call ./util/mk_folder out_png
&& cd /d out_png
&& call ../util/pdf_to_png.bat 600 ../\infile\space
}}]{standalone}

備註

pdftocairo

pdftocairo 會自動地把一多頁的PDF自動分割為多張PNG。故此只需要把輸入文件給它即可(即 infile),而不需要設置輸出文件(即 outfile)。

本方法用到以下兩份腳本:

  1. mk_folder
    創建文件夾。
  2. pdf_to_png
    將多頁的PDF轉換為分頁的PNG。

它們的詳細講解在 腳本詳解 中。

轉換為EMF之流程

轉換為EMF之流程可用如下之流程圖表示:

EMF flowchart

如上圖所示,轉換流程將在所在之目錄創建一個名為 out_emf 的文件夾單獨存放生成的EMF文件。之後將會調用 util 文件夾中的 gs_split_pdf 來對生成的PDF進行分頁,pdf_to_emf 腳本來實現轉換。 轉換完畢後會刪除所有單頁之PDF,只保留EMF。

此流程需要用戶對需要轉換之TEX文件的 documentclass 進行如下配置:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
\documentclass[tikz, convert, convert={outext=.pdf, command=\unexpanded{
% 'out_emf'是用来存放EMF的文件夹
% 'out_emf'是用來存放EMF的文件夾
% 'out_emf' is the destination folder for EMF files
call ./util/mk_folder out_emf
&& call ./util/gs_split_pdf.bat out_emf \outfile\space \infile\space
&& cd /d out_emf
&& call ../util/pdf_to_emf.bat
&& del /F *.pdf \sapce
}}]{standalone}
% inkscape只能实现单张的PDF转换EMF,所以要先用ghostscript把LaTex生成的
% PDF分页,然后调用inkscape做循环,把所有单页的PDF转换为EMF,最后删除所
% 有单页的PDF,只保留EMF。
% inkscape只能實現單張的PDF轉換EMF,所以要先用ghostscript把LaTex生成的
% PDF分頁,然後調用inkscape做循環,把所有單頁的PDF轉換爲EMF,最後刪除所
% 有單頁的PDF,只保留EMF。
% inkscape can only convert single page PDF to EMF. Therefore, the whole
% PDF generated by LaTex needs to be split into single pages first, by
% ghostscript. Then use inkscape in a loop to convert all single page
% PDFs into EMFs. Finally, delete all single page PDFs and keep only the
% EMFs.

備註

inkscape

inkscape 在轉換時不會自動對PDF進行分頁。若直接使用 inkscape 對多頁PDF進行轉換,只有第一頁會被轉換。

故此,本方法會先調用 ghostscript 對PDF進行分頁,然後在調用 inkscape 對所有的單頁PDF進行轉換。

本方法用到以下三份腳本:

  1. mk_folder
    創建文件夾。
  2. gs_split_pdf
    將多頁的PDF分割為單頁的PDF。
  3. pdf_to_emf
    將PDF轉換為EMF(僅一頁)。

它們的詳細講解在 腳本詳解 中。

轉換為EPS之流程

轉換為EPS之流程可用如下之流程圖表示:

EPS flowchart

如上圖所示,轉換流程將在所在之目錄創建一個名為 out_eps 的文件夾單獨存放生成的EMF文件。之後將會調用 util 文件夾中的 gs_split_pdf 來對生成的PDF進行分頁,pdf_to_eps 腳本來實現轉換。 轉換完畢後會刪除所有單頁之PDF,只保留EMF。

此流程需要用戶對需要轉換之TEX文件的 documentclass 進行如下配置:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
\documentclass[tikz, convert, convert={outext=.pdf,
command=\unexpanded{{
% 'out_eps'是用来存放EPS的文件夹
% 'out_eps'是用來存放EPS的文件夾
% 'out_eps' is the destination folder for EPS files
call ./util/mk_folder out_eps
&& call ./util/gs_split_pdf.bat out_eps \outfile\space \infile\space
&& cd /d out_eps
&& call ../util/pdf_to_eps.bat
&& del /F *.pdf \sapce
}}}]{standalone}
% inkscape只能实现单张的PDF转换EPS,所以要先用ghostscript把LaTex生成的
% PDF分页,然后调用inkscape做循环,把所有单页的PDF转换为EPS,最后删除所
% 有单页的PDF,只保留EPS。
% inkscape只能實現單張的PDF轉換EPS,所以要先用ghostscript把LaTex生成的
% PDF分頁,然後調用inkscape做循環,把所有單頁的PDF轉換爲EPS,最後刪除所
% 有單頁的PDF,只保留EPS。
% inkscape can only convert single page PDF to EPS. Therefore, the whole
% PDF generated by LaTex needs to be split into single pages first, by
% ghostscript. Then use inkscape in a loop to convert all single page
% PDFs into EPSs. Finally, delete all single page PDFs and keep only the
% EPSs.

本方法之原理於轉換為EMF的流程完全一樣。都是先對生成的PDF進行分頁,再調用 inkscape 進行處理。

本方法用到以下三份腳本:

  1. mk_folder
    創建文件夾。
  2. gs_split_pdf
    將多頁的PDF分割為單頁的PDF。
  3. pdf_to_eps
    將PDF轉換為EPS(僅一頁)。

它們的詳細講解在 腳本詳解 中。

腳本詳解

本章將對本教程中所用到之腳本進行講解。

本項目所使用到的腳本存放在 util 文件夾之中,它們為:

  • mk_folder.bat

    用於創建文件夾。

    備註

    腳本命名問題

    在Windows當中,如果把批處理腳本命名為所要調用的系統命令名,很可能會導致死循環。 故此命名此腳本為 mk_folder.bat 而不是 mkdir.bat

  • gs_split_pdf.bat

    調用 ghostscript 把PDF分割為單頁。

  • pdf_to_svg.bat

    把多頁PDF轉換為分頁的SVG。

  • pdf_to_png.bat

    把多頁PDF轉換為分頁的PNG。

  • pdf_to_emf.bat

    把PDF轉換為EMF(僅一頁)。

  • pdf_to_eps.bat

    把PDF轉換為的EPS(僅一頁)。

警告

路徑

在設置 documentclass 時,需要注意輸入的路徑參數。本教程一律使用相對路徑。

./ 是指當前所在路徑。

../ 是指往上移一層目錄。

mk_folder.bat 詳解

mk_folder.bat 的內容如下:

1
2
3
4
5
6
@echo off
REM this file is not call "mkdir" to avoid run errors

set dst_dir=%1

if not exist %dst_dir%/NUL mkdir %dst_dir%

此腳本用於在CMD當前所在之目錄為根來創建文件夾。如果該文件夾已存在,則不創建而退出。

此腳本接受一個參數。此參數為將要創建的文件夾路徑。

此腳本之使用方法如下:

mk_folder <要創建之文件夾路徑>

此腳本的語法和 mkdir 命令的語法一致。此處給出一個例子,假設要在目前的目錄下創建一個名為 a 的文件夾,其下有一個子目錄,名為 b,而 b 之下又有一個子目錄,名為 c

mk_folder a\b\c

若文件夾路徑中有空格,則需要把路徑放在兩個雙引號之中,如:

mk_folder "a b\c d"

gs_split_pdf.bat 詳解

gs_split_pdf.bat 的內容如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
@echo off
REM use 64-bit ghosescript to split a pdf

set temp_folder=%1
set outfile=%2
set infile=%3

REM the gswinXXc.exe does not prompt the ghostscript window, the ones without the "c" do prompt

gswin64c -sDEVICE=pdfwrite -dSAFER -dNOPAUSE -dBATCH -sOutputFile=%temp_folder%/%outfile% %infile%

此腳本用於把輸入的PDF分割為單頁的PDF。

此腳本接受三個參數。它們如下(按順序):

  1. 輸出的單頁PDF的文件夾的路徑
  2. 輸出的單頁PDF文件的共用文件名加上“%d”
  3. 需要分頁的PDF的路徑

此腳本調用的是64位的 ghostscript ,若你安裝的是32位的版本則需要把此腳本中的 gswin64c 更改為 gswin32c

此處給出一個例子,輸出的文件夾為 output (已存在),共用文件名為 common,需要分頁的PDF為 pdf_in

gs_split_pdf output common%d.pdf pdf_in.pdf

備註

“%d”

如果不在共用文件名後加上“%d”,ghostscript 則不會對PDF進行分頁。

pdf_to_svg.bat 詳解

pdf_to_svg.bat 的內容如下:

1
2
3
4
5
6
7
@echo off
REM use pdf2svg (https://github.com/jalios/pdf2svg-windows) to convert a pdf to individual svgs

set inputfile=%1
set outputfile=%2

pdf2svg %inputfile% %outputfile% all

此腳本用於把PDF轉換為SVG。

此腳本接受兩個參數。它們如下(按順序):

  1. 需要轉換的PDF文件路徑
  2. 輸出的單頁PDF文件的共用文件名加上“%d”

此腳本調用 pdf2svg 來進行文件的轉換。此處給出一個例子,需要轉換的PDF名為 pdf_in,輸出的單頁PDF的共用文件名為 pdf_out ,輸出的文件夾為 out_svg (已存在)。

pdf_to_svg pdf_in.pdf .\out_svg\pdf_out%d.svg

備註

“%d”

如果不在共用文件名後加上“%d”,則只會轉換PDF的第一頁。

pdf_to_png.bat 詳解

pdf_to_png.bat 的內容如下:

1
2
3
4
5
6
7
@echo off
REM use pdftocairo to convert a pdf into multiple pngs

set dpi=%1
set inputfile=%2

pdftocairo -r %dpi% -png %inputfile%

此腳本用於把PDF轉換為PNG。此腳本會在CMD當前所在之目錄創建PNG文件。

此腳本接受兩個參數。它們如下(按順序):

  1. 轉換的PNG的DPI,一般為300或600。過高的DPI會令轉換過程冗長。一般而言,打印需要至少300 DPI,一般600 DPI足以應付絕大部分情況。
  2. 需要轉換的PDF的路徑

此腳本調用 pdftocairo 來進行文件的轉換。此處給出一個例子,轉換的DPI為600像素,需要轉換的PDF名為 pdf_in

pdf_to_png 600 pdf_in.pdf

備註

pdftocairo

pdftocairo 會自動把多頁PDF轉換為單頁的PNG,非常方便。

備註

為了方便,用戶可以把 util 文件夾的路徑加入到系統環境變量 Path 中,這樣就可以直接調用腳本,而不需要在命令中指定 util 文件夾的路徑。

一步到位

本章在 腳本詳解 的基礎上,講解怎樣把命令合併到一個腳本中從而簡化 documentclass 的配置。

腳本詳解 中可以看出,本教程爲了方便排錯,而把命令分到多個腳本之中,逐個擊破,但其實完全是可以把命令全部寫入單個腳本之中,而實現簡化 documentclass 的設置的。

本章將會提供這麼做的範例。

一步轉換成SVG

本小結將使用 util 文件夾中之 qk_pdf_to_svg.bat 腳本,以 mwe 文件夾中的 qk_to_svg.tex 爲例,展示如何一步轉換到SVG。

qk_to_svg.tex 中的 documentclass 的配置如下:

1
2
3
4
5
6
\documentclass[tikz, convert, convert={outext=.svg, command=\unexpanded{
% 'out_svg'是用来存放SVG的文件夹
% 'out_svg'是用來存放SVG的文件夾
% 'out_svg' is the destination folder for SVG files
call ../util/qk_pdf_to_svg out_svg \infile\space \outfile\space
}}]{standalone}

其中, out_svg 是存放SVG的文件夾。

qk_pdf_svg.bat 腳本的內容如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
@echo off

set dst_dir=%1
set inputfile=%2
set outputfile=%3

if not exist %dst_dir%/NUL mkdir %dst_dir%

cd /d %dst_dir%

pdf2svg ../%inputfile% %outputfile% all

qk_pdf_to_svg.bat 中的命令,是把 demo_to_svg.tex 中的 documentclass 中的命令整合爲一,以達到簡化 documentclass 的配置的目的。

一步轉換成PNG

本小結將使用 util 文件夾中之 qk_pdf_to_png.bat 腳本,以 mwe 文件夾中的 qk_to_png.tex 爲例,展示如何一步轉換到PNG 。

qk_to_png.tex 中的 documentclass 的配置如下:

1
2
3
4
5
6
\documentclass[tikz, convert, convert={outext=.svg, command=\unexpanded{
% 'out_png'是用来存放PNG的文件夹
% 'out_png'是用來存放PNG的文件夾
% 'out_png' is the destination folder for PNG files
call ../util/qk_pdf_to_png out_png 600 \infile\space
}}]{standalone}

其中, out_png 是存放PNG的文件夾。

qk_pdf_to_png.bat 腳本的內容如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
@echo off

set dst_dir=%1
set dpi=%2
set intputfile=%3

if not exist %dst_dir%/NUL mkdir %dst_dir%

cd /d %dst_dir%

pdftocairo -r  %dpi% -png ../%intputfile%

qk_pdf_to_png.bat 中的命令,是把 demo_to_png.tex 中的 documentclass 中的命令整合爲一,以達到簡化 documentclass 的配置的目的。

一步轉換成EMF

本小結將使用 util 文件夾中之 qk_pdf_to_emf.bat 腳本,以 mwe 文件夾中的 qk_to_emf.tex 爲例,展示如何一步轉換到EMF。

qk_to_emf.tex 中的 documentclass 的配置如下:

1
2
3
4
5
6
7
\documentclass[tikz, convert, convert={outext=.pdf,
command=\unexpanded{
% 'out_emf'是用来存放EMF的文件夹
% 'out_emf'是用來存放EMF的文件夾
% 'out_emf' is the destination folder for EMF files
call ../util/qk_pdf_to_emf out_emf \outfile\space \infile\space
}}]{standalone}

其中, out_emf 是存放EMF的文件夾。

qk_pdf_to_emf.bat 腳本的內容如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
@echo off

set dst_dir=%1
set outputfile=%2
set intputfile=%3

if not exist %dst_dir%/NUL mkdir %dst_dir%

gswin64c -sDEVICE=pdfwrite -dSAFER -dNOPAUSE -dBATCH -sOutputFile=%dst_dir%/%outputfile% %intputfile%

cd /d %dst_dir%

for /r %%i in (*.pdf) do inkscape %%i -M %%~pni.emf

del /F *.pdf

qk_pdf_to_emf.bat 中的命令,是把 demo_to_emf.tex 中的 documentclass 中的命令整合爲一,以達到簡化 documentclass 的配置的目的。

一步轉換成EPS

本小結將使用 util 文件夾中之 qk_pdf_to_eps.bat 腳本,以 mwe 文件夾中的 qk_to_eps.tex 爲例,展示如何一步轉換到EPS。

qk_to_eps.tex 中的 documentclass 的配置如下:

1
2
3
4
5
6
7
\documentclass[tikz, convert, convert={outext=.pdf,
command=\unexpanded{
% 'out_eps'是用来存放EPS的文件夹
% 'out_eps'是用來存放EPS的文件夾
% 'out_eps' is the destination folder for EPS files
call ../util/qk_pdf_to_eps out_eps \outfile\space \infile\space
}}]{standalone}

其中, out_eps 是存放EPS的文件夾。

qk_pdf_to_eps.bat 腳本的內容如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
@echo off

set dst_dir=%1
set outputfile=%2
set intputfile=%3

if not exist %dst_dir%/NUL mkdir %dst_dir%

gswin64c -sDEVICE=pdfwrite -dSAFER -dNOPAUSE -dBATCH -sOutputFile=%dst_dir%/%outputfile% %intputfile%

cd /d %dst_dir%

for /r %%i in (*.pdf) do inkscape %%i -E %%~pni.eps

del /F *.pdf

qk_pdf_to_eps.bat 中的命令,是把 demo_to_eps.tex 中的 documentclass 中的命令整合爲一,以達到簡化 documentclass 的配置的目的。

總結

本章為此教程之總結。

本教程利用Latex中的 standalone 包和Windows命令和腳本,結合 pdf2svg, pdftocairo, inkscapeghostscript 來實現編譯TEX文件時,同時把生成的PDF轉換成單頁的圖片文件。

本教程講述來如何轉換成SVG,PNG,EMF和EPS這四種類型的圖片。

如果你需要轉換為JPG,請參考EMF的轉換教程,自行實現。

本項目使用 git 進行版本控制。遠端倉庫存放在GitHub上。你可以在 這裡 下載本項目,並提出問題。