You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ghostscript如何为PDF大纲/书签启用Unicode编码支持

Ghostscript 生成PDF书签时Unicode字符乱码解决方案

Ghostscript 的 pdfmark 语法默认将圆括号()包裹的字符串按单字节PDFDocEncoding编码解析,原生不支持UTF-8编码的文本,因此直接写入带变音符号、非拉丁字符的UTF-8内容必然出现乱码。

正确实现方式

要正常显示包含变音符号在内的所有Unicode字符,需按照PDF规范使用Unicode格式的书签字符串,规则如下:

  • 字符串不能用圆括号()包裹,需使用尖括号<>包裹
  • 尖括号内的内容为**带UTF-16BE BOM(固定前缀为FEFF)**的文本字节对应的大写十六进制序列

最小可用示例

针对测试用的书签文本Lügenbaron,正确的pdfmark配置行如下:

[/Page 1 /Count 0 /View [/XYZ null null null] /Title <FEFF004C00FC00670065006E006200610072006F006E> /OUT pdfmark

批量生成脚本(Python)

不要直接将UTF-16编码的字节对象写入配置文件,需先转成十六进制字符串再拼接,参考代码:

def make_pdfmark(page: int, title: str, count: int = 0) -> str:
    # 标题文本转UTF-16BE字节
    title_bytes = title.encode("utf-16-be")
    # 拼接BOM前缀,转大写十六进制
    title_hex = "FEFF" + title_bytes.hex().upper()
    return f"[/Page {page} /Count {count} /View [/XYZ null null null] /Title <{title_hex}> /OUT pdfmark\n"

if __name__ == "__main__":
    bookmark_entries = [
        (1, 0, "Lügenbaron"),
        (4, 0, "Vorwort"),
        (7, 0, "1. Regeln")
    ]
    # pdfmark文件必须存为ASCII编码
    with open("index.info", "w", encoding="ascii") as f:
        for p, cnt, t in bookmark_entries:
            f.write(make_pdfmark(p, t, cnt))

执行Ghostscript命令

-o参数默认隐含-dBATCH -dNOPAUSE参数,无需重复添加,注意pdfmark配置文件必须放在原PDF文件参数之前:

gs -sDEVICE=pdfwrite -o newfile_indexed.pdf index.info -f original_unindexed_file.pdf

之前尝试方案的错误原因

  • 直接写入UTF-8编码文本并用()包裹:解析器按单字节PDFDocEncoding拆分多字节UTF-8字符,直接导致乱码
  • 整个pdfmark文件存为带BOM的UTF-16BE编码:Ghostscript的PostScript解析器仅支持ASCII编码的脚本文件,UTF-16编码的文件会触发解析错误直接退出
  • 将UTF-16BE字节对象直接格式化写入配置:实际写入的是Python bytes类型的字符串表示(即b'\x00xxx'格式的文本),并非合法的PostScript字符串,显示必然异常
  • 给十六进制字符串额外加()包裹:尖括号外的括号会被识别为普通文本内容,和书签内容一起显示在阅读器中

内容的提问来源于stack exchange,提问作者Xaver

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 23:51:24