matlab - 如何以 Matlab eps 格式导出变音符号(或任何外来字符)?

标签 matlab printing character-encoding diacritics eps

我正在尝试在 MATLAB 的图例命令中使用变音符号。一个快速的谷歌告诉我我想要的表格是 char(146) ,这适用于显示文件或将其打印到 tif。

但是当我打印为 EPS 格式(或 epsc、eps2、epsc2)时,文件中会显示不同的字符。我试过打印前 300 多个字符,它们肯定会改变(尽管速度很慢,其中很大一部分是“A”,紧接着是一个符号),但这似乎是一种很慢的方法,我不是保证真正找到我想要的符号。那么,这里有人对我可以尝试的方法有任何想法吗?

我正在使用 MATLAB R2011a,我的默认字符集是 UTF-8,我的打印行看起来像..

legend( plot_id , strcat('lala',char(146)) )

我的打印线看起来像..
print -depsc2 -tiff -r600 <filename>

(但关闭 tiff 缩略图生成没有任何效果)

最佳答案

当 MATLAB 字符编码为 UTF-8 时会出现问题,这通常是 Linux 用户的情况(因此 Amro 使用 CP1252 的配置没有问题)。当 MATLAB 字符集编码(使用 slCharacterEncoding() 获取)为 UTF-8 时,MATLAB eps 导出函数会被窃听(至少在 R2011b 之前),因为它以八进制转义 UTF-8 格式(2 个字节)导出非 ASCII 字符而 Postscript 解释器设置为解码 1 字节格式。

让我们用字符 ö U+00F6 来说明这个错误,它的一些表示是:

  • UTF-16:0x00F6
  • UTF-8:0xC3 0xB6
  • C 八进制转义 UTF-8:\303\266
  • XML 十进制实体:ö

  • MATLAB 创建的 eps 文件包含:
    /Helvetica /ISOLatin1Encoding 120 FMSR
    (\303\266) s
    

    MATLAB 在 eps 文件中定义了一个函数 FMSR将 Helvetica 字体重新编码为另一种编码,这里是 ISOLatin1Encoding它是两个内置编码向量之一,与 ISO-8859-1 (Latin1) 标准非常匹配(有关详细信息,请参阅 Postscript 语言引用手册的第 329-330 页)。简而言之,编码向量是将字符名称与字符代码相关联的 256 个元素数组。所以它只读取 1 字节的字符代码。在 ISO-8859-1 中,\303=195=à 和\266=182=¶。结果,它打印 ö。

    使用 UTF-8 语言环境导出非 ASCII ISO-8859-1 字符的选项
  • 将八进制 UTF-8 代码转换为八进制 ISO-8859-1 代码,这很容易,因为非 ASCII ISO-8859-1 字符在 UTF-8 中遵循相同的布局。例如,使用程序 sed,它可以从命令窗口或导出脚本运行:
    !sed -i -e 's/\\302\(\\2[4-7][0-7]\)/\1/g' -e 's/\\303\\2\([0-7][0-7]\)/\\3\1/g' file.eps
    

    因此,\303\266变成 \366 =246=ö。您可以在 MATLAB 中直接键入非 ASCII 字符。
  • 更改 MATLAB 字符集编码 slCharacterEncoding('ISO-8859-1')在向图中添加文本之前,如果从命令窗口添加文本,请对非 ASCII 字符使用 char(number)。如果使用绘图工具直接在图中添加文本,则可以输入非 ASCII 字符。此解决方案并不理想,因为非 ASCII 字符不会以默认字体(Linux 上的 MATLAB 默认为 Helvetica)出现在图形上,并且如果您编写图形创建脚本,则需要使用 char(number)。
  • 稍后使用用户提交的 MATLAB 函数(例如 LaPrint 或其一个分支)使用 LaTex 渲染文本,该函数创建一个包含图形文本的 tex 文件和一个包含图形非文本部分的 eps 文件。一个类似的解决方案是 matlab2tikz,它创建一个 tikz/pgfplot 文件和一个 tex 文件。
  • 使用 MATLAB 的 Latex 解释器:\"{o} . MATLAB 通过将 ASCII 字符与其变音符号组合来创建字符,但由于相对定位不佳(与字符相比,变音符号在右侧有点太多),结果质量很低。 MATLAB 使用 Computer Modern 字体中的字形并将字体嵌入到 eps 文件中(增加了约 80 Ko)。此外,从 eps 创建的 pdf 中的原始文本不包含 ö但是 o ̈ .

  • 导出非 ISO-8859-1 字符

    用于导出不在 ISO-8859-1 中的字符,这是在 here 上询问的,如果需要的字符数小于 256(8 位格式)并且理想情况下在标准编码集中,则可能有一个合理的解决方案。它包括以下步骤:
  • 将八进制码转换为Unicode字符;
  • 将文件保存为目标编码标准(8位格式);
  • 添加目标编码集的编码向量。

  • 例如,如果要导出波兰语文本,则需要将文件转换为 ISO-8859-2。这是在 Linux 上使用 Bash 的实现:
    #!/bin/bash
    name=$(basename "$1" .eps)
    ascii2uni -a K "$1" > /tmp/eps_uni.eps
    iconv -t ISO-8859-2 /tmp/eps_uni.eps -o "$name"_latin2.eps
    sed -i -e '/%EndPageSetup/ r ISOLatin2Encoding.ps' -e 's/ISOLatin1Encoding/MyEncoding/' "$name"_latin2.eps
    

    保存为 eps_lat2;然后运行命令 sh eps_lat2 file.eps使用 Latin-2 编码创建 file_latin2.eps。文件 ISOLatin2Encoding.ps 包含以下内容:
    /MyEncoding
    % The first 144 entries are the same as the ISO Latin-1 encoding.
    ISOLatin1Encoding 0 144 getinterval aload pop
    % \22x
        /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
        /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
    % \24x
        /nbspace /Aogonek /breve /Lslash /currency /Lcaron /Sacute /section
        /dieresis /Scaron /Scedilla /Tcaron /Zacute /hyphen /Zcaron /Zdotaccent
        /degree /aogonek /ogonek /lslash /acute /lcaron /sacute /caron
        /cedilla /scaron /scedilla /tcaron /zacute /hungarumlaut /zcaron /zdotaccent
    % \30x
        /Racute /Aacute /Acircumflex /Abreve /Adieresis /Lacute /Cacute /Ccedilla
        /Ccaron /Eacute /Eogonek /Edieresis /Ecaron /Iacute /Icircumflex /Dcaron
        /Dcroat /Nacute /Ncaron /Oacute /Ocircumflex /Ohungarumlaut /Odieresis /multiply
        /Rcaron /Uring /Uacute /Uhungarumlaut /Udieresis /Yacute /Tcedilla /germandbls
    % \34x
        /racute /aacute /acircumflex /abreve /adieresis /lacute /cacute /ccedilla
        /ccaron /eacute /eogonek /edieresis /ecaron /iacute /icircumflex /dcaron
        /dcroat /nacute /ncaron /oacute /ocircumflex /ohungarumlaut /odieresis /divide
        /rcaron /uring /uacute /uhungarumlaut /udieresis /yacute /tcedilla /dotaccent
    256 packedarray def
    

    这是 Python 的另一个实现(因此它也可以在 Windows 和 Mac 上运行):
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    import sys,codecs
    input = sys.argv[1]
    fo = codecs.open(input[:-4]+'_latin2.eps','w','latin2')
    with codecs.open(input,'r','string_escape') as fi:
        data = fi.readlines()
    with open('ISOLatin2Encoding.ps') as fenc:
        for line in data:
            fo.write(line.decode('utf-8').replace('ISOLatin1Encoding','MyEncoding'))
            if line.startswith('%%EndPageSetup'):
                fo.write(fenc.read())
    fo.close()
    

    保存为 eps_lat2.py;然后运行命令 python eps_lat2.py file.eps使用 Latin-2 编码创建 file_latin2.eps。

    通过更改脚本中的编码向量和 iconv(或 codecs.open)参数,它可以轻松适应其他 8 位编码标准。

    关于matlab - 如何以 Matlab eps 格式导出变音符号(或任何外来字符)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11891836/

    相关文章:

    c - 在 C 中帮助 While 循环

    java - "IllegalArgumentException: UNMAPPABLE[1]"压缩带有希腊字符的文件时

    python - 如何获取任意编码的所有字符?

    css - 从维基百科打印预览中删除超链接下划线

    java - 欧元符号 JNA 转换问题

    matlab - 如何在 MATLAB 上将十进制转换为不同的 base-N?

    function - MATLAB 上的并行编程可同时执行 3 个不同的函数

    matlab - 计算以零分隔的回合数

    matlab - 机器学习: How can I include sensitivity or specificity in error calculation?

    html - Bootstrap 3 - 在每个网格列之后打印布局和中断